diff --git a/.hgignore b/.hgignore index 8f35298eb..0d04fc2a0 100644 --- a/.hgignore +++ b/.hgignore @@ -23,6 +23,7 @@ glob:*.ncb glob:*.exe glob:*.bat glob:platform/macosx/build +glob:platform/macosx/Build glob:platform/macosx/DerivedData glob:platform/macosx/*.xcodeproj/bill* glob:platform/macosx/*.xcodeproj/xcuserdata diff --git a/.hgtags b/.hgtags index f0477f422..c1795ff2b 100644 --- a/.hgtags +++ b/.hgtags @@ -5,3 +5,4 @@ db7cd0682883ed357adef013a326bbb26de28c98 0.6.2 18d79c306466d188919c238d23e50ea705b07c03 0.7.1 bcca82b60d0f5cd724edbe4ed65db18ab95d4691 0.7.2 e0f98d53debb62347c6433ca0534a0f77f15f76f 0.8.0 +38c00c788bcb03bda2ad40efebcdfe7a6be85b4a 0.9.0 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..c8af83674 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,1284 @@ +# +# Copyright (c) 2006-2014 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. +# + +if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + # Protip: run cmake like this: cmake -G "" -H. -Bbuild + message(FATAL_ERROR "Prevented in-tree build.") +endif() + +cmake_minimum_required(VERSION 2.8) + +project(love) + +if(NOT MEGA) + message(FATAL_ERROR " +It is currently only possible to build with megasource on Windows. +Please see http://bitbucket.org/rude/megasource +") +endif() + +set(LOVE_EXE_NAME love) +set(LOVE_LIB_NAME liblove) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(LOVE_X64 TRUE) + set(LOVE_TARGET_PLATFORM x64) +else() + set(LOVE_X86 TRUE) + set(LOVE_TARGET_PLATFORM x86) +endif() + +option(LOVE_JIT "Use LuaJIT" TRUE) + +if(LOVE_JIT) + message(STATUS "LuaJIT: Enabled") +else() + message(STATUS "LuaJIT: Disabled") +endif() + +message(STATUS "Target platform: ${LOVE_TARGET_PLATFORM}") + +find_package(OpenGL) + +if(${LOVE_JIT}) + set(MEGA_LUA ${MEGA_LUAJIT_LIB}) + set(MEGA_EXTRA_INCLUDE ${MEGA_LUAJIT_INCLUDE}) + set(MEGA_EXTRA_DLLS ${MEGA_LUAJIT_DLL}) + set(MEGA_EXTRA_DEPENDECIES luajit) +else() + set(MEGA_LUA ${MEGA_LUA51}) + # MEGA_LUA51 is a CMake target, so includes are handled + # automatically. +endif() + +# +# common +# + +set(LOVE_SRC_COMMON + src/common/b64.cpp + src/common/b64.h + src/common/config.h + src/common/Data.h + src/common/delay.cpp + src/common/delay.h + src/common/EnumMap.h + src/common/Exception.cpp + src/common/Exception.h + src/common/int.h + src/common/math.h + src/common/Matrix.cpp + src/common/Matrix.h + src/common/Memoizer.cpp + src/common/Memoizer.h + src/common/Module.cpp + src/common/Module.h + src/common/Object.cpp + src/common/Object.h + src/common/Reference.cpp + src/common/Reference.h + src/common/runtime.cpp + src/common/runtime.h + src/common/StringMap.h + src/common/types.h + src/common/utf8.cpp + src/common/utf8.h + src/common/Variant.cpp + src/common/Variant.h + #src/common/Vector.cpp # Vector.cpp is empty. + src/common/Vector.h + src/common/version.h + src/common/wrap_Data.cpp + src/common/wrap_Data.h +) + +source_group("common" FILES ${LOVE_SRC_COMMON}) + +# +# love.audio +# + +set(LOVE_SRC_MODULE_AUDIO_ROOT + src/modules/audio/Audio.cpp + src/modules/audio/Audio.h + src/modules/audio/Source.cpp + src/modules/audio/Source.h + src/modules/audio/wrap_Audio.cpp + src/modules/audio/wrap_Audio.h + src/modules/audio/wrap_Source.cpp + src/modules/audio/wrap_Source.h +) + +set(LOVE_SRC_MODULE_AUDIO_NULL + src/modules/audio/null/Audio.cpp + src/modules/audio/null/Audio.h + src/modules/audio/null/Source.cpp + src/modules/audio/null/Source.h +) + +set(LOVE_SRC_MODULE_AUDIO_OPENAL + src/modules/audio/openal/Audio.cpp + src/modules/audio/openal/Audio.h + src/modules/audio/openal/Pool.cpp + src/modules/audio/openal/Pool.h + src/modules/audio/openal/Source.cpp + src/modules/audio/openal/Source.h +) + +set(LOVE_SRC_MODULE_AUDIO + ${LOVE_SRC_MODULE_AUDIO_ROOT} + ${LOVE_SRC_MODULE_AUDIO_NULL} + ${LOVE_SRC_MODULE_AUDIO_OPENAL} +) + +source_group("modules\\audio" FILES ${LOVE_SRC_MODULE_AUDIO_ROOT}) +source_group("modules\\audio\\null" FILES ${LOVE_SRC_MODULE_AUDIO_NULL}) +source_group("modules\\audio\\openal" FILES ${LOVE_SRC_MODULE_AUDIO_OPENAL}) + +# +# love.event +# + +set(LOVE_SRC_MODULE_EVENT_ROOT + src/modules/event/Event.cpp + src/modules/event/Event.h +) + +set(LOVE_SRC_MODULE_EVENT_SDL + src/modules/event/sdl/Event.cpp + src/modules/event/sdl/Event.h + src/modules/event/sdl/wrap_Event.cpp + src/modules/event/sdl/wrap_Event.h +) + +set(LOVE_SRC_MODULE_EVENT + ${LOVE_SRC_MODULE_EVENT_ROOT} + ${LOVE_SRC_MODULE_EVENT_SDL} +) + +source_group("modules\\event" FILES ${LOVE_SRC_MODULE_EVENT_ROOT}) +source_group("modules\\event\\sdl" FILES ${LOVE_SRC_MODULE_EVENT_SDL}) + +# +# love.filesystem +# + +set(LOVE_SRC_MODULE_FILESYSTEM_ROOT + src/modules/filesystem/File.cpp + src/modules/filesystem/File.h + src/modules/filesystem/FileData.cpp + src/modules/filesystem/FileData.h +) + +set(LOVE_SRC_MODULE_FILESYSTEM_PHYSFS + src/modules/filesystem/physfs/File.cpp + src/modules/filesystem/physfs/File.h + src/modules/filesystem/physfs/Filesystem.cpp + src/modules/filesystem/physfs/Filesystem.h + src/modules/filesystem/physfs/wrap_File.cpp + src/modules/filesystem/physfs/wrap_File.h + src/modules/filesystem/physfs/wrap_FileData.cpp + src/modules/filesystem/physfs/wrap_FileData.h + src/modules/filesystem/physfs/wrap_Filesystem.cpp + src/modules/filesystem/physfs/wrap_Filesystem.h +) + +set(LOVE_SRC_MODULE_FILESYSTEM + ${LOVE_SRC_MODULE_FILESYSTEM_ROOT} + ${LOVE_SRC_MODULE_FILESYSTEM_PHYSFS} +) + +source_group("modules\\filesystem" FILES ${LOVE_SRC_MODULE_FILESYSTEM_ROOT}) +source_group("modules\\filesystem\\physfs" FILES ${LOVE_SRC_MODULE_FILESYSTEM_PHYSFS}) + +# +# love.font +# + +set(LOVE_SRC_MODULE_FONT_ROOT + src/modules/font/Font.h + src/modules/font/GlyphData.cpp + src/modules/font/GlyphData.h + src/modules/font/ImageRasterizer.cpp + src/modules/font/ImageRasterizer.h + src/modules/font/Rasterizer.cpp + src/modules/font/Rasterizer.h + src/modules/font/wrap_GlyphData.cpp + src/modules/font/wrap_GlyphData.h + src/modules/font/wrap_Rasterizer.cpp + src/modules/font/wrap_Rasterizer.h +) + +set(LOVE_SRC_MODULE_FONT_FREETYPE + src/modules/font/freetype/Font.cpp + src/modules/font/freetype/Font.h + src/modules/font/freetype/TrueTypeRasterizer.cpp + src/modules/font/freetype/TrueTypeRasterizer.h + src/modules/font/freetype/wrap_Font.cpp + src/modules/font/freetype/wrap_Font.h +) + +set(LOVE_SRC_MODULE_FONT + ${LOVE_SRC_MODULE_FONT_ROOT} + ${LOVE_SRC_MODULE_FONT_FREETYPE} +) + +source_group("modules\\font" FILES ${LOVE_SRC_MODULE_FONT_ROOT}) +source_group("modules\\font\\freetype" FILES ${LOVE_SRC_MODULE_FONT_FREETYPE}) + +# +# love.graphics +# + +set(LOVE_SRC_MODULE_GRAPHICS_ROOT + src/modules/graphics/Color.h + src/modules/graphics/Drawable.h + src/modules/graphics/Graphics.cpp + src/modules/graphics/Graphics.h + src/modules/graphics/Quad.cpp + src/modules/graphics/Quad.h + src/modules/graphics/Texture.cpp + src/modules/graphics/Texture.h + src/modules/graphics/Volatile.cpp + src/modules/graphics/Volatile.h +) + +set(LOVE_SRC_MODULE_GRAPHICS_OPENGL + src/modules/graphics/opengl/Canvas.cpp + src/modules/graphics/opengl/Canvas.h + src/modules/graphics/opengl/Font.cpp + src/modules/graphics/opengl/Font.h + src/modules/graphics/opengl/GLee.c + src/modules/graphics/opengl/GLee.h + src/modules/graphics/opengl/Graphics.cpp + src/modules/graphics/opengl/Graphics.h + src/modules/graphics/opengl/Image.cpp + src/modules/graphics/opengl/Image.h + src/modules/graphics/opengl/Mesh.cpp + src/modules/graphics/opengl/Mesh.h + src/modules/graphics/opengl/OpenGL.cpp + src/modules/graphics/opengl/OpenGL.h + src/modules/graphics/opengl/ParticleSystem.cpp + src/modules/graphics/opengl/ParticleSystem.h + src/modules/graphics/opengl/Polyline.cpp + src/modules/graphics/opengl/Polyline.h + src/modules/graphics/opengl/Shader.cpp + src/modules/graphics/opengl/Shader.h + src/modules/graphics/opengl/SpriteBatch.cpp + src/modules/graphics/opengl/SpriteBatch.h + src/modules/graphics/opengl/Texture.h + src/modules/graphics/opengl/VertexBuffer.cpp + src/modules/graphics/opengl/VertexBuffer.h + src/modules/graphics/opengl/wrap_Canvas.cpp + src/modules/graphics/opengl/wrap_Canvas.h + src/modules/graphics/opengl/wrap_Font.cpp + src/modules/graphics/opengl/wrap_Font.h + src/modules/graphics/opengl/wrap_Graphics.cpp + src/modules/graphics/opengl/wrap_Graphics.h + src/modules/graphics/opengl/wrap_Image.cpp + src/modules/graphics/opengl/wrap_Image.h + src/modules/graphics/opengl/wrap_Mesh.cpp + src/modules/graphics/opengl/wrap_Mesh.h + src/modules/graphics/opengl/wrap_ParticleSystem.cpp + src/modules/graphics/opengl/wrap_ParticleSystem.h + src/modules/graphics/opengl/wrap_Quad.cpp + src/modules/graphics/opengl/wrap_Quad.h + src/modules/graphics/opengl/wrap_Shader.cpp + src/modules/graphics/opengl/wrap_Shader.h + src/modules/graphics/opengl/wrap_SpriteBatch.cpp + src/modules/graphics/opengl/wrap_SpriteBatch.h + src/modules/graphics/opengl/wrap_Texture.cpp + src/modules/graphics/opengl/wrap_Texture.h +) + +set(LOVE_SRC_MODULE_GRAPHICS + ${LOVE_SRC_MODULE_GRAPHICS_ROOT} + ${LOVE_SRC_MODULE_GRAPHICS_OPENGL} +) + +source_group("modules\\graphics" FILES ${LOVE_SRC_MODULE_GRAPHICS_ROOT}) +source_group("modules\\graphics\\opengl" FILES ${LOVE_SRC_MODULE_GRAPHICS_OPENGL}) + +# +# love.image +# + +set(LOVE_SRC_MODULE_IMAGE_ROOT + src/modules/image/CompressedData.cpp + src/modules/image/CompressedData.h + src/modules/image/Image.h + src/modules/image/ImageData.cpp + src/modules/image/ImageData.h + src/modules/image/wrap_CompressedData.cpp + src/modules/image/wrap_CompressedData.h + src/modules/image/wrap_Image.cpp + src/modules/image/wrap_Image.h + src/modules/image/wrap_ImageData.cpp + src/modules/image/wrap_ImageData.h +) + +set(LOVE_SRC_MODULE_IMAGE_MAGPIE + src/modules/image/magpie/CompressedData.cpp + src/modules/image/magpie/CompressedData.h + src/modules/image/magpie/ddsHandler.cpp + src/modules/image/magpie/ddsHandler.h + src/modules/image/magpie/DevilHandler.cpp + src/modules/image/magpie/DevilHandler.h + src/modules/image/magpie/FormatHandler.h + src/modules/image/magpie/Image.cpp + src/modules/image/magpie/Image.h + src/modules/image/magpie/ImageData.cpp + src/modules/image/magpie/ImageData.h +) + +set(LOVE_SRC_MODULE_IMAGE + ${LOVE_SRC_MODULE_IMAGE_ROOT} + ${LOVE_SRC_MODULE_IMAGE_MAGPIE} +) + +source_group("modules\\image" FILES ${LOVE_SRC_MODULE_IMAGE_ROOT}) +source_group("modules\\image\\magpie" FILES ${LOVE_SRC_MODULE_IMAGE_MAGPIE}) + +# +# love.joystick +# + +set(LOVE_SRC_MODULE_JOYSTICK_ROOT + src/modules/joystick/Joystick.cpp + src/modules/joystick/Joystick.h + src/modules/joystick/JoystickModule.h +) + +set(LOVE_SRC_MODULE_JOYSTICK_SDL + src/modules/joystick/sdl/Joystick.cpp + src/modules/joystick/sdl/Joystick.h + src/modules/joystick/sdl/JoystickModule.cpp + src/modules/joystick/sdl/JoystickModule.h + src/modules/joystick/sdl/wrap_Joystick.cpp + src/modules/joystick/sdl/wrap_Joystick.h + src/modules/joystick/sdl/wrap_JoystickModule.cpp + src/modules/joystick/sdl/wrap_JoystickModule.h +) + +set(LOVE_SRC_MODULE_JOYSTICK + ${LOVE_SRC_MODULE_JOYSTICK_ROOT} + ${LOVE_SRC_MODULE_JOYSTICK_SDL} +) + +source_group("modules\\joystick" FILES ${LOVE_SRC_MODULE_JOYSTICK_ROOT}) +source_group("modules\\joystick\\sdl" FILES ${LOVE_SRC_MODULE_JOYSTICK_SDL}) + +# +# love.keyboard +# + +set(LOVE_SRC_MODULE_KEYBOARD_ROOT + src/modules/keyboard/Keyboard.cpp + src/modules/keyboard/Keyboard.h + src/modules/keyboard/wrap_Keyboard.cpp + src/modules/keyboard/wrap_Keyboard.h +) + +set(LOVE_SRC_MODULE_KEYBOARD_SDL + src/modules/keyboard/sdl/Keyboard.cpp + src/modules/keyboard/sdl/Keyboard.h +) + +set(LOVE_SRC_MODULE_KEYBOARD + ${LOVE_SRC_MODULE_KEYBOARD_ROOT} + ${LOVE_SRC_MODULE_KEYBOARD_SDL} +) + +source_group("modules\\keyboard" FILES ${LOVE_SRC_MODULE_KEYBOARD_ROOT}) +source_group("modules\\keyboard\\sdl" FILES ${LOVE_SRC_MODULE_KEYBOARD_SDL}) + +# +# love.math +# + +set(LOVE_SRC_MODULE_MATH + src/modules/math/BezierCurve.cpp + src/modules/math/BezierCurve.h + src/modules/math/MathModule.cpp + src/modules/math/MathModule.h + src/modules/math/RandomGenerator.cpp + src/modules/math/RandomGenerator.h + src/modules/math/wrap_BezierCurve.cpp + src/modules/math/wrap_BezierCurve.h + src/modules/math/wrap_Math.cpp + src/modules/math/wrap_Math.h + src/modules/math/wrap_RandomGenerator.cpp + src/modules/math/wrap_RandomGenerator.h +) + +source_group("modules\\math" FILES ${LOVE_SRC_MODULE_MATH}) + +# +# love (module) +# +set(LOVE_SRC_MODULE_LOVE + src/modules/love/love.cpp + src/modules/love/love.h +) + +source_group("modules\\love" FILES ${LOVE_SRC_MODULE_LOVE}) + +# +# love.mouse +# + +set(LOVE_SRC_MODULE_MOUSE_ROOT + src/modules/mouse/Cursor.cpp + src/modules/mouse/Cursor.h + src/modules/mouse/Mouse.cpp + src/modules/mouse/Mouse.h + src/modules/mouse/wrap_Cursor.cpp + src/modules/mouse/wrap_Cursor.h + src/modules/mouse/wrap_Mouse.cpp + src/modules/mouse/wrap_Mouse.h +) + +set(LOVE_SRC_MODULE_MOUSE_SDL + src/modules/mouse/sdl/Cursor.cpp + src/modules/mouse/sdl/Cursor.h + src/modules/mouse/sdl/Mouse.cpp + src/modules/mouse/sdl/Mouse.h +) + +set(LOVE_SRC_MODULE_MOUSE + ${LOVE_SRC_MODULE_MOUSE_ROOT} + ${LOVE_SRC_MODULE_MOUSE_SDL} +) + +source_group("modules\\mouse" FILES ${LOVE_SRC_MODULE_MOUSE_ROOT}) +source_group("modules\\mouse\\sdl" FILES ${LOVE_SRC_MODULE_MOUSE_SDL}) + +# +# love.physics +# + +set(LOVE_SRC_MODULE_PHYSICS_ROOT + src/modules/physics/Body.cpp + src/modules/physics/Body.h + src/modules/physics/Joint.cpp + src/modules/physics/Joint.h + src/modules/physics/Shape.cpp + src/modules/physics/Shape.h +) + +set(LOVE_SRC_MODULE_PHYSICS_BOX2D + src/modules/physics/box2d/Body.cpp + src/modules/physics/box2d/Body.h + src/modules/physics/box2d/ChainShape.cpp + src/modules/physics/box2d/ChainShape.h + src/modules/physics/box2d/CircleShape.cpp + src/modules/physics/box2d/CircleShape.h + src/modules/physics/box2d/Contact.cpp + src/modules/physics/box2d/Contact.h + src/modules/physics/box2d/DistanceJoint.cpp + src/modules/physics/box2d/DistanceJoint.h + src/modules/physics/box2d/EdgeShape.cpp + src/modules/physics/box2d/EdgeShape.h + src/modules/physics/box2d/Fixture.cpp + src/modules/physics/box2d/Fixture.h + src/modules/physics/box2d/FrictionJoint.cpp + src/modules/physics/box2d/FrictionJoint.h + src/modules/physics/box2d/GearJoint.cpp + src/modules/physics/box2d/GearJoint.h + src/modules/physics/box2d/Joint.cpp + src/modules/physics/box2d/Joint.h + src/modules/physics/box2d/MotorJoint.cpp + src/modules/physics/box2d/MotorJoint.h + src/modules/physics/box2d/MouseJoint.cpp + src/modules/physics/box2d/MouseJoint.h + src/modules/physics/box2d/Physics.cpp + src/modules/physics/box2d/Physics.h + src/modules/physics/box2d/PolygonShape.cpp + src/modules/physics/box2d/PolygonShape.h + src/modules/physics/box2d/PrismaticJoint.cpp + src/modules/physics/box2d/PrismaticJoint.h + src/modules/physics/box2d/PulleyJoint.cpp + src/modules/physics/box2d/PulleyJoint.h + src/modules/physics/box2d/RevoluteJoint.cpp + src/modules/physics/box2d/RevoluteJoint.h + src/modules/physics/box2d/RopeJoint.cpp + src/modules/physics/box2d/RopeJoint.h + src/modules/physics/box2d/Shape.cpp + src/modules/physics/box2d/Shape.h + src/modules/physics/box2d/WeldJoint.cpp + src/modules/physics/box2d/WeldJoint.h + src/modules/physics/box2d/WheelJoint.cpp + src/modules/physics/box2d/WheelJoint.h + src/modules/physics/box2d/World.cpp + src/modules/physics/box2d/World.h + src/modules/physics/box2d/wrap_Body.cpp + src/modules/physics/box2d/wrap_Body.h + src/modules/physics/box2d/wrap_ChainShape.cpp + src/modules/physics/box2d/wrap_ChainShape.h + src/modules/physics/box2d/wrap_CircleShape.cpp + src/modules/physics/box2d/wrap_CircleShape.h + src/modules/physics/box2d/wrap_Contact.cpp + src/modules/physics/box2d/wrap_Contact.h + src/modules/physics/box2d/wrap_DistanceJoint.cpp + src/modules/physics/box2d/wrap_DistanceJoint.h + src/modules/physics/box2d/wrap_EdgeShape.cpp + src/modules/physics/box2d/wrap_EdgeShape.h + src/modules/physics/box2d/wrap_Fixture.cpp + src/modules/physics/box2d/wrap_Fixture.h + src/modules/physics/box2d/wrap_FrictionJoint.cpp + src/modules/physics/box2d/wrap_FrictionJoint.h + src/modules/physics/box2d/wrap_GearJoint.cpp + src/modules/physics/box2d/wrap_GearJoint.h + src/modules/physics/box2d/wrap_Joint.cpp + src/modules/physics/box2d/wrap_Joint.h + src/modules/physics/box2d/wrap_MotorJoint.cpp + src/modules/physics/box2d/wrap_MotorJoint.h + src/modules/physics/box2d/wrap_MouseJoint.cpp + src/modules/physics/box2d/wrap_MouseJoint.h + src/modules/physics/box2d/wrap_Physics.cpp + src/modules/physics/box2d/wrap_Physics.h + src/modules/physics/box2d/wrap_PolygonShape.cpp + src/modules/physics/box2d/wrap_PolygonShape.h + src/modules/physics/box2d/wrap_PrismaticJoint.cpp + src/modules/physics/box2d/wrap_PrismaticJoint.h + src/modules/physics/box2d/wrap_PulleyJoint.cpp + src/modules/physics/box2d/wrap_PulleyJoint.h + src/modules/physics/box2d/wrap_RevoluteJoint.cpp + src/modules/physics/box2d/wrap_RevoluteJoint.h + src/modules/physics/box2d/wrap_RopeJoint.cpp + src/modules/physics/box2d/wrap_RopeJoint.h + src/modules/physics/box2d/wrap_Shape.cpp + src/modules/physics/box2d/wrap_Shape.h + src/modules/physics/box2d/wrap_WeldJoint.cpp + src/modules/physics/box2d/wrap_WeldJoint.h + src/modules/physics/box2d/wrap_WheelJoint.cpp + src/modules/physics/box2d/wrap_WheelJoint.h + src/modules/physics/box2d/wrap_World.cpp + src/modules/physics/box2d/wrap_World.h +) + +set(LOVE_SRC_MODULE_PHYSICS + ${LOVE_SRC_MODULE_PHYSICS_ROOT} + ${LOVE_SRC_MODULE_PHYSICS_BOX2D} +) + +source_group("modules\\physics" FILES ${LOVE_SRC_MODULE_PHYSICS_ROOT}) +source_group("modules\\physics\\box2d" FILES ${LOVE_SRC_MODULE_PHYSICS_BOX2D}) + +# +# love.sound +# + +set(LOVE_SRC_MODULE_SOUND_ROOT + src/modules/sound/Decoder.h + src/modules/sound/Sound.cpp + src/modules/sound/Sound.h + src/modules/sound/SoundData.cpp + src/modules/sound/SoundData.h + src/modules/sound/wrap_Decoder.cpp + src/modules/sound/wrap_Decoder.h + src/modules/sound/wrap_Sound.cpp + src/modules/sound/wrap_Sound.h + src/modules/sound/wrap_SoundData.cpp + src/modules/sound/wrap_SoundData.h +) + +set(LOVE_SRC_MODULE_SOUND_LULLABY + src/modules/sound/lullaby/Decoder.cpp + src/modules/sound/lullaby/Decoder.h + src/modules/sound/lullaby/FLACDecoder.cpp + src/modules/sound/lullaby/FLACDecoder.h + src/modules/sound/lullaby/GmeDecoder.cpp + src/modules/sound/lullaby/GmeDecoder.h + src/modules/sound/lullaby/ModPlugDecoder.cpp + src/modules/sound/lullaby/ModPlugDecoder.h + src/modules/sound/lullaby/Mpg123Decoder.cpp + src/modules/sound/lullaby/Mpg123Decoder.h + src/modules/sound/lullaby/Sound.cpp + src/modules/sound/lullaby/Sound.h + src/modules/sound/lullaby/VorbisDecoder.cpp + src/modules/sound/lullaby/VorbisDecoder.h + src/modules/sound/lullaby/WaveDecoder.cpp + src/modules/sound/lullaby/WaveDecoder.h +) + +set(LOVE_SRC_MODULE_SOUND + ${LOVE_SRC_MODULE_SOUND_ROOT} + ${LOVE_SRC_MODULE_SOUND_LULLABY} +) + +source_group("modules\\sound" FILES ${LOVE_SRC_MODULE_SOUND_ROOT}) +source_group("modules\\sound\\lullaby" FILES ${LOVE_SRC_MODULE_SOUND_LULLABY}) + +# +# love.system +# + +set(LOVE_SRC_MODULE_SYSTEM_ROOT + src/modules/system/System.cpp + src/modules/system/System.h + src/modules/system/wrap_System.cpp + src/modules/system/wrap_System.h +) + +set(LOVE_SRC_MODULE_SYSTEM_SDL + src/modules/system/sdl/System.cpp + src/modules/system/sdl/System.h +) + +set(LOVE_SRC_MODULE_SYSTEM + ${LOVE_SRC_MODULE_SYSTEM_ROOT} + ${LOVE_SRC_MODULE_SYSTEM_SDL} +) + +source_group("modules\\system" FILES ${LOVE_SRC_MODULE_SYSTEM_ROOT}) +source_group("modules\\system\\sdl" FILES ${LOVE_SRC_MODULE_SYSTEM_SDL}) + +# +# love.thread +# + +set(LOVE_SRC_MODULE_THREAD_ROOT + src/modules/thread/Channel.cpp + src/modules/thread/Channel.h + src/modules/thread/LuaThread.cpp + src/modules/thread/LuaThread.h + src/modules/thread/Thread.h + src/modules/thread/ThreadModule.cpp + src/modules/thread/ThreadModule.h + src/modules/thread/threads.cpp + src/modules/thread/threads.h + src/modules/thread/wrap_Channel.cpp + src/modules/thread/wrap_Channel.h + src/modules/thread/wrap_LuaThread.cpp + src/modules/thread/wrap_LuaThread.h + src/modules/thread/wrap_ThreadModule.cpp + src/modules/thread/wrap_ThreadModule.h +) + +set(LOVE_SRC_MODULE_THREAD_SDL + src/modules/thread/sdl/Thread.cpp + src/modules/thread/sdl/Thread.h + src/modules/thread/sdl/threads.cpp + src/modules/thread/sdl/threads.h +) + +set(LOVE_SRC_MODULE_THREAD + ${LOVE_SRC_MODULE_THREAD_ROOT} + ${LOVE_SRC_MODULE_THREAD_SDL} +) + +source_group("modules\\thread" FILES ${LOVE_SRC_MODULE_THREAD_ROOT}) +source_group("modules\\thread\\sdl" FILES ${LOVE_SRC_MODULE_THREAD_SDL}) + +# +# love.timer +# + +set(LOVE_SRC_MODULE_TIMER_ROOT + src/modules/timer/Timer.h + src/modules/timer/wrap_Timer.cpp + src/modules/timer/wrap_Timer.h +) + +set(LOVE_SRC_MODULE_TIMER_SDL + src/modules/timer/sdl/Timer.cpp + src/modules/timer/sdl/Timer.h +) + +set(LOVE_SRC_MODULE_TIMER + ${LOVE_SRC_MODULE_TIMER_ROOT} + ${LOVE_SRC_MODULE_TIMER_SDL} +) + +source_group("modules\\timer" FILES ${LOVE_SRC_MODULE_TIMER_ROOT}) +source_group("modules\\timer\\sdl" FILES ${LOVE_SRC_MODULE_TIMER_SDL}) + +# +# love.window +# + +set(LOVE_SRC_MODULE_WINDOW_ROOT + src/modules/window/Window.cpp + src/modules/window/Window.h + src/modules/window/wrap_Window.cpp + src/modules/window/wrap_Window.h +) + +set(LOVE_SRC_MODULE_WINDOW_SDL + src/modules/window/sdl/Window.cpp + src/modules/window/sdl/Window.h +) + +set(LOVE_SRC_MODULE_WINDOW + ${LOVE_SRC_MODULE_WINDOW_ROOT} + ${LOVE_SRC_MODULE_WINDOW_SDL} +) + +source_group("modules\\window" FILES ${LOVE_SRC_MODULE_WINDOW_ROOT}) +source_group("modules\\window\\sdl" FILES ${LOVE_SRC_MODULE_WINDOW_SDL}) + +################################### +# Third-party libraries +################################### + +# +# Box2D +# + +set(LOVE_SRC_3P_BOX2D_ROOT + src/libraries/Box2D/Box2D.h +) + +set(LOVE_SRC_3P_BOX2D_COLLISION + src/libraries/Box2D/Collision/b2BroadPhase.cpp + src/libraries/Box2D/Collision/b2BroadPhase.h + src/libraries/Box2D/Collision/b2CollideCircle.cpp + src/libraries/Box2D/Collision/b2CollideEdge.cpp + src/libraries/Box2D/Collision/b2CollidePolygon.cpp + src/libraries/Box2D/Collision/b2Collision.cpp + src/libraries/Box2D/Collision/b2Collision.h + src/libraries/Box2D/Collision/b2Distance.cpp + src/libraries/Box2D/Collision/b2Distance.h + src/libraries/Box2D/Collision/b2DynamicTree.cpp + src/libraries/Box2D/Collision/b2DynamicTree.h + src/libraries/Box2D/Collision/b2TimeOfImpact.cpp + src/libraries/Box2D/Collision/b2TimeOfImpact.h +) + +set(LOVE_SRC_3P_BOX2D_COLLISION_SHAPES + src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp + src/libraries/Box2D/Collision/Shapes/b2ChainShape.h + src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp + src/libraries/Box2D/Collision/Shapes/b2CircleShape.h + src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp + src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h + src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp + src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h + src/libraries/Box2D/Collision/Shapes/b2Shape.h +) + +set(LOVE_SRC_3P_BOX2D_COMMON + src/libraries/Box2D/Common/b2BlockAllocator.cpp + src/libraries/Box2D/Common/b2BlockAllocator.h + src/libraries/Box2D/Common/b2Draw.cpp + src/libraries/Box2D/Common/b2Draw.h + src/libraries/Box2D/Common/b2GrowableStack.h + src/libraries/Box2D/Common/b2Math.cpp + src/libraries/Box2D/Common/b2Math.h + src/libraries/Box2D/Common/b2Settings.cpp + src/libraries/Box2D/Common/b2Settings.h + src/libraries/Box2D/Common/b2StackAllocator.cpp + src/libraries/Box2D/Common/b2StackAllocator.h + src/libraries/Box2D/Common/b2Timer.cpp + src/libraries/Box2D/Common/b2Timer.h +) + +set(LOVE_SRC_3P_BOX2D_DYNAMICS + src/libraries/Box2D/Dynamics/b2Body.cpp + src/libraries/Box2D/Dynamics/b2Body.h + src/libraries/Box2D/Dynamics/b2ContactManager.cpp + src/libraries/Box2D/Dynamics/b2ContactManager.h + src/libraries/Box2D/Dynamics/b2Fixture.cpp + src/libraries/Box2D/Dynamics/b2Fixture.h + src/libraries/Box2D/Dynamics/b2Island.cpp + src/libraries/Box2D/Dynamics/b2Island.h + src/libraries/Box2D/Dynamics/b2TimeStep.h + src/libraries/Box2D/Dynamics/b2World.cpp + src/libraries/Box2D/Dynamics/b2World.h + src/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp + src/libraries/Box2D/Dynamics/b2WorldCallbacks.h +) + +set(LOVE_SRC_3P_BOX2D_DYNAMICS_CONTACTS + src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h + src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h + src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h + src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2Contact.h + src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp + src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h + src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h + src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h + src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h + src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp + src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h +) + +set(LOVE_SRC_3P_BOX2D_DYNAMICS_JOINTS + src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h + src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h + src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2GearJoint.h + src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp + src/libraries/Box2D/Dynamics/Joints/b2Joint.h + src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h + src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h + src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h + src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h + src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h + src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h + src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h + src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp + src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h +) + +set(LOVE_SRC_3P_BOX2D_ROPE + src/libraries/Box2D/Rope/b2Rope.cpp + src/libraries/Box2D/Rope/b2Rope.h +) + +set(LOVE_SRC_3P_BOX2D + ${LOVE_SRC_3P_BOX2D_ROOT} + ${LOVE_SRC_3P_BOX2D_COLLISION} + ${LOVE_SRC_3P_BOX2D_COLLISION_SHAPES} + ${LOVE_SRC_3P_BOX2D_COMMON} + ${LOVE_SRC_3P_BOX2D_DYNAMICS} + ${LOVE_SRC_3P_BOX2D_DYNAMICS_CONTACTS} + ${LOVE_SRC_3P_BOX2D_DYNAMICS_JOINTS} + ${LOVE_SRC_3P_BOX2D_ROPE} +) + +add_library(love_3p_box2d ${LOVE_SRC_3P_BOX2D}) + +# +# ddsparse +# + +set(LOVE_SRC_3P_DDSPARSE + src/libraries/ddsparse/ddsinfo.h + src/libraries/ddsparse/ddsparse.cpp + src/libraries/ddsparse/ddsparse.h +) + +add_library(love_3p_ddsparse ${LOVE_SRC_3P_DDSPARSE}) + +# +# enet +# + +set(LOVE_SRC_3P_ENET_ROOT + src/libraries/enet/enet.cpp + src/libraries/enet/lua-enet.h +) + +set(LOVE_SRC_3P_ENET_LIBENET + src/libraries/enet/libenet/callbacks.c + src/libraries/enet/libenet/compress.c + src/libraries/enet/libenet/host.c + src/libraries/enet/libenet/list.c + src/libraries/enet/libenet/packet.c + src/libraries/enet/libenet/peer.c + src/libraries/enet/libenet/protocol.c + src/libraries/enet/libenet/unix.c + src/libraries/enet/libenet/win32.c +) + +set(LOVE_SRC_3P_ENET_LIBENET_INCLUDE_ENET + src/libraries/enet/libenet/include/enet/enet.h + src/libraries/enet/libenet/include/enet/list.h + src/libraries/enet/libenet/include/enet/protocol.h + src/libraries/enet/libenet/include/enet/time.h + src/libraries/enet/libenet/include/enet/types.h + src/libraries/enet/libenet/include/enet/unix.h + src/libraries/enet/libenet/include/enet/utility.h + src/libraries/enet/libenet/include/enet/win32.h +) + +set(LOVE_SRC_3P_ENET + ${LOVE_SRC_3P_ENET_ROOT} + ${LOVE_SRC_3P_ENET_LIBENET} + ${LOVE_SRC_3P_ENET_LIBENET_INCLUDE_ENET} +) + +add_library(love_3p_enet ${LOVE_SRC_3P_ENET}) +target_link_libraries(love_3p_enet ${MEGA_LUA}) +target_include_directories(love_3p_enet PUBLIC src/libraries/enet/libenet/include) + +# +# luasocket +# + +set(LOVE_SRC_3P_LUASOCKET_ROOT + src/libraries/luasocket/luasocket.cpp + src/libraries/luasocket/luasocket.h +) + +set(LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET + src/libraries/luasocket/libluasocket/auxiliar.c + src/libraries/luasocket/libluasocket/auxiliar.h + src/libraries/luasocket/libluasocket/buffer.c + src/libraries/luasocket/libluasocket/buffer.h + src/libraries/luasocket/libluasocket/except.c + src/libraries/luasocket/libluasocket/except.h + src/libraries/luasocket/libluasocket/ftp.lua.h + src/libraries/luasocket/libluasocket/http.lua.h + src/libraries/luasocket/libluasocket/inet.c + src/libraries/luasocket/libluasocket/inet.h + src/libraries/luasocket/libluasocket/io.c + src/libraries/luasocket/libluasocket/io.h + src/libraries/luasocket/libluasocket/ltn12.lua.h + src/libraries/luasocket/libluasocket/lua.h + src/libraries/luasocket/libluasocket/luasocket.c + src/libraries/luasocket/libluasocket/luasocket.h + src/libraries/luasocket/libluasocket/mime.c + src/libraries/luasocket/libluasocket/mime.h + src/libraries/luasocket/libluasocket/mime.lua.h + src/libraries/luasocket/libluasocket/options.c + src/libraries/luasocket/libluasocket/options.h + src/libraries/luasocket/libluasocket/select.c + src/libraries/luasocket/libluasocket/select.h + src/libraries/luasocket/libluasocket/smtp.lua.h + src/libraries/luasocket/libluasocket/socket.h + src/libraries/luasocket/libluasocket/socket.lua.h + src/libraries/luasocket/libluasocket/tcp.c + src/libraries/luasocket/libluasocket/tcp.h + src/libraries/luasocket/libluasocket/timeout.c + src/libraries/luasocket/libluasocket/timeout.h + src/libraries/luasocket/libluasocket/tp.lua.h + src/libraries/luasocket/libluasocket/udp.c + src/libraries/luasocket/libluasocket/udp.h + src/libraries/luasocket/libluasocket/url.lua.h +) + +if(MSVC) + set(LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET + ${LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET} + src/libraries/luasocket/libluasocket/wsocket.c + src/libraries/luasocket/libluasocket/wsocket.h + ) +endif() + +set(LOVE_SRC_3P_LUASOCKET + ${LOVE_SRC_3P_LUASOCKET_ROOT} + ${LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET} +) + +add_library(love_3p_luasocket ${LOVE_SRC_3P_LUASOCKET}) +target_link_libraries(love_3p_luasocket ${MEGA_LUA}) + +# +# noise1234 +# + +set(LOVE_SRC_3P_NOISE1234 + src/libraries/noise1234/simplexnoise1234.cpp + src/libraries/noise1234/simplexnoise1234.h +) + +add_library(love_3p_noise1234 ${LOVE_SRC_3P_NOISE1234}) + +# +# utf8 +# + +set(LOVE_SRC_3P_UTF8_ROOT src/libraries/utf8/utf8.h) + +set(LOVE_SRC_3P_UTF8_UTF8 + src/libraries/utf8/utf8/checked.h + src/libraries/utf8/utf8/core.h + src/libraries/utf8/utf8/unchecked.h +) + +set(LOVE_SRC_3P_UTF8 + ${LOVE_SRC_3P_UTF8_ROOT} + ${LOVE_SRC_3P_UTF8_UTF8} +) + +# This library is all headers ... so there is no need to +# add_library() here. + +# +# Wuff +# + +set(LOVE_SRC_3P_WUFF + src/libraries/Wuff/wuff.c + src/libraries/Wuff/wuff.h + src/libraries/Wuff/wuff_config.h + src/libraries/Wuff/wuff_convert.c + src/libraries/Wuff/wuff_convert.h + src/libraries/Wuff/wuff_internal.c + src/libraries/Wuff/wuff_internal.h + src/libraries/Wuff/wuff_memory.c +) + +add_library(love_3p_wuff ${LOVE_SRC_3P_WUFF}) + +set(LOVE_3P + love_3p_box2d + love_3p_ddsparse + love_3p_enet + love_3p_luasocket + love_3p_noise1234 + love_3p_wuff +) + +disable_warnings(love_3p_box2d love_3p_enet love_3p_luasocket) + +# +# liblove +# +set(LOVE_LIB_SRC + ${LOVE_SRC_COMMON} + # Modules + ${LOVE_SRC_MODULE_AUDIO} + ${LOVE_SRC_MODULE_EVENT} + ${LOVE_SRC_MODULE_FILESYSTEM} + ${LOVE_SRC_MODULE_FONT} + ${LOVE_SRC_MODULE_GRAPHICS} + ${LOVE_SRC_MODULE_IMAGE} + ${LOVE_SRC_MODULE_JOYSTICK} + ${LOVE_SRC_MODULE_KEYBOARD} + ${LOVE_SRC_MODULE_LOVE} + ${LOVE_SRC_MODULE_MATH} + ${LOVE_SRC_MODULE_MOUSE} + ${LOVE_SRC_MODULE_PHYSICS} + ${LOVE_SRC_MODULE_SOUND} + ${LOVE_SRC_MODULE_SYSTEM} + ${LOVE_SRC_MODULE_THREAD} + ${LOVE_SRC_MODULE_TIMER} + ${LOVE_SRC_MODULE_WINDOW} +) + +include_directories( + src + src/libraries + src/modules + ${MEGA_EXTRA_INCLUDE} +) + +# SDL2 links with some DirectX libraries, and we apparently also +# pull those libraries in for linkage because we link with SDL2. +link_directories(${SDL_LINK_DIR}) + +set(LOVE_MEGA_3P + ${MEGA_DEVIL} + ${MEGA_FREETYPE} + ${MEGA_JASPER} + ${MEGA_JPEG} + ${MEGA_LIBOGG} + ${MEGA_LIBPNG} + ${MEGA_LIBVORBISFILE} + ${MEGA_LIBVORBIS} + ${MEGA_LUA} + ${MEGA_MODPLUG} + ${MEGA_MPEG123} + ${MEGA_OPENAL} + ${MEGA_PHYSFS} + ${MEGA_SDL2MAIN} + ${MEGA_SDL2} + ${MEGA_TIFF} + ${MEGA_ZLIB} +) + +set(LOVE_LINK_LIBRARIES + ${OPENGL_gl_LIBRARY} + ${LOVE_MEGA_3P} +) + +set(LOVE_RC) + +if(MSVC) + set(LOVE_LINK_LIBRARIES ${LOVE_LINK_LIBRARIES} + ws2_32.lib + winmm.lib + ) + + set(LOVE_RC + platform/msvc2010/love.rc + platform/msvc2010/love.ico + ) +endif() + +add_library(${LOVE_LIB_NAME} SHARED ${LOVE_LIB_SRC} ${LOVE_RC}) +target_link_libraries(liblove ${LOVE_LINK_LIBRARIES} ${LOVE_3P}) + +if(MEGA_EXTRA_DEPENDECIES) + add_dependencies(${LOVE_LIB_NAME} ${MEGA_EXTRA_DEPENDECIES}) +endif() + +if(MSVC) + set_target_properties(${LOVE_LIB_NAME} PROPERTIES RELEASE_OUTPUT_NAME "love" PDB_NAME "liblove") + set_target_properties(${LOVE_LIB_NAME} PROPERTIES DEBUG_OUTPUT_NAME "love" PDB_NAME "liblove") +endif() + +# +# love (executable) +# +add_executable(${LOVE_EXE_NAME} WIN32 src/love.cpp ${LOVE_RC}) +target_link_libraries(love liblove) + +# Add post build steps to move the DLLs next to the binary. Otherwise +# running/debugging the binary will not work from inside VS. +add_move_dll(love ${MEGA_MPEG123}) +add_move_dll(love ${MEGA_SDL2}) +add_move_dll(love ${MEGA_OPENAL}) +add_move_dll(love ${MEGA_DEVIL}) + +if(LOVE_JIT) + add_move_file(love ${MEGA_LUAJIT_DLL}) +else() + add_move_dll(love ${MEGA_LUA51}) +endif() + +################################### +# Version +################################### + +# Extract version.h contents. +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/common/version.h LOVE_VERSION_FILE_CONTENTS) + +# Extract one of LOVE_VERSION_MAJOR/MINOR/REV. +function(match_version ARG_STRING OUT_VAR) + string(REGEX MATCH "VERSION_${ARG_STRING} = ([0-9]+);" TMP_VER "${LOVE_VERSION_FILE_CONTENTS}") + string(REGEX MATCH "[0-9]+" TMP_VER "${TMP_VER}") + set(${OUT_VAR} ${TMP_VER} PARENT_SCOPE) +endfunction() + +match_version("MAJOR" LOVE_VERSION_MAJOR) +match_version("MINOR" LOVE_VERSION_MINOR) +match_version("REV" LOVE_VERSION_REV) + +set(LOVE_VERSION_STR "${LOVE_VERSION_MAJOR}.${LOVE_VERSION_MINOR}.${LOVE_VERSION_REV}") + +message(STATUS "Version: ${LOVE_VERSION_STR}") + +################################### +# CPack +################################### +install(TARGETS love ${LOVE_LIB_NAME} RUNTIME DESTINATION .) + +# Extra DLLs. +if(MEGA_EXTRA_DLLS) + foreach(DLL ${MEGA_EXTRA_DLLS}) + get_filename_component(DLL_NAME ${DLL} NAME) + message(STATUS "Extra DLL: ${DLL_NAME}") + endforeach() + install(FILES ${MEGA_EXTRA_DLLS} DESTINATION .) +endif() + +# Dynamic runtime libs. +if(MEGA_MSVC_DLLS) + foreach(DLL ${MEGA_MSVC_DLLS}) + get_filename_component(DLL_NAME ${DLL} NAME) + message(STATUS "Runtime DLL: ${DLL_NAME}") + endforeach() + install(FILES ${MEGA_MSVC_DLLS} DESTINATION .) +endif() + +# Copy a text file from CMAKE_CURRENT_SOURCE_DIR to CMAKE_CURRENT_BINARY_DIR. +# On Windows, this function will convert line endings to CR,LF. +function(copy_text_file ARG_FILE_IN ARG_FILE_OUT) + file(READ ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_FILE_IN} TMP_TXT_CONTENTS) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${ARG_FILE_OUT} ${TMP_TXT_CONTENTS}) +endfunction() + +# Text files. +copy_text_file(readme.md readme.txt) +copy_text_file(license.txt license.txt) +copy_text_file(changes.txt changes.txt) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/changes.txt + ${CMAKE_CURRENT_BINARY_DIR}/license.txt + ${CMAKE_CURRENT_BINARY_DIR}/readme.txt + DESTINATION .) + +# Icons +install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/extra/nsis/love.ico + ${CMAKE_CURRENT_SOURCE_DIR}/extra/nsis/game.ico + DESTINATION .) + +set(CPACK_GENERATOR ZIP NSIS) +set(CPACK_PACKAGE_NAME "love") +set(CPACK_PACKAGE_VENDOR "love2d.org") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LOVE -- It's awesome") +set(CPACK_PACKAGE_VERSION "${LOVE_VERSION_STR}") +set(CPACK_PACKAGE_VERSION_MAJOR "${LOVE_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${LOVE_VERSION_MINOR}") +set(CPACK_PACKAGE_VERSION_PATCH "${LOVE_VERSION_REV}") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "LOVE") +set(CPACK_PACKAGE_EXECUTABLES "love;LOVE") +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt") + +set(CPACK_NSIS_EXECUTABLES_DIRECTORY .) +set(CPACK_NSIS_PACKAGE_NAME "LOVE") +set(CPACK_NSIS_DISPLAY_NAME "LÖVE ${LOVE_VERSION_STR}") +set(CPACK_NSIS_MODIFY_PATH OFF) + +if(LOVE_X64) + set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64") +else() + set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES") +endif() + +set(CPACK_NSIS_MENU_LINKS "http://love2d.org/wiki" "Documentation") + +# Some bug somewhere in NSIS requires "\\\\" somewhere in the path, +# according to The Internet. (And sure enough, it does not work +# without it). +set(NSIS_LEFT_BMP "${CMAKE_CURRENT_SOURCE_DIR}/extra/nsis\\\\left.bmp") +set(NSIS_TOP_BMP "${CMAKE_CURRENT_SOURCE_DIR}/extra/nsis\\\\top.bmp") +set(NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/extra/nsis\\\\love.ico") +set(NSIS_MUI_UNICON "${CMAKE_CURRENT_SOURCE_DIR}/extra/nsis\\\\love.ico") + +set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE " + !define MUI_WELCOMEPAGE_TITLE \\\"LÖVE ${LOVE_VERSION_STR} Setup\\\" + !define MUI_WELCOMEFINISHPAGE_BITMAP \\\"${NSIS_LEFT_BMP}\\\" + !define MUI_HEADERIMAGE_BITMAP \\\"${NSIS_TOP_BMP}\\\" + !define MUI_ICON \\\"${NSIS_MUI_ICON}\\\" + !define MUI_UNICON \\\"${NSIS_MUI_UNICON}\\\" +") + +set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS " + WriteRegStr HKCR \\\".love\\\" \\\"\\\" \\\"LOVE\\\" + WriteRegStr HKCR \\\"LOVE\\\" \\\"\\\" \\\"LOVE Game File\\\" + WriteRegStr HKCR \\\"LOVE\\\\DefaultIcon\\\" \\\"\\\" \\\"$INSTDIR\\\\game.ico\\\" + WriteRegStr HKCR \\\"LOVE\\\\shell\\\" \\\"\\\" \\\"open\\\" + WriteRegStr HKCR \\\"LOVE\\\\shell\\\\open\\\" \\\"\\\" \\\"Open in LOVE\\\" + WriteRegStr HKCR \\\"LOVE\\\\shell\\\\open\\\\command\\\" \\\"\\\" \\\"$INSTDIR\\\\love.exe $\\\\\\\"%1$\\\\\\\"\\\" + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' +") + +set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS " + DeleteRegKey HKCR \\\"LOVE\\\" + DeleteRegKey HKCR \\\".love\\\" + System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' +") + +include(CPack) diff --git a/changes.txt b/changes.txt index 925e7ffd2..569cb7ef4 100644 --- a/changes.txt +++ b/changes.txt @@ -1,72 +1,251 @@ -LOVE 0.9.0 [] --------------- +LOVE 0.9.1 [Baby Inspector] +--------------------------- + Released: N/A + + * Added Source:clone. + * Added ParticleSystem:clone. + * Added Mesh:setWireframe and Mesh:isWireframe for debugging. + * Added CircleShape:getPoint and CircleShape:setPoint. + * Added Mesh/SpriteBatch/ParticleSystem:setTexture, accepts Canvases and Images. + + * Deprecated Mesh/SpriteBatch/ParticleSystem:setImage. + + * Fixed love.graphics.scale with negative values causing incorrect line widths. + * Fixed Joystick:isDown using 0-based button index arguments. + * Fixed Source:setPitch to error when infinity or NaN is given. + * Fixed love.graphics.setCanvas() to restore the proper viewport and scissor rectangles. + * Fixed TrueType font glyphs which request a monochrome bitmap pixel mode. + * Fixed love.graphics.reset causing crashes when called in between love.graphics.push/pop. + + * Updated the error text for love.filesystem’s module searchers when require fails. + * Updated the love.filesystem module searchers to be tried after package.preload instead of before. + * Updated love.graphics.newParticleSystem, newSpriteBatch, and newMesh to accept Canvases. + * Updated Canvas drawing code, texture coordinates are no longer flipped vertically. + +LOVE 0.9.0 [Baby Inspector] +--------------------------- + + Released: 2013-12-13 + + * Added better multiplayer networking support via ENet. * Added --fused command line argument, to simulate fusing. * Added liblove. * Added the ability to have exit values. * Added exit value of 1 in case of error by default. - * Added love.joystick.reload. * Added basic support for the file:// uri scheme. - * Added love.mouse.setX/setY. + * Added love.filesystem.isFused. * Added love.filesystem.getIdentity. - * Added HDR canvas support. - * Added Source:isPlaying. - * Added mipmapping support (has isSupported test). + * Added love.filesystem.append. + * Added love.filesystem.getSize. + * Added love.filesystem.mount and love.filesystem.unmount. + * Added optional file search order parameter to love.filesystem.setIdentity. + * Added File:isOpen and File:getMode. + * Added Fie:setBuffer, File:getBuffer, and File:flush. + * Added textinput event for unicode text input. + * Added love.keyboard.setTextInput and love.keyboard.hasTextInput. + * Added previously internal Rasterizer and GlyphData object methods. + * Added support for UTF-8 ImageFonts. * Added Font:getAscent/getDescent/getBaseline. - * Added Canvas:getPixel. + * Added Font:setFilter/getFilter. + * Added Font:hasGlyphs. + * Added angle, scale, and shear parameters to love.graphics.printf. + * Added HDR canvas support. + * Added mipmapping support (has isSupported test). * Added vertex shader support. * Added boolean support to Shader:send. - * Added support for UTF-8 ImageFonts. - * Added SoundData:getDuration. - * Added new Channels api for love.thread. - * Added flags to setMode. - * Added support for resizable and borderless windows. - * Added resize event. + * Added Canvas:getPixel. + * Added blend mode "replace". + * Added line join modes. + * Added Mesh objects, allowing for arbitrary textured polygons. + * Added multiple render target support to love.graphics.setCanvas. + * Added love.graphics.setColorMask. + * Added love.graphics.origin. + * Added love.graphics.getRendererInfo. + * Added love.graphics.getMaxImageSize. + * Added SpriteBatch:getCount and SpriteBatch:getBufferSize. + * Added SpriteBatch:getColor. + * Added ParticleSystem:emit. + * Added ParticleSystem:setInsertMode and ParticleSystem:getInsertMode. + * Added many ParticleSystem getter methods. + * Added DXT compressed texture support via love.image.newCompressedData. + * Added love.image.isCompressed and Image:isCompressed. + * Added Image/Canvas/ImageData:getDimensions. + * Added anisotropic filtering support for Images, Canvases, and Fonts. + * Added Image:refresh. + * Added Image:getData. + * Added SoundData:getDuration and SoundData:getSampleCount. + * Added Source:isPlaying. + * Added Source:setRelative and Source:isRelative. + * Added Source:setCone and Source:getCone. + * Added Source:getChannels. + * Added new Channels API for love.thread. + * Added limited table support to Channel:push. + * Added Thread:getError. + * Added Thread:isRunning. + * Added threaderror event. * Added love.math module. * Added a platform-independent (good) random implementation to love.math. - * OPTIONAL: Added support for GME. + * Added RandomGenerator objects. + * Added BezierCurve objects. + * Added love.math.triangulate and love.math.isConvex. + * Added love.math.noise. + * Added love.timer.getAverageDelta. + * Added Data:getString. + * Added Contact:getChildren. + * Added love.system module. + * Added love.system.getClipboardText and love.system.setClipboardText. + * Added love.system.getOS and love.system.getProcessorCount. + * Added love.window module. + * Added love.window.isVisible. + * Added flags to love.window.setMode. + * Added monitor choosing support to love.window.setMode. + * Added support for resizable, borderless, and non-centered windows. + * Added support for "fullscreen-desktop" mode. + * Added window resize and visible events. + * Added love.window.getDimensions. + * Added love.window.getIcon. + * Added t.window.icon to love.conf. + * Added love.mousefocus and love.window.hasMouseFocus. + * Added custom hardware cursors via love.mouse.newCursor. + * Added love.mouse.setX/setY. + * Added Joystick objects. + * Added love.joystick.getJoystick. + * Added joystick connect and disconnect events. + * Added joystickaxis and joystickhat events. + * Added unified Gamepad API for joysticks which have a similar layout to the Xbox controller. + * Added joystick vibration support, works with most common gamepads. + * OPTIONAL: Added support for Game Music Emu. - * Fixed crashes with font drawing on some ATI cards. + * Fixed fused mode in OS X. + * Fixed printing to the console in Windows before love.load is called. + * Fixed the default love.run to not include the time taken by love.load in the first frame's dt. + * Fixed the error screen not always appearing until the next input event. + * Fixed love.event.clear. + * Fixed love.mouse.setPosition when called in love.load. * Fixed scaling in several love.physics functions. + * Fixed Box2D exception in World:update. + * Fixed many uncaught Box2D / love.physics exceptions for Bodies and Joints. + * Fixed ChainShape:getPoints running out of Lua stack space and crashing. + * Fixed File:read reading past end of file. + * Fixed love.filesystem.setIdentity not removing read access from old directories. + * Fixed possible memory leak in utf-8 decoder. + * Fixed spacing for the last character in an ImageFont. + * Fixed line wrapping in love.graphics.printf. + * Fixed love.graphics.printf to error if the wrap limit is negative. + * Fixed love.graphics.print truncating strings with embedded zeros. + * Fixed crashes with font drawing on some ATI cards. * Fixed artifacts when drawing lines at huge scale. - * Fixed ImageFonts ignoring default image filter. + * Fixed Fonts and Canvases ignoring default image filter. + * Fixed scissor boxes when a canvas is set after love.graphics.setScissor is called. + * Fixed love.graphics.getLineWidth returning incorrect values. + * Fixed love.graphics.getColor on some Windows systems. + * Fixed alpha blend mode. + * Fixed multiplicative blend mode. + * Fixed love.graphics.getPointStyle. + * Fixed line numbers in shader errors. + * Fixed Shader:send with Images and Canvases failing sometimes. + * Fixed Shader:send to keep a reference to sent Images and Canvases. + * Fixed crash when binding SpriteBatches multiple times. + * Fixed SpriteBatches with more than 16,384 sprites. + * Fixed particle draw order for ParticleSystems. + * Fixed ParticleSystem:setSizes resetting the size variation. + * Fixed the graphics viewport not matching the window size when using an unsupported fullscreen mode. * Fixed getMode and friends returning wrong values when using desktop size. + * Fixed keyrepeat settings being lost after (indirect) setMode. + * Fixed the icon being reset after setMode. * Fixed memory leak in the mp3 decoder. * Fixed sound issues with some versions of OpenAL soft, by enabling direct channels. * Fixed 'random' hangs in audio. - * Fixed love.graphics.getLineWidth returning incorrect values. - * Fixed possible memory leak in utf-8 decoder. * Fixed love.sound.newDecoder not accepting FileData. - * Fixed multiplicative blend mode. - * Fixed Box2D exception in World:update. - * Fixed spacing for the last character in an ImageFont. - * Fixed crash when locking SpriteBatches multiple times. - * Fixed File:read reading past end of file. - * Fixed keyrepeat settings being lost after (indirect) setMode. + * Fixed case (in)sensitivity of sound file extension parsing. + * Fixed looping support in tracker music formats. + * Fixed skipping/looping issues when playing streaming audio Sources. + * Fixed race condition in Source:play. + * Fixed WAVE sound playback. * Moved love's startup to modules/love. + * Moved window-related functions from love.graphics to love.window. * Renamed love's boot script to 'love.boot', which can be required. + * Renamed love.filesystem.mkdir to love.filesystem.createDirectory. + * Renamed love.filesystem.enumerate to love.filesystem.getDirectoryItems. + * Renamed World:setAllowSleeping to World:setSleepingAllowed. + * Renamed ChainShape:setPrevVertex to ChainShape:setPreviousVertex. + * Renamed Joint:enableMotor to Joint:setMotorEnabled. + * Renamed Joint:enableLimit and Joint:isLimitEnabled to Joint:setLimitsEnabled and Joint:hasLimitsEnabled. + * Renamed t.screen to t.window in love.conf. + * Renamed love.graphics.setCaption to love.window.setTitle. * Renamed PixelEffect to Shader (but now with vertex shaders). + * Renamed love.graphics.setDefaultImageFilter to love.graphics.setDefaultFilter. + * Renamed ParticleSystem:setSprite to ParticleSystem:setImage. + * Renamed ParticleSystem:setGravity to ParticleSystem:setLinearAcceleration. + * Renamed ParticleSystem:setLifetime/setParticleLife to setEmitter/ParticleLifetime. + * Renamed ParticleSystem:count and all getNum* functions to get*Count. + * Renamed Source:setDistance to Source:setAttenuationDistances. + * Renamed SoundData:getBits and Decoder:getBits to SoundData:getBitDepth and Decoder:getBitDepth. + * Renamed love.mouse.setGrab to love.mouse.setGrabbed. - * Removed love.joystick.open and friends. + * Removed release mode. + * Removed love.keyboard.getKeyRepeat (see love.keyboard.hasKeyRepeat). + * Removed the unicode argument from love.keypressed (see love.textinput). * Removed love.graphics.drawTest. - * Removed thread names. - * Removed old thread messaging api (see Channels). * Removed love.graphics.quad/triangle. + * Removed love.graphics.setColorMode. + * Removed love.graphics.newStencil. + * Removed love.graphics.setLine/setPoint. + * Removed love.graphics.drawq (functionality is merged into love.graphics.draw). + * Removed SpriteBatch:addq/setq (functionality is merged into SpriteBatch:add/set). + * Removed Quad:flip. + * Removed ParticleSystem:isFull/isEmpty. + * Removed ParticleSystem:getX/getY. + * Removed love.graphics.checkMode. + * Removed love.joystick.open and friends. + * Removed love.joystick module functions which operated on individual joysticks (see Joystick objects). + * Removed joystick ball support. + * Removed thread names. + * Removed old thread messaging API (see Channels). + * Removed love.timer.getMicroTime. - * Updated allocation for SoundData, it's more efficient and less wasteful. - * Updated Source:set* functions to default z to 0. + * Updated functions which return love objects to re-use the Lua-side object instead of always recreating it. * Updated the windows console, it now tries to re-use an active one first. - * Updated love.image memory handling, improves errors and thread-safety. - * Updated order of sleep/present in love.run (now draws, *then* sleeps). - * Updated the setFilter and setWrap methods, the second argument is now optional. - * Updated font rendering code, now more performant. * Updated error handling, error handlers now get resolved when the error occurs. + * Updated order of sleep/present in love.run (now draws, *then* sleeps). + * Updated love.filesystem to try to create the appdata directory if it doesn't exist yet. + * Updated the default filesystem identity to omit file extension. + * Updated love.filesystem.newFile to optionally open the file. + * Updated most love.filesystem functions to return nil, error on internal failure. + * Updated love.keyboard.setKeyRepeat to take a boolean argument instead of numbers. + * Updated love.keypressed's second argument to be a boolean indicating key repeat. + * Updated keyboard key constants for some more modern keyboard keys. + * Updated window code to use adaptive vsync when available, if vsync is enabled. + * updated love.graphics.print's x and y arguments to default to 0. + * Updated the setFilter and setWrap methods, the second argument is now optional. + * Updated Font and ParticleSystem rendering code, now more performant. + * Updated SpriteBatch code, now more performant when adding/setting and (un)binding. + * Updated Canvas code to support more systems. + * Updated Canvas:getImageData and love.graphics.newScreenshot to be more efficient. + * Updated love.graphics.newScreenshot to create a fully opaque image by default. + * Updated error messages when sending bad values to Shaders. + * Updated love.graphics.newParticleSystem to have a default buffer size of 1000. + * Updated ImageData:setPixel to accept a table and default to 255 alpha. + * Updated ImageData:mapPixel, is now more efficient and accepts optional x,y,w,h arguments. + * Updated love.image memory handling, improves errors and thread-safety. + * Updated all love object constructors to optionally accept FileData if they accept a filename. + * Updated allocation for SoundData, it's more efficient and less wasteful. + * Updated SoundData:set/getSample to error for invalid samples. + * Updated Source:set* functions to default z to 0. + * Updated Source:seek to error for negative offsets. + * Updated Thread:start to accept arguments which get passed to the thread. + * Updated love.timer.getFPS to be microsecond-accurate. + * Updated love.timer.getTime to be microsecond-accurate and monotonic. + * Updated Box2D to version 2.3.0. LOVE 0.8.0 [Rubber Piggy] ------------------------- + Released: 2012-04-02 + * Added release error screen. * Added alpha to love.graphics.setBackgroundColor. * Added Canvas:clear(r, g, b, a). @@ -156,6 +335,8 @@ LOVE 0.8.0 [Rubber Piggy] LOVE 0.7.2 [Game Slave] ----------------------- + Released: 2011-05-04 + * Added Framebuffer:get/setWrap. * Added love.event.clear. * Added support for any number of arguments to love.keyboard.isDown, love.mouse.isDown and love.joystick.isDown. @@ -180,6 +361,8 @@ LOVE 0.7.2 [Game Slave] LOVE 0.7.1 [Game Slave] ----------------------- + Released: 2011-02-14 + * Added source:isPaused() * Added error when initial window can't be created. * Added framebuffer filter modes. @@ -214,6 +397,8 @@ LOVE 0.7.1 [Game Slave] LOVE 0.7.0 [Game Slave] ----------------------- + Released: 2010-12-05 + * Added love.thread. * Added love.font. * Added love.graphics.Framebuffer. @@ -268,6 +453,8 @@ LOVE 0.7.0 [Game Slave] LOVE 0.6.2 [Jiggly Juice] ------------------------- + Released: 2010-03-06 + * Fixed a bug causing ImageFonts to cut off some pixels. * Fixed a bug where filled rectangles were too small. * Fixed a bug in Image:setFilter where it would switch the parameters. @@ -280,6 +467,8 @@ LOVE 0.6.2 [Jiggly Juice] LOVE 0.6.1 [Jiggly Juice] ------------------------- + Released: 2010-02-07 + * Added Shape:setGroupIndex and getGroupIndex. * Added Body:setFixedRotation and Body:getFixedRotation. * Added Body:setInertia. @@ -303,6 +492,8 @@ LOVE 0.6.1 [Jiggly Juice] LOVE 0.6.0 [Jiggly Juice] ------------------------- + Released: 2009-12-24 + * Lost track of 0.6.0 changes a long while ago. Don't trust the list below. * Added love.graphics.print()/printf(). @@ -338,6 +529,8 @@ LOVE 0.6.0 [Jiggly Juice] LOVE 0.5.0 [Salted Nuts] ------------------------ + Released: 2009-01-02 + * Added love.joystick. * Added network support via LuaSocket. * Added support for loading of appended .love-file. @@ -373,6 +566,8 @@ LOVE 0.5.0 [Salted Nuts] LOVE 0.4.0 [Taco Beam] ---------------------- + Released: 2008-08-29 + * Added love.physics. (YES!) * Added love.audio.setMode(). * Added love.audio.setChannels(). @@ -385,6 +580,8 @@ LOVE 0.4.0 [Taco Beam] LOVE 0.3.2 [Lemony Fresh] ------------------------- + Released: 2008-07-04 + * Added love.graphics.rectangle() * Added love.graphics.setLineWidth() * Added love.graphics.setLineStyle() @@ -402,6 +599,8 @@ LOVE 0.3.2 [Lemony Fresh] LOVE 0.3.1 [Space Meat] ----------------------- + Released: 2008-06-21 + * Fixed segfault related to graphics. * Fixed wait-forever bug related to audio. * Fixed error reporting not working across modules. @@ -411,6 +610,8 @@ LOVE 0.3.1 [Space Meat] LOVE 0.3.0 [Mutant Vermin] -------------------------- + Released: 2008-06-17 + * Added ParticleSystem. * Added visual error reporting. * Added love.system for game control needs. @@ -429,6 +630,8 @@ LOVE 0.3.0 [Mutant Vermin] LOVE 0.2.1 [Impending Doom] --------------------------- + Released: 2008-03-29 + * Added many functions in love.filesystem. * Added a dedicated save-folder for each game. * Added timer.sleep. @@ -463,6 +666,8 @@ LOVE 0.2.1 [Impending Doom] LOVE 0.2.0 [Mini-Moose] ----------------------- + Released: 2008-02-06 + * Added ImageFont * Added Animation * Added text formatting functions @@ -481,7 +686,8 @@ LOVE 0.2.0 [Mini-Moose] LOVE 0.1.1 [Santa-Power] ------------------------ -Initial release! + Initial release! + Released: 2008-01-13 * Image loading and rendering. * Sound loading and playing. diff --git a/license.txt b/license.txt index b530dd64d..c087cc71c 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2006-2012 LOVE Development Team +Copyright (c) 2006-2014 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 @@ -21,13 +21,10 @@ distribution. - ------- + LÖVE also uses the following LGPL libraries: - - SDL - Website: http://libsdl.org - Source download: http://www.libsdl.org/release/SDL-1.2.14.tar.gz - libmpg123 Website: http://www.mpg123.de/ Source download: http://sourceforge.net/projects/mpg123/files/latest/download diff --git a/platform/macosx/Info-Framework.plist b/platform/macosx/Info-Framework.plist index fcc7ee4ce..2bdfccf99 100644 --- a/platform/macosx/Info-Framework.plist +++ b/platform/macosx/Info-Framework.plist @@ -17,11 +17,11 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.8.0 + 0.9.0 CFBundleSignature LoVe CFBundleVersion - 0.8.0 + 0.9.0 NSPrincipalClass diff --git a/platform/macosx/OSX.h b/platform/macosx/OSX.h new file mode 100644 index 000000000..6a6d8b804 --- /dev/null +++ b/platform/macosx/OSX.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_OSX_H +#define LOVE_OSX_H + +#include + +namespace love +{ +namespace osx +{ + +/** + * Returns the filepath of the first detected love file in the Resources folder + * in love.app. + * Returns an empty string if no love file is found. + **/ +std::string getLoveInResources(); + +/** + * Checks for drop-file events. Returns the filepath if an event occurred, or + * an empty string otherwise. + **/ +std::string checkDropEvents(); + +} // osx +} // love + +#endif // LOVE_OSX_H diff --git a/platform/macosx/OSX.mm b/platform/macosx/OSX.mm new file mode 100644 index 000000000..418de494f --- /dev/null +++ b/platform/macosx/OSX.mm @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#import "OSX.h" +#import + +#include + +namespace love +{ +namespace osx +{ + +std::string getLoveInResources() +{ + std::string path; + + @autoreleasepool + { + // check to see if there are any .love files in Resources - props to stevejohnson/diordna + NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil]; + if ([lovePaths count] > 0) + { + NSString *firstLovePath = [lovePaths objectAtIndex:0]; + path = std::string([firstLovePath UTF8String]); + } + } + + return path; +} + +std::string checkDropEvents() +{ + std::string dropstr; + SDL_Event event; + + bool initvideo = SDL_WasInit(SDL_INIT_VIDEO) != 0; + if (!initvideo) + SDL_InitSubSystem(SDL_INIT_VIDEO); + + SDL_PumpEvents(); + if (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_DROPFILE, SDL_DROPFILE) > 0) + { + if (event.type == SDL_DROPFILE) + { + dropstr = std::string(event.drop.file); + SDL_free(event.drop.file); + } + } + + if (!initvideo) + SDL_QuitSubSystem(SDL_INIT_VIDEO); + + return dropstr; +} + +} // osx +} // love diff --git a/platform/macosx/SDLMain.h b/platform/macosx/SDLMain.h deleted file mode 100644 index 8f89029e2..000000000 --- a/platform/macosx/SDLMain.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import -#import "SDL/SDL.h" - -@interface SDLMain : NSObject -@end diff --git a/platform/macosx/SDLMain.m b/platform/macosx/SDLMain.m deleted file mode 100644 index a6d4bf075..000000000 --- a/platform/macosx/SDLMain.m +++ /dev/null @@ -1,437 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -//#import "SDL.h" -#import "SDLMain.h" -#import /* for MAXPATHLEN */ -#import - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; -@end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ -@interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; -@end -#endif - -@interface SDLApplication : NSApplication -@end - -@implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} - -/* Hack to make Cocoa ignore keystrokes that aren't shortcuts, otherwise it beeps on every key press */ -- (void)sendEvent:(NSEvent *)theEvent { - if (NSKeyDown == [theEvent type] || NSKeyUp == [theEvent type]) { - if ([theEvent modifierFlags] & NSCommandKeyMask) - [super sendEvent: theEvent]; - } else { - [super sendEvent: theEvent]; - } -} -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -/*CHANGED to Bundle's Resource Directory. */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - /* - char parentdir[PATH_MAX]; - //CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, PATH_MAX)) { - assert ( chdir (parentdir) == 0 ); // chdir to the binary app's parent // - } - CFRelease(url); - CFRelease(url2); - */ - CFBundleRef mainBundle = CFBundleGetMainBundle(); - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); - char path[PATH_MAX]; - if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) - { - // error! - } - CFRelease(resourcesURL); - chdir(path); - } - -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[[NSMenu alloc] init] autorelease]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Set up the app to receive menu events via keyboard shortcut */ - setenv("SDL_ENABLEAPPEVENTS", "1", 1); - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} -@end - - -@implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - -@end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - - /* check to see if there are any .love files in Resources - props to stevejohnson/diordna */ - NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil]; - if ([lovePaths count] > 0) { /* there are, load the first one we found and run it */ - NSString *firstLovePath = [lovePaths objectAtIndex:0]; - gCalledAppMainline = YES; - //NSLog(firstLovePath); - - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - temparg = [firstLovePath UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *)SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - newargv = (char **)realloc(gArgv, sizeof(char *) * (gArgc + 2)); - if (newargv == NULL) { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - } - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} diff --git a/platform/macosx/autobuild b/platform/macosx/autobuild deleted file mode 100755 index b7aa7bef5..000000000 --- a/platform/macosx/autobuild +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -cd ../.. - -# Check which revision to build. -if [ -z $2 ]; then - buildrev="tip" -else - buildrev=$2 -fi - -# Update to the appropriate revision. -hg pull -hg update $buildrev - -# Set the displayversion. -if [ -z $3 ]; then - if [ "$buildrev" == "tip" ]; then - # Get the current SVN version, use sed to remove any non-numbers. - currentversion=`hg log -l1 | grep changeset | sed 's/.*://g'` - currentdate=`date +%Y%m%d` - displayversion="$currentdate-$currentversion" - else - # The revision is already specified, so we'll use that as the - # display version. - displayversion="$buildrev" - fi -else - # If the param is present, it overrides everything else. - displayversion=$3 -fi - -cd platform/macosx - -outfile="love-$displayversion-macosx-ub" -outdmg="$outfile.dmg" -outlog="$outfile.log" - -xcodebuild > $outlog 2>&1 - -cp love.dmg $outdmg - -# Deal with uploading. -if [ "$1" == "build" ]; then - pass=`cat pwtehlol` - ftp -u ftp://love2d:$pass@love2d.org/public_html/builds/files/$outdmg $outdmg - ftp -u ftp://love2d:$pass@love2d.org/public_html/builds/files/$outlog $outlog -fi - -if [ "$1" == "release" ]; then - echo "release" -fi - diff --git a/platform/macosx/love-Info.plist b/platform/macosx/love-Info.plist index 112b95bab..b14f6022a 100644 --- a/platform/macosx/love-Info.plist +++ b/platform/macosx/love-Info.plist @@ -13,12 +13,12 @@ LÖVE Project CFBundleTypeRole Viewer + LSHandlerRank + Owner LSItemContentTypes org.love2d.love-game - LSHandlerRank - Owner CFBundleTypeName @@ -46,13 +46,13 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.8.0 + 0.9.0 CFBundleSignature LoVe + LSApplicationCategoryType + public.app-category.games NSHumanReadableCopyright - © 2006-2013 LÖVE Development Team - NSMainNibFile - SDLMain + © 2006-2014 LÖVE Development Team NSPrincipalClass NSApplication UTExportedTypeDeclarations diff --git a/platform/macosx/love-framework.xcodeproj/project.pbxproj b/platform/macosx/love-framework.xcodeproj/project.pbxproj index d5deeecb1..dedef2bf8 100644 --- a/platform/macosx/love-framework.xcodeproj/project.pbxproj +++ b/platform/macosx/love-framework.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + FA01BE1E1878E35B00640047 /* wrap_Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA01BE1C1878E35B00640047 /* wrap_Texture.cpp */; }; + FA01BE1F1878E35B00640047 /* wrap_Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA01BE1D1878E35B00640047 /* wrap_Texture.h */; }; + FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA03546A1731F3A700284828 /* simplexnoise1234.cpp */; }; + FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */ = {isa = PBXBuildFile; fileRef = FA03546B1731F3A700284828 /* simplexnoise1234.h */; }; FA08F5B016C752F900F007B5 /* Source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2FB732687B1669402408356D /* Source.cpp */; }; FA08F5B116C752F900F007B5 /* wrap_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02CA1BE908D91B104EB9590F /* wrap_Audio.cpp */; }; FA08F5B216C752F900F007B5 /* wrap_Source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02662CBC29B954295A634A39 /* wrap_Source.cpp */; }; @@ -19,7 +23,6 @@ FA08F5B916C7532A00F007B5 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D383DA1468545C30E7B5805 /* b64.cpp */; }; FA08F5BA16C7532A00F007B5 /* delay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36437CE95936736320710513 /* delay.cpp */; }; FA08F5BB16C7532A00F007B5 /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3746164716797CF80D6B0CEE /* Exception.cpp */; }; - FA08F5BC16C7532A00F007B5 /* math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 168502C6505A6D455C4F69AA /* math.cpp */; }; FA08F5BD16C7532A00F007B5 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CB6025618505B055A4E75DD /* Matrix.cpp */; }; FA08F5BE16C7532A00F007B5 /* Memoizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40A0593B616A223A4CEF07C9 /* Memoizer.cpp */; }; FA08F5BF16C7532A00F007B5 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 30E466F441EE727658716873 /* Module.cpp */; }; @@ -108,11 +111,8 @@ FA08F61216C753E700F007B5 /* Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B1C4E4D288A1D2F29E57B1B /* Rasterizer.cpp */; }; FA08F61316C753E700F007B5 /* wrap_GlyphData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4E22F1388E2B2E76E3377B /* wrap_GlyphData.cpp */; }; FA08F61416C753E700F007B5 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11745DE315E859F71E881D76 /* wrap_Rasterizer.cpp */; }; - FA08F61516C753F600F007B5 /* Drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58BA2BB460AF3C591B22690E /* Drawable.cpp */; }; - FA08F61616C753F600F007B5 /* DrawQable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 346C3C7F62FA35DA2C9C4F69 /* DrawQable.cpp */; }; FA08F61716C753F600F007B5 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F17FF546D637744E263961 /* Graphics.cpp */; }; - FA08F61816C753F600F007B5 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58CC50E70A375FDF53EF01B6 /* Image.cpp */; }; - FA08F61916C753F600F007B5 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D3B224C2F9D2359288028FD /* Quad.cpp */; }; + FA08F61816C753F600F007B5 /* Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58CC50E70A375FDF53EF01B6 /* Texture.cpp */; }; FA08F61A16C753F600F007B5 /* Volatile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B731754147B27AF73AC5358 /* Volatile.cpp */; }; FA08F61B16C7541400F007B5 /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AD52074367950B735707CE1 /* Canvas.cpp */; }; FA08F61C16C7541400F007B5 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 583037E9238A6EF00DD20B1A /* Font.cpp */; }; @@ -121,7 +121,6 @@ FA08F61F16C7541400F007B5 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56D6030A0B8F7397715062B9 /* Image.cpp */; }; FA08F62016C7541400F007B5 /* OpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E406F8328543EC63EB922C6 /* OpenGL.cpp */; }; FA08F62116C7541400F007B5 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 48A206C9004150640C432100 /* ParticleSystem.cpp */; }; - FA08F62216C7541400F007B5 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74504EB554D871C36DD55F17 /* Quad.cpp */; }; FA08F62316C7541400F007B5 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA577A8516C71CF000860150 /* Shader.cpp */; }; FA08F62416C7541400F007B5 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */; }; FA08F62516C7541400F007B5 /* VertexBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 426B1C4475DC54505B824B7F /* VertexBuffer.cpp */; }; @@ -130,17 +129,15 @@ FA08F62816C7541400F007B5 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */; }; FA08F62916C7541400F007B5 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */; }; FA08F62A16C7541400F007B5 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */; }; - FA08F62B16C7541400F007B5 /* wrap_Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162283C11024AC35897618C /* wrap_Quad.cpp */; }; FA08F62C16C7541400F007B5 /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA577A8716C71CF000860150 /* wrap_Shader.cpp */; }; FA08F62D16C7541400F007B5 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C16FDB537A702F4D42534E /* wrap_SpriteBatch.cpp */; }; FA08F62E16C7542600F007B5 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 78115E763B723C0C40AD47CF /* ImageData.cpp */; }; FA08F62F16C7542600F007B5 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505F23A73BFE250833D650E4 /* Image.cpp */; }; - FA08F63016C7542600F007B5 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7781A230065F346E2313A /* ImageData.cpp */; }; + FA08F63016C7542600F007B5 /* DevilHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7781A230065F346E2313A /* DevilHandler.cpp */; }; FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */; }; FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */; }; - FA08F63316C7542D00F007B5 /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 677F545C76EA3B247329358D /* Joystick.cpp */; }; - FA08F63416C7542D00F007B5 /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B425307C0C1C4B3EFC3A5F /* Joystick.cpp */; }; - FA08F63516C7542D00F007B5 /* wrap_Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139411436818381E493F00F5 /* wrap_Joystick.cpp */; }; + FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */; }; + FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */; }; FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 524741891BB93848039F4174 /* Keyboard.cpp */; }; FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */; }; FA08F63816C7543400F007B5 /* wrap_Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19F40DF6507028212FEB1D77 /* wrap_Keyboard.cpp */; }; @@ -205,30 +202,132 @@ FA08F67316C754A100F007B5 /* Mpg123Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F875B224C4E1B9E35854766 /* Mpg123Decoder.cpp */; }; FA08F67416C754A100F007B5 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A5F7DCB40652F9B7D61073A /* Sound.cpp */; }; FA08F67516C754A100F007B5 /* VorbisDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 727648E06CD863A2582F798F /* VorbisDecoder.cpp */; }; - FA08F67616C754A900F007B5 /* Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D9B456C6C554F66660F7650 /* Thread.cpp */; }; FA08F67716C754A900F007B5 /* threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B3565203A1778431F8A5409 /* threads.cpp */; }; - FA08F67816C754A900F007B5 /* wrap_Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3348511C3BCE65F003DA68CD /* wrap_Thread.cpp */; }; FA08F67916C754B100F007B5 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 113269E55FCF208D2D6754BC /* Timer.cpp */; }; FA08F67A16C754B100F007B5 /* wrap_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 695E4ED13AA0689E64280573 /* wrap_Timer.cpp */; }; FA08F67B16C754BA00F007B5 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 351B09E51FDC338622F44624 /* Window.cpp */; }; FA08F67C16C754BA00F007B5 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6CDD4F3320303D222C180CD0 /* Window.cpp */; }; + FA0A4BF0182E0C2800E1E4D2 /* b2MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A4BEE182E0C2800E1E4D2 /* b2MotorJoint.cpp */; }; + FA0A4BF1182E0C2800E1E4D2 /* b2MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A4BEF182E0C2800E1E4D2 /* b2MotorJoint.h */; }; + FA0A4BF4182E1AD600E1E4D2 /* MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A4BF2182E1AD600E1E4D2 /* MotorJoint.cpp */; }; + FA0A4BF5182E1AD600E1E4D2 /* MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A4BF3182E1AD600E1E4D2 /* MotorJoint.h */; }; + FA0A4BF9182E260200E1E4D2 /* wrap_MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A4BF7182E260200E1E4D2 /* wrap_MotorJoint.h */; }; + FA0A4BFA182E26F500E1E4D2 /* wrap_MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A4BF6182E260200E1E4D2 /* wrap_MotorJoint.cpp */; }; + FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */; }; + FA1EF7C41799FEAC00FF380C /* wrap_System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */; }; + FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7D5174B55AF00E04D3F /* wrap_System.h */; }; + FA34E7CD174B513F00E04D3F /* System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7CB174B513F00E04D3F /* System.cpp */; }; + FA34E7CE174B513F00E04D3F /* System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7CC174B513F00E04D3F /* System.h */; }; + FA34E7D2174B515D00E04D3F /* System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7D0174B515D00E04D3F /* System.cpp */; }; + FA34E7D3174B515D00E04D3F /* System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7D1174B515D00E04D3F /* System.h */; }; + FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */; }; + FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E0C16E68DE600CA6630 /* Cursor.h */; }; + FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */; }; + FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1016E68EAE00CA6630 /* Cursor.h */; }; + FA3D9E1516E6D41100CA6630 /* wrap_Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */; }; + FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */; }; + FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA435EA117B36E9C004C3F22 /* Polyline.cpp */; }; + FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = FA435EA217B36E9C004C3F22 /* Polyline.h */; }; + FA5454C216F1310000D30303 /* MathModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5454C016F1310000D30303 /* MathModule.cpp */; }; + FA5454C316F1310000D30303 /* MathModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5454C116F1310000D30303 /* MathModule.h */; }; FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; }; FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6716C719D900860150 /* FreeType.framework */; }; - FA577AC316C7512F00860150 /* Game_Music_Emu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6B16C719E400860150 /* Game_Music_Emu.framework */; }; FA577AC416C7513200860150 /* IL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6916C719DE00860150 /* IL.framework */; }; FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A8216C71A5300860150 /* libmodplug.framework */; }; - FA577AC616C7513800860150 /* Lua.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6D16C719EA00860150 /* Lua.framework */; }; FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6F16C719F000860150 /* mpg123.framework */; }; FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7116C719F400860150 /* Ogg.framework */; }; FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7C16C71A2600860150 /* OpenGL.framework */; }; FA577ACB16C7514400860150 /* physfs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7316C719F900860150 /* physfs.framework */; }; - FA577ACC16C7514700860150 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7516C719FF00860150 /* SDL.framework */; }; FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7716C71A0800860150 /* Vorbis.framework */; }; - FA7C937816DCC6C2006F2BEE /* ModMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937316DCC6C2006F2BEE /* ModMath.cpp */; }; - FA7C937916DCC6C2006F2BEE /* ModMath.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937416DCC6C2006F2BEE /* ModMath.h */; }; + FA5FDC791788D548002F0ED2 /* enet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC5F1788D548002F0ED2 /* enet.cpp */; }; + FA5FDC7A1788D548002F0ED2 /* callbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC611788D548002F0ED2 /* callbacks.c */; }; + FA5FDC7C1788D548002F0ED2 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC631788D548002F0ED2 /* compress.c */; }; + FA5FDC7D1788D548002F0ED2 /* host.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC641788D548002F0ED2 /* host.c */; }; + FA5FDC7E1788D548002F0ED2 /* callbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC671788D548002F0ED2 /* callbacks.h */; }; + FA5FDC7F1788D548002F0ED2 /* enet.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC681788D548002F0ED2 /* enet.h */; }; + FA5FDC801788D548002F0ED2 /* list.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC691788D548002F0ED2 /* list.h */; }; + FA5FDC811788D548002F0ED2 /* protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6A1788D548002F0ED2 /* protocol.h */; }; + FA5FDC821788D548002F0ED2 /* time.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6B1788D548002F0ED2 /* time.h */; }; + FA5FDC831788D548002F0ED2 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6C1788D548002F0ED2 /* types.h */; }; + FA5FDC841788D548002F0ED2 /* unix.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6D1788D548002F0ED2 /* unix.h */; }; + FA5FDC851788D548002F0ED2 /* utility.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6E1788D548002F0ED2 /* utility.h */; }; + FA5FDC861788D548002F0ED2 /* win32.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6F1788D548002F0ED2 /* win32.h */; }; + FA5FDC881788D548002F0ED2 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC711788D548002F0ED2 /* list.c */; }; + FA5FDC891788D548002F0ED2 /* packet.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC721788D548002F0ED2 /* packet.c */; }; + FA5FDC8A1788D548002F0ED2 /* peer.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC731788D548002F0ED2 /* peer.c */; }; + FA5FDC8B1788D548002F0ED2 /* protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC741788D548002F0ED2 /* protocol.c */; }; + FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC761788D548002F0ED2 /* unix.c */; }; + FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC771788D548002F0ED2 /* win32.c */; }; + FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC781788D548002F0ED2 /* lua-enet.h */; }; + FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D88171B70920065623F /* RandomGenerator.cpp */; }; + FA636D8B171B70920065623F /* RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D89171B70920065623F /* RandomGenerator.h */; }; + FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */; }; + FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */; }; + FA7175AA178E8418001FE7FE /* lua.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7175A9178E8418001FE7FE /* lua.h */; }; + FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */; }; + FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */; }; FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */; }; FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937616DCC6C2006F2BEE /* wrap_Math.h */; }; + FA9B492A1875EFB900201DA9 /* Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9B49281875EFB900201DA9 /* Texture.h */; }; + FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; }; + FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */; }; + FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9FC0AF173D6E3E005027FF /* wrap_Window.h */; }; + FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAAC6B00170A373A008A61C5 /* CompressedData.cpp */; }; + FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAC6B01170A373A008A61C5 /* CompressedData.h */; }; FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; }; + FAB0078F1740C12D00A9664D /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB0078D1740C12D00A9664D /* Joystick.cpp */; }; + FAB007901740C12D00A9664D /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB0078E1740C12D00A9664D /* Joystick.h */; }; + FAB007931740C28900A9664D /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB007911740C28900A9664D /* Joystick.cpp */; }; + FAB007941740C28900A9664D /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB007921740C28900A9664D /* Joystick.h */; }; + FAB007971740C87D00A9664D /* wrap_Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB007951740C87D00A9664D /* wrap_Joystick.cpp */; }; + FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB007961740C87D00A9664D /* wrap_Joystick.h */; }; + FAC5710017402D1100D147E4 /* BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FC17402D1100D147E4 /* BezierCurve.cpp */; }; + FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FD17402D1100D147E4 /* BezierCurve.h */; }; + FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */; }; + FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */; }; + FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E611724552C00EED715 /* wrap_Quad.cpp */; }; + FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Quad.h */; }; + FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Quad.cpp */; }; + FAC86E6C1724555D00EED715 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Quad.h */; }; + FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010D8170DDE99006F29D0 /* ddsinfo.h */; }; + FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010D9170DDE99006F29D0 /* ddsparse.cpp */; }; + FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DA170DDE99006F29D0 /* ddsparse.h */; }; + FAE010E0170DE25E006F29D0 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */; }; + FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DF170DE25E006F29D0 /* ddsHandler.h */; }; + FAE010E4170DF75C006F29D0 /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */; }; + FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */; }; + FAEC808A1710FEA60057279A /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC80881710FEA60057279A /* ImageData.cpp */; }; + FAEC808B1710FEA60057279A /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEC80891710FEA60057279A /* ImageData.h */; }; + FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC808C1711E76C0057279A /* CompressedData.cpp */; }; + FAEC808F1711E76C0057279A /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEC808D1711E76C0057279A /* CompressedData.h */; }; + FAF272A416E3D44400CC193A /* Channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729816E3D44400CC193A /* Channel.cpp */; }; + FAF272A516E3D44400CC193A /* Channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729916E3D44400CC193A /* Channel.h */; }; + FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729A16E3D44400CC193A /* LuaThread.cpp */; }; + FAF272A716E3D44400CC193A /* LuaThread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729B16E3D44400CC193A /* LuaThread.h */; }; + FAF272A816E3D44400CC193A /* ThreadModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729C16E3D44400CC193A /* ThreadModule.cpp */; }; + FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729D16E3D44400CC193A /* ThreadModule.h */; }; + FAF272AA16E3D44400CC193A /* wrap_Channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729E16E3D44400CC193A /* wrap_Channel.cpp */; }; + FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729F16E3D44400CC193A /* wrap_Channel.h */; }; + FAF272AC16E3D44400CC193A /* wrap_LuaThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272A016E3D44400CC193A /* wrap_LuaThread.cpp */; }; + FAF272AD16E3D44400CC193A /* wrap_LuaThread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272A116E3D44400CC193A /* wrap_LuaThread.h */; }; + FAF272AE16E3D44400CC193A /* wrap_ThreadModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272A216E3D44400CC193A /* wrap_ThreadModule.cpp */; }; + FAF272AF16E3D44400CC193A /* wrap_ThreadModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272A316E3D44400CC193A /* wrap_ThreadModule.h */; }; + FAF272B516E3D46400CC193A /* Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272B116E3D46400CC193A /* Thread.cpp */; }; + FAF272B616E3D46400CC193A /* Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B216E3D46400CC193A /* Thread.h */; }; + FAF272B716E3D46400CC193A /* threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272B316E3D46400CC193A /* threads.cpp */; }; + FAF272B816E3D46400CC193A /* threads.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B416E3D46400CC193A /* threads.h */; }; + FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF4376D17F4AC530074F9E2 /* Mesh.cpp */; }; + FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF4376E17F4AC530074F9E2 /* Mesh.h */; }; + FAF6704C18184FF800DBDEEA /* wuff.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704418184FF800DBDEEA /* wuff.c */; }; + FAF6704D18184FF800DBDEEA /* wuff.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704518184FF800DBDEEA /* wuff.h */; }; + FAF6704E18184FF800DBDEEA /* wuff_config.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704618184FF800DBDEEA /* wuff_config.h */; }; + FAF6704F18184FF800DBDEEA /* wuff_convert.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704718184FF800DBDEEA /* wuff_convert.c */; }; + FAF6705018184FF800DBDEEA /* wuff_convert.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704818184FF800DBDEEA /* wuff_convert.h */; }; + FAF6705118184FF800DBDEEA /* wuff_internal.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704918184FF800DBDEEA /* wuff_internal.c */; }; + FAF6705218184FF800DBDEEA /* wuff_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704A18184FF800DBDEEA /* wuff_internal.h */; }; + FAF6705318184FF800DBDEEA /* wuff_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704B18184FF800DBDEEA /* wuff_memory.c */; }; + FAF670561818501300DBDEEA /* WaveDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF670541818501300DBDEEA /* WaveDecoder.cpp */; }; + FAF670571818501300DBDEEA /* WaveDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF670551818501300DBDEEA /* WaveDecoder.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -309,11 +408,10 @@ 131F69C3368C4B8A55EE0DAD /* wrap_WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_WeldJoint.h; sourceTree = ""; }; 135801A6483528800C676492 /* io.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = ""; }; 138913BE5126483748FA43D0 /* Joint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joint.h; sourceTree = ""; }; - 139411436818381E493F00F5 /* wrap_Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Joystick.cpp; sourceTree = ""; }; + 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_JoystickModule.cpp; sourceTree = ""; }; 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = ""; }; 15093E1B1A14176374C81299 /* wrap_CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_CircleShape.h; sourceTree = ""; }; 153957EB332E1269671E7F4A /* b2CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = ""; }; - 168502C6505A6D455C4F69AA /* math.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = math.cpp; sourceTree = ""; }; 16C36B3C59A10CDC7ACE0DD4 /* http.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = http.lua.h; sourceTree = ""; }; 174D472C1AFE594D77A0322B /* b2ChainAndCircleContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2ChainAndCircleContact.h; sourceTree = ""; }; 175A1B8D733B2D4803F64AC1 /* b2Distance.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = ""; }; @@ -332,7 +430,7 @@ 1A95437F513E662113AC154A /* b2Rope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Rope.h; sourceTree = ""; }; 1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = ""; }; 1AA213FC158815FA77C40330 /* ChainShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChainShape.h; sourceTree = ""; }; - 1AA7781A230065F346E2313A /* ImageData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = ""; }; + 1AA7781A230065F346E2313A /* DevilHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DevilHandler.cpp; sourceTree = ""; }; 1B036C7C5A8832AE53BB1C06 /* b2CollideEdge.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideEdge.cpp; sourceTree = ""; }; 1B1C4E4D288A1D2F29E57B1B /* Rasterizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Rasterizer.cpp; sourceTree = ""; }; 1B4E22F1388E2B2E76E3377B /* wrap_GlyphData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_GlyphData.cpp; sourceTree = ""; }; @@ -341,9 +439,7 @@ 1CAA69E00D0808BA2108238B /* wrap_ChainShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ChainShape.cpp; sourceTree = ""; }; 1CD02D1975803957282F28AB /* auxiliar.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = auxiliar.c; sourceTree = ""; }; 1CE84F1F19BC2AA412C638B1 /* timeout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = timeout.h; sourceTree = ""; }; - 1D824A63414874DE584B59B2 /* Quad.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; - 1D9B456C6C554F66660F7650 /* Thread.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Thread.cpp; sourceTree = ""; }; - 1DA41DFF0869489411A71AFC /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; + 1DA41DFF0869489411A71AFC /* Texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; 1E22646A710E5EFC27FE3932 /* FrictionJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FrictionJoint.cpp; sourceTree = ""; }; 1E27263847302FCA1F843B47 /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = ""; }; 1E827AE8548C52493ED95629 /* wrap_Filesystem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Filesystem.cpp; sourceTree = ""; }; @@ -378,7 +474,7 @@ 27F777AB188D674F30BC1829 /* wrap_World.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_World.h; sourceTree = ""; }; 28016C9B51FE1A893DC35B66 /* Variant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Variant.h; sourceTree = ""; }; 28024635525B077E08A73D9B /* Source.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = ""; }; - 283342E174613897621A43F1 /* ImageData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = ""; }; + 283342E174613897621A43F1 /* DevilHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DevilHandler.h; sourceTree = ""; }; 286660042F9654F61AB90D7A /* Body.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Body.h; sourceTree = ""; }; 2912092853050AF9785F39BE /* wrap_RevoluteJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_RevoluteJoint.h; sourceTree = ""; }; 295C665B1E0B6B2D03CC4937 /* wrap_Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = ""; }; @@ -392,7 +488,7 @@ 2CAE75B079B828FE6892684A /* udp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = udp.h; sourceTree = ""; }; 2CEC5ED5211174C7583849AD /* Reference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Reference.h; sourceTree = ""; }; 2D290E902C451D6849051FEF /* b2WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = ""; }; - 2D7B7DEC4FC87878332E41B3 /* wrap_Joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Joystick.h; sourceTree = ""; }; + 2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_JoystickModule.h; sourceTree = ""; }; 2D8E6FAE2A100B5866E96BFF /* runtime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = runtime.h; sourceTree = ""; }; 2D9475890CDA3D3776435622 /* Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = ""; }; 2DC90F3C6160198256795C75 /* luasocket.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = luasocket.cpp; sourceTree = ""; }; @@ -406,7 +502,6 @@ 2FF26CC52C28773750B812D9 /* PolygonShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PolygonShape.h; sourceTree = ""; }; 30E466F441EE727658716873 /* Module.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Module.cpp; sourceTree = ""; }; 30ED4BB03C5F11254AF12E98 /* Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sound.cpp; sourceTree = ""; }; - 30FC314F4137398F63961338 /* wrap_Quad.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = ""; }; 31871B8B7E1A697A73576040 /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = ""; }; 31A444CF0B4E6DA450120730 /* File.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = ""; }; 31B85B507F466FE158A3718E /* wrap_ImageData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ImageData.h; sourceTree = ""; }; @@ -417,12 +512,10 @@ 32CC11481CD9164455455D72 /* b2Collision.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = ""; }; 32FD3FEE52FD1911405B3C59 /* b2BroadPhase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = ""; }; 330F59B11A5B5D1B44DC07BF /* wrap_Source.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Source.h; sourceTree = ""; }; - 3348511C3BCE65F003DA68CD /* wrap_Thread.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Thread.cpp; sourceTree = ""; }; 33627AE97E66147E76804EF9 /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = ""; }; 33FD508B0754314530A35EF3 /* StringMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StringMap.h; sourceTree = ""; }; 340345481F165F8945C716AE /* wrap_FrictionJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_FrictionJoint.cpp; sourceTree = ""; }; 343E66751EBA75264C3400FA /* b2Draw.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Draw.h; sourceTree = ""; }; - 346C3C7F62FA35DA2C9C4F69 /* DrawQable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawQable.cpp; sourceTree = ""; }; 34A36BB617BC5CCA5B870EA6 /* DistanceJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DistanceJoint.cpp; sourceTree = ""; }; 350C47C774835EA552130431 /* Object.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Object.h; sourceTree = ""; }; 3512460642B046876D687B22 /* wrap_FileData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_FileData.h; sourceTree = ""; }; @@ -454,7 +547,6 @@ 3C965422252F672D3FF6598C /* CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CircleShape.h; sourceTree = ""; }; 3CDA3E9B364F17A902384AAC /* wrap_Font.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Font.h; sourceTree = ""; }; 3CFE5C4A12D5675E7C9C7BF9 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; - 3D3B224C2F9D2359288028FD /* Quad.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; 3D8460B2486A372825213933 /* Vector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = ""; }; 3DFF31EE26405E554C610C8F /* wrap_WeldJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_WeldJoint.cpp; sourceTree = ""; }; 3EA80A4E0CE0014052076037 /* Joint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joint.cpp; sourceTree = ""; }; @@ -464,10 +556,9 @@ 40F412FF29F65F5A3D511B98 /* wrap_EdgeShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_EdgeShape.cpp; sourceTree = ""; }; 411B061C49172C971C622125 /* Object.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Object.cpp; sourceTree = ""; }; 415E1438178736BE0EA908D5 /* select.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = select.c; sourceTree = ""; }; - 4162283C11024AC35897618C /* wrap_Quad.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = ""; }; 426B1C4475DC54505B824B7F /* VertexBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VertexBuffer.cpp; sourceTree = ""; }; 427B4B2517C0516844370E3D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = ""; }; - 439E46D768A266780E894800 /* Joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = ""; }; + 439E46D768A266780E894800 /* JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JoystickModule.h; sourceTree = ""; }; 43A258C229C75C15238E520C /* Decoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Decoder.h; sourceTree = ""; }; 43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = ""; }; 448C492C7AEB7840504F1C9D /* b2EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2EdgeShape.h; sourceTree = ""; }; @@ -498,7 +589,7 @@ 4B41232F7AF7793540F46C58 /* timeout.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timeout.c; sourceTree = ""; }; 4B5F4DF8110020A96B5D3EAB /* b2BroadPhase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = ""; }; 4B731754147B27AF73AC5358 /* Volatile.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Volatile.cpp; sourceTree = ""; }; - 4C606AEC342457600C3F0741 /* Joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = ""; }; + 4C606AEC342457600C3F0741 /* JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JoystickModule.h; sourceTree = ""; }; 4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatch.cpp; sourceTree = ""; }; 4D81102E7ABD1C282BE42CE3 /* wrap_MouseJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_MouseJoint.cpp; sourceTree = ""; }; 4DAB28A9235E2CBE75F56848 /* CircleShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CircleShape.cpp; sourceTree = ""; }; @@ -525,12 +616,11 @@ 53C6151E07FB1E3471590CB9 /* ltn12.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ltn12.lua.h; sourceTree = ""; }; 53EE57FF4DBD52BB22701160 /* ParticleSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; 54A13C2209F945671BC27974 /* FileData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FileData.h; sourceTree = ""; }; - 54CC34F563B7405046FF1E43 /* audio.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = audio.lua.h; sourceTree = ""; }; 54E653E84E8873D467C750FC /* mime.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mime.lua.h; sourceTree = ""; }; 54E85987318206E93DC8189F /* PolygonShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PolygonShape.cpp; sourceTree = ""; }; 55A759CE711E157339930E58 /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = ""; }; 55AE226405CC1A55462E1D89 /* threads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = ""; }; - 55B425307C0C1C4B3EFC3A5F /* Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = ""; }; + 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JoystickModule.cpp; sourceTree = ""; }; 561D4A4722E36BAA16D17CC8 /* EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EdgeShape.h; sourceTree = ""; }; 567C0A0C58931DE54733011B /* b2StackAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = ""; }; 56D6030A0B8F7397715062B9 /* Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; @@ -540,8 +630,7 @@ 583037E9238A6EF00DD20B1A /* Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; }; 584E16AE09E12536206C46FE /* Mouse.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Mouse.cpp; sourceTree = ""; }; 58792BC1126C2917432D706B /* b2CircleContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = ""; }; - 58BA2BB460AF3C591B22690E /* Drawable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Drawable.cpp; sourceTree = ""; }; - 58CC50E70A375FDF53EF01B6 /* Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; + 58CC50E70A375FDF53EF01B6 /* Texture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Texture.cpp; sourceTree = ""; }; 58CD093F254501E37CA47CA8 /* types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; 597478A255B82B56488B4717 /* wrap_FileData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_FileData.cpp; sourceTree = ""; }; 59BE634A2ACE722F14B86F89 /* b2Island.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = ""; }; @@ -586,9 +675,7 @@ 6590063A6E4B3AEF4550443C /* b2GearJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = ""; }; 66EC3C0463A703A97445193B /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = ""; }; 66F8479E6D2D587A592F2024 /* socket.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = socket.lua.h; sourceTree = ""; }; - 677F545C76EA3B247329358D /* Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = ""; }; 678E42771C9B415628A3234D /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = ""; }; - 68317360363E2C5339396995 /* wrap_Thread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Thread.h; sourceTree = ""; }; 68616BD516DB124312B47EB3 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; 691C5C5828550E2F60754EF2 /* wrap_Event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Event.cpp; sourceTree = ""; }; 695E4ED13AA0689E64280573 /* wrap_Timer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Timer.cpp; sourceTree = ""; }; @@ -628,7 +715,6 @@ 74003CB27FA762A021183AD5 /* GlyphData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GlyphData.cpp; sourceTree = ""; }; 74215662418726B35C581E55 /* Thread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = ""; }; 7423362764CF57574BB16CDA /* Window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = ""; }; - 74504EB554D871C36DD55F17 /* Quad.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; 74EE403977734BA53DDF16F0 /* core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = core.h; sourceTree = ""; }; 753F0B42534106D6545926C8 /* Memoizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Memoizer.h; sourceTree = ""; }; 755C2B980C106EA7423E7E5E /* EdgeShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeShape.cpp; sourceTree = ""; }; @@ -655,10 +741,8 @@ 7BAB25936D207169591A666A /* wrap_GearJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_GearJoint.h; sourceTree = ""; }; 7CA02BF51EBA65C263E15250 /* unchecked.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unchecked.h; sourceTree = ""; }; 7CC5707C79175FA6427B3D62 /* Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - 7D13274605967A612D770598 /* Quad.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; 7D48236B78EA06D346A86E3F /* smtp.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = smtp.lua.h; sourceTree = ""; }; 7D9B03C2438B748D0DE93DD5 /* utf8.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = utf8.cpp; sourceTree = ""; }; - 7E1316A41EA850403C0C7343 /* DrawQable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawQable.h; sourceTree = ""; }; 7E4B280637927B532B456D5E /* Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; 7E7A068041FD553876712F05 /* b2CollideCircle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = ""; }; 7EC570BC74C369747ED0183A /* Window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = ""; }; @@ -667,15 +751,40 @@ 7F575BE9573C654B5ED44CC1 /* wrap_Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Timer.h; sourceTree = ""; }; 7F796B7A3362196075C62E61 /* wrap_Fixture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Fixture.cpp; sourceTree = ""; }; 7F911CF2107B22F44C5B2542 /* b2Collision.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = ""; }; + FA01BE1C1878E35B00640047 /* wrap_Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Texture.cpp; sourceTree = ""; }; + FA01BE1D1878E35B00640047 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = ""; }; + FA03546A1731F3A700284828 /* simplexnoise1234.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simplexnoise1234.cpp; sourceTree = ""; }; + FA03546B1731F3A700284828 /* simplexnoise1234.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simplexnoise1234.h; sourceTree = ""; }; FA08F5AE16C7525600F007B5 /* Info-Framework.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-Framework.plist"; sourceTree = ""; }; + FA0A4BEE182E0C2800E1E4D2 /* b2MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MotorJoint.cpp; sourceTree = ""; }; + FA0A4BEF182E0C2800E1E4D2 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = ""; }; + FA0A4BF2182E1AD600E1E4D2 /* MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MotorJoint.cpp; sourceTree = ""; }; + FA0A4BF3182E1AD600E1E4D2 /* MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MotorJoint.h; sourceTree = ""; }; + FA0A4BF6182E260200E1E4D2 /* wrap_MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_MotorJoint.cpp; sourceTree = ""; }; + FA0A4BF7182E260200E1E4D2 /* wrap_MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_MotorJoint.h; sourceTree = ""; }; + FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = ""; }; + FA34E7CB174B513F00E04D3F /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = ""; }; + FA34E7CC174B513F00E04D3F /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = ""; }; + FA34E7D0174B515D00E04D3F /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = ""; }; + FA34E7D1174B515D00E04D3F /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = ""; }; + FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_System.cpp; sourceTree = ""; }; + FA34E7D5174B55AF00E04D3F /* wrap_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_System.h; sourceTree = ""; }; + FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = ""; }; + FA3D9E0C16E68DE600CA6630 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = ""; }; + FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = ""; }; + FA3D9E1016E68EAE00CA6630 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = ""; }; + FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Cursor.cpp; sourceTree = ""; }; + FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Cursor.h; sourceTree = ""; }; + FA435EA117B36E9C004C3F22 /* Polyline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polyline.cpp; sourceTree = ""; }; + FA435EA217B36E9C004C3F22 /* Polyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = ""; }; + FA5454C016F1310000D30303 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = ""; }; + FA5454C116F1310000D30303 /* MathModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathModule.h; sourceTree = ""; }; FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; FA577A6916C719DE00860150 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = ""; }; - FA577A6B16C719E400860150 /* Game_Music_Emu.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Game_Music_Emu.framework; path = /Library/Frameworks/Game_Music_Emu.framework; sourceTree = ""; }; FA577A6D16C719EA00860150 /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; FA577A6F16C719F000860150 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; FA577A7116C719F400860150 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; FA577A7316C719F900860150 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = ""; }; - FA577A7516C719FF00860150 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; }; FA577A7716C71A0800860150 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; FA577A7916C71A1700860150 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; FA577A7C16C71A2600860150 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; @@ -684,16 +793,99 @@ FA577A8616C71CF000860150 /* Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = ""; }; FA577A8716C71CF000860150 /* wrap_Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Shader.cpp; sourceTree = ""; }; FA577A8816C71CF000860150 /* wrap_Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Shader.h; sourceTree = ""; }; - FA577A8B16C71D3600860150 /* audio.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = audio.lua; sourceTree = ""; }; FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = auto.lua; sourceTree = ""; }; FA577A8D16C71D3600860150 /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boot.lua; sourceTree = ""; }; FA577A8E16C71D3600860150 /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = graphics.lua; sourceTree = ""; }; FA577AAF16C7507900860150 /* love.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FA7C937316DCC6C2006F2BEE /* ModMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModMath.cpp; sourceTree = ""; }; - FA7C937416DCC6C2006F2BEE /* ModMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModMath.h; sourceTree = ""; }; + FA5FDC5F1788D548002F0ED2 /* enet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = enet.cpp; sourceTree = ""; }; + FA5FDC611788D548002F0ED2 /* callbacks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = callbacks.c; sourceTree = ""; }; + FA5FDC631788D548002F0ED2 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = ""; }; + FA5FDC641788D548002F0ED2 /* host.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = host.c; sourceTree = ""; }; + FA5FDC671788D548002F0ED2 /* callbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = callbacks.h; sourceTree = ""; }; + FA5FDC681788D548002F0ED2 /* enet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enet.h; sourceTree = ""; }; + FA5FDC691788D548002F0ED2 /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = ""; }; + FA5FDC6A1788D548002F0ED2 /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = ""; }; + FA5FDC6B1788D548002F0ED2 /* time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = ""; }; + FA5FDC6C1788D548002F0ED2 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; + FA5FDC6D1788D548002F0ED2 /* unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unix.h; sourceTree = ""; }; + FA5FDC6E1788D548002F0ED2 /* utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utility.h; sourceTree = ""; }; + FA5FDC6F1788D548002F0ED2 /* win32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = win32.h; sourceTree = ""; }; + FA5FDC711788D548002F0ED2 /* list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = list.c; sourceTree = ""; }; + FA5FDC721788D548002F0ED2 /* packet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = packet.c; sourceTree = ""; }; + FA5FDC731788D548002F0ED2 /* peer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = peer.c; sourceTree = ""; }; + FA5FDC741788D548002F0ED2 /* protocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = protocol.c; sourceTree = ""; }; + FA5FDC761788D548002F0ED2 /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = ""; }; + FA5FDC771788D548002F0ED2 /* win32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = win32.c; sourceTree = ""; }; + FA5FDC781788D548002F0ED2 /* lua-enet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lua-enet.h"; sourceTree = ""; }; + FA636D88171B70920065623F /* RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomGenerator.cpp; sourceTree = ""; }; + FA636D89171B70920065623F /* RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomGenerator.h; sourceTree = ""; }; + FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RandomGenerator.cpp; sourceTree = ""; }; + FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_RandomGenerator.h; sourceTree = ""; }; + FA7175A9178E8418001FE7FE /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua.h; sourceTree = ""; }; + FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; + FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Math.cpp; sourceTree = ""; }; FA7C937616DCC6C2006F2BEE /* wrap_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Math.h; sourceTree = ""; }; + FA9B49281875EFB900201DA9 /* Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; + FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; + FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Window.cpp; sourceTree = ""; }; + FA9FC0AF173D6E3E005027FF /* wrap_Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Window.h; sourceTree = ""; }; + FAAC6B00170A373A008A61C5 /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = ""; }; + FAAC6B01170A373A008A61C5 /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = ""; }; FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = ""; }; + FAB0078D1740C12D00A9664D /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = ""; }; + FAB0078E1740C12D00A9664D /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = ""; }; + FAB007911740C28900A9664D /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = ""; }; + FAB007921740C28900A9664D /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = ""; }; + FAB007951740C87D00A9664D /* wrap_Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Joystick.cpp; sourceTree = ""; }; + FAB007961740C87D00A9664D /* wrap_Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Joystick.h; sourceTree = ""; }; + FAC570FC17402D1100D147E4 /* BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BezierCurve.cpp; sourceTree = ""; }; + FAC570FD17402D1100D147E4 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezierCurve.h; sourceTree = ""; }; + FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_BezierCurve.cpp; sourceTree = ""; }; + FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_BezierCurve.h; sourceTree = ""; }; + FAC86E611724552C00EED715 /* wrap_Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = ""; }; + FAC86E621724552C00EED715 /* wrap_Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = ""; }; + FAC86E671724555D00EED715 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; + FAC86E681724555D00EED715 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; + FAE010D8170DDE99006F29D0 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = ""; }; + FAE010D9170DDE99006F29D0 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = ""; }; + FAE010DA170DDE99006F29D0 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = ""; }; + FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsHandler.cpp; sourceTree = ""; }; + FAE010DF170DE25E006F29D0 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = ""; }; + FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CompressedData.cpp; sourceTree = ""; }; + FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = ""; }; + FAEC80881710FEA60057279A /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = ""; }; + FAEC80891710FEA60057279A /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = ""; }; + FAEC808C1711E76C0057279A /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = ""; }; + FAEC808D1711E76C0057279A /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = ""; }; + FAF2729816E3D44400CC193A /* Channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Channel.cpp; sourceTree = ""; }; + FAF2729916E3D44400CC193A /* Channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Channel.h; sourceTree = ""; }; + FAF2729A16E3D44400CC193A /* LuaThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LuaThread.cpp; sourceTree = ""; }; + FAF2729B16E3D44400CC193A /* LuaThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LuaThread.h; sourceTree = ""; }; + FAF2729C16E3D44400CC193A /* ThreadModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadModule.cpp; sourceTree = ""; }; + FAF2729D16E3D44400CC193A /* ThreadModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadModule.h; sourceTree = ""; }; + FAF2729E16E3D44400CC193A /* wrap_Channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Channel.cpp; sourceTree = ""; }; + FAF2729F16E3D44400CC193A /* wrap_Channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Channel.h; sourceTree = ""; }; + FAF272A016E3D44400CC193A /* wrap_LuaThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_LuaThread.cpp; sourceTree = ""; }; + FAF272A116E3D44400CC193A /* wrap_LuaThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_LuaThread.h; sourceTree = ""; }; + FAF272A216E3D44400CC193A /* wrap_ThreadModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ThreadModule.cpp; sourceTree = ""; }; + FAF272A316E3D44400CC193A /* wrap_ThreadModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ThreadModule.h; sourceTree = ""; }; + FAF272B116E3D46400CC193A /* Thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Thread.cpp; sourceTree = ""; }; + FAF272B216E3D46400CC193A /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = ""; }; + FAF272B316E3D46400CC193A /* threads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = threads.cpp; sourceTree = ""; }; + FAF272B416E3D46400CC193A /* threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = ""; }; + FAF4376D17F4AC530074F9E2 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = ""; }; + FAF4376E17F4AC530074F9E2 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = ""; }; + FAF6704418184FF800DBDEEA /* wuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff.c; sourceTree = ""; }; + FAF6704518184FF800DBDEEA /* wuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff.h; sourceTree = ""; }; + FAF6704618184FF800DBDEEA /* wuff_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_config.h; sourceTree = ""; }; + FAF6704718184FF800DBDEEA /* wuff_convert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_convert.c; sourceTree = ""; }; + FAF6704818184FF800DBDEEA /* wuff_convert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_convert.h; sourceTree = ""; }; + FAF6704918184FF800DBDEEA /* wuff_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_internal.c; sourceTree = ""; }; + FAF6704A18184FF800DBDEEA /* wuff_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_internal.h; sourceTree = ""; }; + FAF6704B18184FF800DBDEEA /* wuff_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_memory.c; sourceTree = ""; }; + FAF670541818501300DBDEEA /* WaveDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaveDecoder.cpp; sourceTree = ""; }; + FAF670551818501300DBDEEA /* WaveDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveDecoder.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -701,18 +893,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */, FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */, FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */, FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */, - FA577AC316C7512F00860150 /* Game_Music_Emu.framework in Frameworks */, FA577AC416C7513200860150 /* IL.framework in Frameworks */, FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */, - FA577AC616C7513800860150 /* Lua.framework in Frameworks */, FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */, FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */, FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */, FA577ACB16C7514400860150 /* physfs.framework in Frameworks */, - FA577ACC16C7514700860150 /* SDL.framework in Frameworks */, FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -723,10 +913,14 @@ 003F4BA82B6046BC133B3F0F /* image */ = { isa = PBXGroup; children = ( + FAAC6B00170A373A008A61C5 /* CompressedData.cpp */, + FAAC6B01170A373A008A61C5 /* CompressedData.h */, 25C325DC2128769F6C6A54C3 /* Image.h */, 78115E763B723C0C40AD47CF /* ImageData.cpp */, 07B301984BE42246402F7D27 /* ImageData.h */, - 13730AB030E309FF6E2961F1 /* devil */, + 13730AB030E309FF6E2961F1 /* magpie */, + FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */, + FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */, 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */, 006B015320155B4D42B43B61 /* wrap_Image.h */, 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */, @@ -738,12 +932,22 @@ 02E0744773D13AD65E7C49DC /* thread */ = { isa = PBXGroup; children = ( - 1D9B456C6C554F66660F7650 /* Thread.cpp */, + FAF2729816E3D44400CC193A /* Channel.cpp */, + FAF2729916E3D44400CC193A /* Channel.h */, + FAF2729A16E3D44400CC193A /* LuaThread.cpp */, + FAF2729B16E3D44400CC193A /* LuaThread.h */, + FAF272B016E3D46400CC193A /* sdl */, 74215662418726B35C581E55 /* Thread.h */, + FAF2729C16E3D44400CC193A /* ThreadModule.cpp */, + FAF2729D16E3D44400CC193A /* ThreadModule.h */, 6B3565203A1778431F8A5409 /* threads.cpp */, 55AE226405CC1A55462E1D89 /* threads.h */, - 3348511C3BCE65F003DA68CD /* wrap_Thread.cpp */, - 68317360363E2C5339396995 /* wrap_Thread.h */, + FAF2729E16E3D44400CC193A /* wrap_Channel.cpp */, + FAF2729F16E3D44400CC193A /* wrap_Channel.h */, + FAF272A016E3D44400CC193A /* wrap_LuaThread.cpp */, + FAF272A116E3D44400CC193A /* wrap_LuaThread.h */, + FAF272A216E3D44400CC193A /* wrap_ThreadModule.cpp */, + FAF272A316E3D44400CC193A /* wrap_ThreadModule.h */, ); path = thread; sourceTree = ""; @@ -761,7 +965,6 @@ 3746164716797CF80D6B0CEE /* Exception.cpp */, 7A5C32955F016AB85EB55519 /* Exception.h */, 40BC14C607396F8B1B084012 /* int.h */, - 168502C6505A6D455C4F69AA /* math.cpp */, 52D130DF3DC82D9D4C867B61 /* math.h */, 0CB6025618505B055A4E75DD /* Matrix.cpp */, 085B376E3FBB254F0FD37958 /* Matrix.h */, @@ -818,9 +1021,13 @@ 130737AF4BD12D0356A65C87 /* mouse */ = { isa = PBXGroup; children = ( + FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */, + FA3D9E0C16E68DE600CA6630 /* Cursor.h */, 31E0110E5797041465FF5F95 /* Mouse.cpp */, 63A63DFB339266AC401B545A /* Mouse.h */, 1E017A8673D531394B5A3B16 /* sdl */, + FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */, + FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */, 22EF17981EBD442773FE41B6 /* wrap_Mouse.cpp */, 4E972C114A6C25A63B5B6EF2 /* wrap_Mouse.h */, ); @@ -830,6 +1037,7 @@ 1350109F709C227D4AFD423C /* libluasocket */ = { isa = PBXGroup; children = ( + FA7175A9178E8418001FE7FE /* lua.h */, 1CD02D1975803957282F28AB /* auxiliar.c */, 1F6F652A57F8098E5CCA6F9A /* auxiliar.h */, 21B25A7E333315172B754D4F /* buffer.c */, @@ -871,23 +1079,32 @@ path = libluasocket; sourceTree = ""; }; - 13730AB030E309FF6E2961F1 /* devil */ = { + 13730AB030E309FF6E2961F1 /* magpie */ = { isa = PBXGroup; children = ( + FAEC808C1711E76C0057279A /* CompressedData.cpp */, + FAEC808D1711E76C0057279A /* CompressedData.h */, + FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */, + FAE010DF170DE25E006F29D0 /* ddsHandler.h */, + 1AA7781A230065F346E2313A /* DevilHandler.cpp */, + 283342E174613897621A43F1 /* DevilHandler.h */, + FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */, 505F23A73BFE250833D650E4 /* Image.cpp */, 68616BD516DB124312B47EB3 /* Image.h */, - 1AA7781A230065F346E2313A /* ImageData.cpp */, - 283342E174613897621A43F1 /* ImageData.h */, + FAEC80881710FEA60057279A /* ImageData.cpp */, + FAEC80891710FEA60057279A /* ImageData.h */, ); - path = devil; + path = magpie; sourceTree = ""; }; 153D76205F7A4ACD12FB4C0E /* window */ = { isa = PBXGroup; children = ( + 63082CBA23A6046C60DA1C6F /* sdl */, 351B09E51FDC338622F44624 /* Window.cpp */, 7423362764CF57574BB16CDA /* Window.h */, - 63082CBA23A6046C60DA1C6F /* sdl */, + FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */, + FA9FC0AF173D6E3E005027FF /* wrap_Window.h */, ); path = window; sourceTree = ""; @@ -936,6 +1153,8 @@ 1E017A8673D531394B5A3B16 /* sdl */ = { isa = PBXGroup; children = ( + FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */, + FA3D9E1016E68EAE00CA6630 /* Cursor.h */, 584E16AE09E12536206C46FE /* Mouse.cpp */, 198A44BD71BB61EE517C2A39 /* Mouse.h */, ); @@ -995,6 +1214,8 @@ 25CE236F66F70EB3444A7CC8 /* GearJoint.h */, 3EA80A4E0CE0014052076037 /* Joint.cpp */, 138913BE5126483748FA43D0 /* Joint.h */, + FA0A4BF2182E1AD600E1E4D2 /* MotorJoint.cpp */, + FA0A4BF3182E1AD600E1E4D2 /* MotorJoint.h */, 3C0B06AF6B5326C840477B18 /* MouseJoint.cpp */, 208275724C9421035EA145A4 /* MouseJoint.h */, 370D76DC224F2EB300CB4E2F /* Physics.cpp */, @@ -1037,6 +1258,8 @@ 7BAB25936D207169591A666A /* wrap_GearJoint.h */, 71810207414B52F8340D7797 /* wrap_Joint.cpp */, 047815B73C1C5373551442A6 /* wrap_Joint.h */, + FA0A4BF6182E260200E1E4D2 /* wrap_MotorJoint.cpp */, + FA0A4BF7182E260200E1E4D2 /* wrap_MotorJoint.h */, 4D81102E7ABD1C282BE42CE3 /* wrap_MouseJoint.cpp */, 64BA1CE328FF17144B475111 /* wrap_MouseJoint.h */, 6CEB48E969FC42C53F9432B1 /* wrap_Physics.cpp */, @@ -1066,8 +1289,6 @@ 352E6C5F6F8A681766EB5299 /* scripts */ = { isa = PBXGroup; children = ( - FA577A8B16C71D3600860150 /* audio.lua */, - 54CC34F563B7405046FF1E43 /* audio.lua.h */, FA577A8C16C71D3600860150 /* auto.lua */, FA577A8D16C71D3600860150 /* boot.lua */, 503971A86B7167A91B670FBA /* boot.lua.h */, @@ -1152,6 +1373,8 @@ 77234CEE2EFE633537975850 /* Sound.h */, 727648E06CD863A2582F798F /* VorbisDecoder.cpp */, 4A80315175C5625804AA4A56 /* VorbisDecoder.h */, + FAF670541818501300DBDEEA /* WaveDecoder.cpp */, + FAF670551818501300DBDEEA /* WaveDecoder.h */, ); path = lullaby; sourceTree = ""; @@ -1160,8 +1383,12 @@ isa = PBXGroup; children = ( 63287ED84D0F2EEB65D249A3 /* Box2D */, + FAE010D7170DDE99006F29D0 /* ddsparse */, + FA5FDC5E1788D548002F0ED2 /* enet */, 3AED1DE005A53DDB07902760 /* luasocket */, + FA0354691731F3A700284828 /* noise1234 */, 36C14C81334735EC54E33637 /* utf8 */, + FAF6704318184FF800DBDEEA /* Wuff */, ); name = libraries; path = ../../src/libraries; @@ -1171,11 +1398,11 @@ isa = PBXGroup; children = ( 43A258C229C75C15238E520C /* Decoder.h */, + 47217E6729AC72E74FF651E3 /* lullaby */, 30ED4BB03C5F11254AF12E98 /* Sound.cpp */, 23985AB32E7B463A2CB87E2C /* Sound.h */, 0C5C6C6E47851D1308411DE6 /* SoundData.cpp */, 785D31764A1D6CDE21BC6404 /* SoundData.h */, - 47217E6729AC72E74FF651E3 /* lullaby */, 5CF629B94C7802D446D61C45 /* wrap_Decoder.cpp */, 782A153A1E6314CB583250E0 /* wrap_Decoder.h */, 385902BD584E7D73154E4EBB /* wrap_Sound.cpp */, @@ -1199,8 +1426,9 @@ 501126AD67DC2A4B527654EA /* joystick */ = { isa = PBXGroup; children = ( - 677F545C76EA3B247329358D /* Joystick.cpp */, - 4C606AEC342457600C3F0741 /* Joystick.h */, + FAB0078D1740C12D00A9664D /* Joystick.cpp */, + FAB0078E1740C12D00A9664D /* Joystick.h */, + 4C606AEC342457600C3F0741 /* JoystickModule.h */, 687216AD6FA406C838284B91 /* sdl */, ); path = joystick; @@ -1219,6 +1447,7 @@ ); name = love; sourceTree = ""; + usesTabs = 1; }; 548A533617C45319431D3ECF /* modules */ = { isa = PBXGroup; @@ -1236,6 +1465,7 @@ 130737AF4BD12D0356A65C87 /* mouse */, 67F10C1D58A96C1C53563B5C /* physics */, 4BAB08EE4A6B4A1A01DA50A4 /* sound */, + FA34E7CA174B512200E04D3F /* system */, 02E0744773D13AD65E7C49DC /* thread */, 6D590DDD41E72A60262E4A4F /* timer */, 153D76205F7A4ACD12FB4C0E /* window */, @@ -1248,17 +1478,14 @@ isa = PBXGroup; children = ( 4941079838020ECA049B5C21 /* Color.h */, - 58BA2BB460AF3C591B22690E /* Drawable.cpp */, 5D93601669875EE06721689E /* Drawable.h */, - 346C3C7F62FA35DA2C9C4F69 /* DrawQable.cpp */, - 7E1316A41EA850403C0C7343 /* DrawQable.h */, 03F17FF546D637744E263961 /* Graphics.cpp */, 777352284E262F48543E6E7F /* Graphics.h */, - 58CC50E70A375FDF53EF01B6 /* Image.cpp */, - 1DA41DFF0869489411A71AFC /* Image.h */, 75093EE94918576801F50993 /* opengl */, - 3D3B224C2F9D2359288028FD /* Quad.cpp */, - 7D13274605967A612D770598 /* Quad.h */, + FAC86E671724555D00EED715 /* Quad.cpp */, + FAC86E681724555D00EED715 /* Quad.h */, + 58CC50E70A375FDF53EF01B6 /* Texture.cpp */, + 1DA41DFF0869489411A71AFC /* Texture.h */, 4B731754147B27AF73AC5358 /* Volatile.cpp */, 0CFF64090F0F4F481BB80CF0 /* Volatile.h */, ); @@ -1356,6 +1583,8 @@ 6590063A6E4B3AEF4550443C /* b2GearJoint.h */, 6F1B61350B6B36AF216C57D7 /* b2Joint.cpp */, 10F83B5848B77A937C250FEB /* b2Joint.h */, + FA0A4BEE182E0C2800E1E4D2 /* b2MotorJoint.cpp */, + FA0A4BEF182E0C2800E1E4D2 /* b2MotorJoint.h */, 4A47384208BE218F688C4EFA /* b2MouseJoint.cpp */, 0AA1539E66B2641B66130709 /* b2MouseJoint.h */, 1E27263847302FCA1F843B47 /* b2PrismaticJoint.cpp */, @@ -1377,10 +1606,14 @@ 687216AD6FA406C838284B91 /* sdl */ = { isa = PBXGroup; children = ( - 55B425307C0C1C4B3EFC3A5F /* Joystick.cpp */, - 439E46D768A266780E894800 /* Joystick.h */, - 139411436818381E493F00F5 /* wrap_Joystick.cpp */, - 2D7B7DEC4FC87878332E41B3 /* wrap_Joystick.h */, + FAB007911740C28900A9664D /* Joystick.cpp */, + FAB007921740C28900A9664D /* Joystick.h */, + 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */, + 439E46D768A266780E894800 /* JoystickModule.h */, + FAB007951740C87D00A9664D /* wrap_Joystick.cpp */, + FAB007961740C87D00A9664D /* wrap_Joystick.h */, + 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */, + 2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */, ); path = sdl; sourceTree = ""; @@ -1388,8 +1621,8 @@ 6D590DDD41E72A60262E4A4F /* timer */ = { isa = PBXGroup; children = ( - 2D9475890CDA3D3776435622 /* Timer.h */, 5CFF12567FFB5C5166631693 /* sdl */, + 2D9475890CDA3D3776435622 /* Timer.h */, 695E4ED13AA0689E64280573 /* wrap_Timer.cpp */, 7F575BE9573C654B5ED44CC1 /* wrap_Timer.h */, ); @@ -1438,16 +1671,19 @@ 389E3CEC356050A27784290E /* Graphics.h */, 56D6030A0B8F7397715062B9 /* Image.cpp */, 3CFE5C4A12D5675E7C9C7BF9 /* Image.h */, + FAF4376D17F4AC530074F9E2 /* Mesh.cpp */, + FAF4376E17F4AC530074F9E2 /* Mesh.h */, 2E406F8328543EC63EB922C6 /* OpenGL.cpp */, 2C87695707B046B536F347D8 /* OpenGL.h */, 48A206C9004150640C432100 /* ParticleSystem.cpp */, 53EE57FF4DBD52BB22701160 /* ParticleSystem.h */, - 74504EB554D871C36DD55F17 /* Quad.cpp */, - 1D824A63414874DE584B59B2 /* Quad.h */, + FA435EA117B36E9C004C3F22 /* Polyline.cpp */, + FA435EA217B36E9C004C3F22 /* Polyline.h */, FA577A8516C71CF000860150 /* Shader.cpp */, FA577A8616C71CF000860150 /* Shader.h */, 4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */, 727D23FA1CC755B902471A45 /* SpriteBatch.h */, + FA9B49281875EFB900201DA9 /* Texture.h */, 426B1C4475DC54505B824B7F /* VertexBuffer.cpp */, 577B66502A5360AE60733B10 /* VertexBuffer.h */, 4E3251027026699A1D4D310D /* wrap_Canvas.cpp */, @@ -1458,14 +1694,18 @@ 05DF237B657042515F3B4E52 /* wrap_Graphics.h */, 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */, 78A2127828793F7A778D7932 /* wrap_Image.h */, + FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */, + FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */, 5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */, 678E42771C9B415628A3234D /* wrap_ParticleSystem.h */, - 4162283C11024AC35897618C /* wrap_Quad.cpp */, - 30FC314F4137398F63961338 /* wrap_Quad.h */, + FAC86E611724552C00EED715 /* wrap_Quad.cpp */, + FAC86E621724552C00EED715 /* wrap_Quad.h */, FA577A8716C71CF000860150 /* wrap_Shader.cpp */, FA577A8816C71CF000860150 /* wrap_Shader.h */, 02C16FDB537A702F4D42534E /* wrap_SpriteBatch.cpp */, 2BE75A693BE206B22DAE1B2E /* wrap_SpriteBatch.h */, + FA01BE1C1878E35B00640047 /* wrap_Texture.cpp */, + FA01BE1D1878E35B00640047 /* wrap_Texture.h */, ); path = opengl; sourceTree = ""; @@ -1546,6 +1786,15 @@ path = Contacts; sourceTree = ""; }; + FA0354691731F3A700284828 /* noise1234 */ = { + isa = PBXGroup; + children = ( + FA03546A1731F3A700284828 /* simplexnoise1234.cpp */, + FA03546B1731F3A700284828 /* simplexnoise1234.h */, + ); + path = noise1234; + sourceTree = ""; + }; FA08F5AC16C751BA00F007B5 /* Resources */ = { isa = PBXGroup; children = ( @@ -1554,12 +1803,33 @@ name = Resources; sourceTree = ""; }; + FA34E7CA174B512200E04D3F /* system */ = { + isa = PBXGroup; + children = ( + FA34E7CF174B514F00E04D3F /* sdl */, + FA34E7CB174B513F00E04D3F /* System.cpp */, + FA34E7CC174B513F00E04D3F /* System.h */, + FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */, + FA34E7D5174B55AF00E04D3F /* wrap_System.h */, + ); + path = system; + sourceTree = ""; + }; + FA34E7CF174B514F00E04D3F /* sdl */ = { + isa = PBXGroup; + children = ( + FA34E7D0174B515D00E04D3F /* System.cpp */, + FA34E7D1174B515D00E04D3F /* System.h */, + ); + path = sdl; + sourceTree = ""; + }; FA577A6616C7199700860150 /* Frameworks */ = { isa = PBXGroup; children = ( + FA9B4A0716E1578300074F42 /* SDL2.framework */, FA577A7916C71A1700860150 /* Cocoa.framework */, FA577A6716C719D900860150 /* FreeType.framework */, - FA577A6B16C719E400860150 /* Game_Music_Emu.framework */, FA577A6916C719DE00860150 /* IL.framework */, FA577A8216C71A5300860150 /* libmodplug.framework */, FA577A6D16C719EA00860150 /* Lua.framework */, @@ -1568,23 +1838,117 @@ FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */, FA577A7C16C71A2600860150 /* OpenGL.framework */, FA577A7316C719F900860150 /* physfs.framework */, - FA577A7516C719FF00860150 /* SDL.framework */, FA577A7716C71A0800860150 /* Vorbis.framework */, ); name = Frameworks; sourceTree = ""; }; + FA5FDC5E1788D548002F0ED2 /* enet */ = { + isa = PBXGroup; + children = ( + FA5FDC5F1788D548002F0ED2 /* enet.cpp */, + FA5FDC601788D548002F0ED2 /* libenet */, + FA5FDC781788D548002F0ED2 /* lua-enet.h */, + ); + path = enet; + sourceTree = ""; + }; + FA5FDC601788D548002F0ED2 /* libenet */ = { + isa = PBXGroup; + children = ( + FA5FDC611788D548002F0ED2 /* callbacks.c */, + FA5FDC631788D548002F0ED2 /* compress.c */, + FA5FDC641788D548002F0ED2 /* host.c */, + FA5FDC651788D548002F0ED2 /* include */, + FA5FDC711788D548002F0ED2 /* list.c */, + FA5FDC721788D548002F0ED2 /* packet.c */, + FA5FDC731788D548002F0ED2 /* peer.c */, + FA5FDC741788D548002F0ED2 /* protocol.c */, + FA5FDC761788D548002F0ED2 /* unix.c */, + FA5FDC771788D548002F0ED2 /* win32.c */, + ); + path = libenet; + sourceTree = ""; + }; + FA5FDC651788D548002F0ED2 /* include */ = { + isa = PBXGroup; + children = ( + FA5FDC661788D548002F0ED2 /* enet */, + ); + path = include; + sourceTree = ""; + }; + FA5FDC661788D548002F0ED2 /* enet */ = { + isa = PBXGroup; + children = ( + FA5FDC671788D548002F0ED2 /* callbacks.h */, + FA5FDC681788D548002F0ED2 /* enet.h */, + FA5FDC691788D548002F0ED2 /* list.h */, + FA5FDC6A1788D548002F0ED2 /* protocol.h */, + FA5FDC6B1788D548002F0ED2 /* time.h */, + FA5FDC6C1788D548002F0ED2 /* types.h */, + FA5FDC6D1788D548002F0ED2 /* unix.h */, + FA5FDC6E1788D548002F0ED2 /* utility.h */, + FA5FDC6F1788D548002F0ED2 /* win32.h */, + ); + path = enet; + sourceTree = ""; + }; FA7C937116DCC6C2006F2BEE /* math */ = { isa = PBXGroup; children = ( - FA7C937316DCC6C2006F2BEE /* ModMath.cpp */, - FA7C937416DCC6C2006F2BEE /* ModMath.h */, + FAC570FC17402D1100D147E4 /* BezierCurve.cpp */, + FAC570FD17402D1100D147E4 /* BezierCurve.h */, + FA5454C016F1310000D30303 /* MathModule.cpp */, + FA5454C116F1310000D30303 /* MathModule.h */, + FA636D88171B70920065623F /* RandomGenerator.cpp */, + FA636D89171B70920065623F /* RandomGenerator.h */, + FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */, + FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */, FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */, FA7C937616DCC6C2006F2BEE /* wrap_Math.h */, + FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */, + FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */, ); path = math; sourceTree = ""; }; + FAE010D7170DDE99006F29D0 /* ddsparse */ = { + isa = PBXGroup; + children = ( + FAE010D8170DDE99006F29D0 /* ddsinfo.h */, + FAE010D9170DDE99006F29D0 /* ddsparse.cpp */, + FAE010DA170DDE99006F29D0 /* ddsparse.h */, + ); + path = ddsparse; + sourceTree = ""; + }; + FAF272B016E3D46400CC193A /* sdl */ = { + isa = PBXGroup; + children = ( + FAF272B116E3D46400CC193A /* Thread.cpp */, + FAF272B216E3D46400CC193A /* Thread.h */, + FAF272B316E3D46400CC193A /* threads.cpp */, + FAF272B416E3D46400CC193A /* threads.h */, + ); + path = sdl; + sourceTree = ""; + }; + FAF6704318184FF800DBDEEA /* Wuff */ = { + isa = PBXGroup; + children = ( + FAF6704418184FF800DBDEEA /* wuff.c */, + FAF6704518184FF800DBDEEA /* wuff.h */, + FAF6704618184FF800DBDEEA /* wuff_config.h */, + FAF6704718184FF800DBDEEA /* wuff_convert.c */, + FAF6704818184FF800DBDEEA /* wuff_convert.h */, + FAF6704918184FF800DBDEEA /* wuff_internal.c */, + FAF6704A18184FF800DBDEEA /* wuff_internal.h */, + FAF6704B18184FF800DBDEEA /* wuff_memory.c */, + ); + path = Wuff; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1592,8 +1956,65 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - FA7C937916DCC6C2006F2BEE /* ModMath.h in Headers */, FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */, + FAF272A516E3D44400CC193A /* Channel.h in Headers */, + FAF272A716E3D44400CC193A /* LuaThread.h in Headers */, + FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */, + FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */, + FAF6705018184FF800DBDEEA /* wuff_convert.h in Headers */, + FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */, + FA0A4BF9182E260200E1E4D2 /* wrap_MotorJoint.h in Headers */, + FAF272AD16E3D44400CC193A /* wrap_LuaThread.h in Headers */, + FAF272AF16E3D44400CC193A /* wrap_ThreadModule.h in Headers */, + FAF272B616E3D46400CC193A /* Thread.h in Headers */, + FAF272B816E3D46400CC193A /* threads.h in Headers */, + FA5454C316F1310000D30303 /* MathModule.h in Headers */, + FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */, + FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */, + FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */, + FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */, + FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */, + FAF6704E18184FF800DBDEEA /* wuff_config.h in Headers */, + FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */, + FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */, + FA01BE1F1878E35B00640047 /* wrap_Texture.h in Headers */, + FAEC808B1710FEA60057279A /* ImageData.h in Headers */, + FAEC808F1711E76C0057279A /* CompressedData.h in Headers */, + FA636D8B171B70920065623F /* RandomGenerator.h in Headers */, + FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */, + FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */, + FAC86E6C1724555D00EED715 /* Quad.h in Headers */, + FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */, + FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */, + FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */, + FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */, + FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */, + FAB007901740C12D00A9664D /* Joystick.h in Headers */, + FAF6705218184FF800DBDEEA /* wuff_internal.h in Headers */, + FAB007941740C28900A9664D /* Joystick.h in Headers */, + FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */, + FA9B492A1875EFB900201DA9 /* Texture.h in Headers */, + FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */, + FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */, + FA5FDC7E1788D548002F0ED2 /* callbacks.h in Headers */, + FA5FDC7F1788D548002F0ED2 /* enet.h in Headers */, + FA5FDC801788D548002F0ED2 /* list.h in Headers */, + FA5FDC811788D548002F0ED2 /* protocol.h in Headers */, + FA5FDC821788D548002F0ED2 /* time.h in Headers */, + FA5FDC831788D548002F0ED2 /* types.h in Headers */, + FA0A4BF5182E1AD600E1E4D2 /* MotorJoint.h in Headers */, + FA5FDC841788D548002F0ED2 /* unix.h in Headers */, + FA0A4BF1182E0C2800E1E4D2 /* b2MotorJoint.h in Headers */, + FA5FDC851788D548002F0ED2 /* utility.h in Headers */, + FAF6704D18184FF800DBDEEA /* wuff.h in Headers */, + FA5FDC861788D548002F0ED2 /* win32.h in Headers */, + FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */, + FA7175AA178E8418001FE7FE /* lua.h in Headers */, + FA34E7CE174B513F00E04D3F /* System.h in Headers */, + FA34E7D3174B515D00E04D3F /* System.h in Headers */, + FAF670571818501300DBDEEA /* WaveDecoder.h in Headers */, + FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */, + FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1624,7 +2045,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0500; }; buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "love-framework" */; compatibilityVersion = "Xcode 3.2"; @@ -1663,17 +2084,18 @@ FA08F5B316C752FC00F007B5 /* Audio.cpp in Sources */, FA08F5B416C7530100F007B5 /* Audio.cpp in Sources */, FA08F5B516C7530100F007B5 /* Source.cpp in Sources */, + FAF6705118184FF800DBDEEA /* wuff_internal.c in Sources */, FA08F5B616C7530A00F007B5 /* Audio.cpp in Sources */, FA08F5B716C7530A00F007B5 /* Pool.cpp in Sources */, FA08F5B816C7530A00F007B5 /* Source.cpp in Sources */, FA08F5B916C7532A00F007B5 /* b64.cpp in Sources */, FA08F5BA16C7532A00F007B5 /* delay.cpp in Sources */, FA08F5BB16C7532A00F007B5 /* Exception.cpp in Sources */, - FA08F5BC16C7532A00F007B5 /* math.cpp in Sources */, FA08F5BD16C7532A00F007B5 /* Matrix.cpp in Sources */, FA08F5BE16C7532A00F007B5 /* Memoizer.cpp in Sources */, FA08F5BF16C7532A00F007B5 /* Module.cpp in Sources */, FA08F5C016C7532A00F007B5 /* Object.cpp in Sources */, + FAF670561818501300DBDEEA /* WaveDecoder.cpp in Sources */, FA08F5C116C7532A00F007B5 /* Reference.cpp in Sources */, FA08F5C216C7532A00F007B5 /* runtime.cpp in Sources */, FA08F5C316C7532A00F007B5 /* utf8.cpp in Sources */, @@ -1694,6 +2116,7 @@ FA08F5D216C7534400F007B5 /* b2PolygonShape.cpp in Sources */, FA08F5D316C7535000F007B5 /* b2BlockAllocator.cpp in Sources */, FA08F5D416C7535000F007B5 /* b2Draw.cpp in Sources */, + FA0A4BF4182E1AD600E1E4D2 /* MotorJoint.cpp in Sources */, FA08F5D516C7535000F007B5 /* b2Math.cpp in Sources */, FA08F5D616C7535000F007B5 /* b2Settings.cpp in Sources */, FA08F5D716C7535000F007B5 /* b2StackAllocator.cpp in Sources */, @@ -1719,6 +2142,7 @@ FA08F5EB16C7538F00F007B5 /* b2Joint.cpp in Sources */, FA08F5EC16C7538F00F007B5 /* b2MouseJoint.cpp in Sources */, FA08F5ED16C7538F00F007B5 /* b2PrismaticJoint.cpp in Sources */, + FAF6705318184FF800DBDEEA /* wuff_memory.c in Sources */, FA08F5EE16C7538F00F007B5 /* b2PulleyJoint.cpp in Sources */, FA08F5EF16C7538F00F007B5 /* b2RevoluteJoint.cpp in Sources */, FA08F5F016C7538F00F007B5 /* b2RopeJoint.cpp in Sources */, @@ -1728,6 +2152,7 @@ FA08F5F416C753A400F007B5 /* luasocket.cpp in Sources */, FA08F5F516C753B800F007B5 /* auxiliar.c in Sources */, FA08F5F616C753B800F007B5 /* buffer.c in Sources */, + FAF6704F18184FF800DBDEEA /* wuff_convert.c in Sources */, FA08F5F716C753B800F007B5 /* except.c in Sources */, FA08F5F816C753B800F007B5 /* inet.c in Sources */, FA08F5F916C753B800F007B5 /* io.c in Sources */, @@ -1758,20 +2183,17 @@ FA08F61216C753E700F007B5 /* Rasterizer.cpp in Sources */, FA08F61316C753E700F007B5 /* wrap_GlyphData.cpp in Sources */, FA08F61416C753E700F007B5 /* wrap_Rasterizer.cpp in Sources */, - FA08F61516C753F600F007B5 /* Drawable.cpp in Sources */, - FA08F61616C753F600F007B5 /* DrawQable.cpp in Sources */, FA08F61716C753F600F007B5 /* Graphics.cpp in Sources */, - FA08F61816C753F600F007B5 /* Image.cpp in Sources */, - FA08F61916C753F600F007B5 /* Quad.cpp in Sources */, + FA08F61816C753F600F007B5 /* Texture.cpp in Sources */, FA08F61A16C753F600F007B5 /* Volatile.cpp in Sources */, FA08F61B16C7541400F007B5 /* Canvas.cpp in Sources */, FA08F61C16C7541400F007B5 /* Font.cpp in Sources */, FA08F61D16C7541400F007B5 /* GLee.c in Sources */, FA08F61E16C7541400F007B5 /* Graphics.cpp in Sources */, + FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */, FA08F61F16C7541400F007B5 /* Image.cpp in Sources */, FA08F62016C7541400F007B5 /* OpenGL.cpp in Sources */, FA08F62116C7541400F007B5 /* ParticleSystem.cpp in Sources */, - FA08F62216C7541400F007B5 /* Quad.cpp in Sources */, FA08F62316C7541400F007B5 /* Shader.cpp in Sources */, FA08F62416C7541400F007B5 /* SpriteBatch.cpp in Sources */, FA08F62516C7541400F007B5 /* VertexBuffer.cpp in Sources */, @@ -1780,17 +2202,17 @@ FA08F62816C7541400F007B5 /* wrap_Graphics.cpp in Sources */, FA08F62916C7541400F007B5 /* wrap_Image.cpp in Sources */, FA08F62A16C7541400F007B5 /* wrap_ParticleSystem.cpp in Sources */, - FA08F62B16C7541400F007B5 /* wrap_Quad.cpp in Sources */, FA08F62C16C7541400F007B5 /* wrap_Shader.cpp in Sources */, + FA0A4BFA182E26F500E1E4D2 /* wrap_MotorJoint.cpp in Sources */, FA08F62D16C7541400F007B5 /* wrap_SpriteBatch.cpp in Sources */, FA08F62E16C7542600F007B5 /* ImageData.cpp in Sources */, FA08F62F16C7542600F007B5 /* Image.cpp in Sources */, - FA08F63016C7542600F007B5 /* ImageData.cpp in Sources */, + FA08F63016C7542600F007B5 /* DevilHandler.cpp in Sources */, FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */, FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */, - FA08F63316C7542D00F007B5 /* Joystick.cpp in Sources */, - FA08F63416C7542D00F007B5 /* Joystick.cpp in Sources */, - FA08F63516C7542D00F007B5 /* wrap_Joystick.cpp in Sources */, + FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */, + FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */, + FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */, FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */, FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */, FA08F63816C7543400F007B5 /* wrap_Keyboard.cpp in Sources */, @@ -1820,6 +2242,7 @@ FA08F65016C7546400F007B5 /* RopeJoint.cpp in Sources */, FA08F65116C7546400F007B5 /* Shape.cpp in Sources */, FA08F65216C7547300F007B5 /* WeldJoint.cpp in Sources */, + FAF6704C18184FF800DBDEEA /* wuff.c in Sources */, FA08F65316C7547300F007B5 /* WheelJoint.cpp in Sources */, FA08F65416C7547300F007B5 /* World.cpp in Sources */, FA08F65516C7547300F007B5 /* wrap_Body.cpp in Sources */, @@ -1855,15 +2278,57 @@ FA08F67316C754A100F007B5 /* Mpg123Decoder.cpp in Sources */, FA08F67416C754A100F007B5 /* Sound.cpp in Sources */, FA08F67516C754A100F007B5 /* VorbisDecoder.cpp in Sources */, - FA08F67616C754A900F007B5 /* Thread.cpp in Sources */, FA08F67716C754A900F007B5 /* threads.cpp in Sources */, - FA08F67816C754A900F007B5 /* wrap_Thread.cpp in Sources */, FA08F67916C754B100F007B5 /* Timer.cpp in Sources */, FA08F67A16C754B100F007B5 /* wrap_Timer.cpp in Sources */, FA08F67B16C754BA00F007B5 /* Window.cpp in Sources */, FA08F67C16C754BA00F007B5 /* Window.cpp in Sources */, - FA7C937816DCC6C2006F2BEE /* ModMath.cpp in Sources */, FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */, + FAF272A416E3D44400CC193A /* Channel.cpp in Sources */, + FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */, + FA0A4BF0182E0C2800E1E4D2 /* b2MotorJoint.cpp in Sources */, + FAF272A816E3D44400CC193A /* ThreadModule.cpp in Sources */, + FA01BE1E1878E35B00640047 /* wrap_Texture.cpp in Sources */, + FAF272AA16E3D44400CC193A /* wrap_Channel.cpp in Sources */, + FAF272AC16E3D44400CC193A /* wrap_LuaThread.cpp in Sources */, + FAF272AE16E3D44400CC193A /* wrap_ThreadModule.cpp in Sources */, + FAF272B516E3D46400CC193A /* Thread.cpp in Sources */, + FAF272B716E3D46400CC193A /* threads.cpp in Sources */, + FA5454C216F1310000D30303 /* MathModule.cpp in Sources */, + FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */, + FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */, + FAE010E0170DE25E006F29D0 /* ddsHandler.cpp in Sources */, + FAE010E4170DF75C006F29D0 /* wrap_CompressedData.cpp in Sources */, + FAEC808A1710FEA60057279A /* ImageData.cpp in Sources */, + FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */, + FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */, + FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */, + FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */, + FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */, + FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */, + FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */, + FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */, + FA3D9E1516E6D41100CA6630 /* wrap_Cursor.cpp in Sources */, + FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */, + FAB0078F1740C12D00A9664D /* Joystick.cpp in Sources */, + FAB007931740C28900A9664D /* Joystick.cpp in Sources */, + FAB007971740C87D00A9664D /* wrap_Joystick.cpp in Sources */, + FAC5710017402D1100D147E4 /* BezierCurve.cpp in Sources */, + FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */, + FA5FDC791788D548002F0ED2 /* enet.cpp in Sources */, + FA5FDC7A1788D548002F0ED2 /* callbacks.c in Sources */, + FA5FDC7C1788D548002F0ED2 /* compress.c in Sources */, + FA5FDC7D1788D548002F0ED2 /* host.c in Sources */, + FA5FDC881788D548002F0ED2 /* list.c in Sources */, + FA5FDC891788D548002F0ED2 /* packet.c in Sources */, + FA5FDC8A1788D548002F0ED2 /* peer.c in Sources */, + FA5FDC8B1788D548002F0ED2 /* protocol.c in Sources */, + FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */, + FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */, + FA34E7CD174B513F00E04D3F /* System.cpp in Sources */, + FA34E7D2174B515D00E04D3F /* System.cpp in Sources */, + FA1EF7C41799FEAC00FF380C /* wrap_System.cpp in Sources */, + FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1873,25 +2338,35 @@ 10D5479E63C26BB35EB5482E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_ENABLE_MODULES = YES; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_OPTIMIZATION_LEVEL = s; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../src\"", "\"$(SRCROOT)/../../src/libraries\"", "\"$(SRCROOT)/../../src/modules\"", + "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", /Library/Frameworks/FreeType.framework/Headers, /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL2.framework/Headers, ); + LD_RUNPATH_SEARCH_PATHS = "@rpath"; LIBRARY_SEARCH_PATHS = ""; - LLVM_LTO = NO; - MACOSX_DEPLOYMENT_TARGET = 10.5; + MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = NO; + USE_HEADERMAP = NO; WARNING_CFLAGS = "-Wall"; }; name = Release; @@ -1899,24 +2374,35 @@ 64274E785071353E1A1D0D4B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_ENABLE_MODULES = YES; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; GCC_OPTIMIZATION_LEVEL = 0; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../src\"", "\"$(SRCROOT)/../../src/libraries\"", "\"$(SRCROOT)/../../src/modules\"", + "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", /Library/Frameworks/FreeType.framework/Headers, /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL2.framework/Headers, ); + LD_RUNPATH_SEARCH_PATHS = "@rpath"; LIBRARY_SEARCH_PATHS = ""; - MACOSX_DEPLOYMENT_TARGET = 10.5; + MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; + USE_HEADERMAP = NO; WARNING_CFLAGS = "-Wall"; }; name = Debug; @@ -1925,8 +2411,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - DYLIB_COMPATIBILITY_VERSION = 0.8.0; - DYLIB_CURRENT_VERSION = 0.8.0; + CLANG_ENABLE_MODULES = NO; + COMBINE_HIDPI_IMAGES = YES; + DYLIB_COMPATIBILITY_VERSION = 9.0; + DYLIB_CURRENT_VERSION = 9.0; FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1935,7 +2423,10 @@ ); INFOPLIST_FILE = "Info-Framework.plist"; LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)"; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + OTHER_LDFLAGS = ( + "-undefined", + dynamic_lookup, + ); PRODUCT_NAME = love; SKIP_INSTALL = YES; WRAPPER_EXTENSION = framework; @@ -1946,14 +2437,19 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = NO; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_COMPATIBILITY_VERSION = 0.8.0; - DYLIB_CURRENT_VERSION = 0.8.0; + DYLIB_COMPATIBILITY_VERSION = 9.0; + DYLIB_CURRENT_VERSION = 9.0; FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; INFOPLIST_FILE = "Info-Framework.plist"; LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)"; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + OTHER_LDFLAGS = ( + "-undefined", + dynamic_lookup, + ); PRODUCT_NAME = love; SKIP_INSTALL = YES; WRAPPER_EXTENSION = framework; diff --git a/platform/macosx/love.xcodeproj/project.pbxproj b/platform/macosx/love.xcodeproj/project.pbxproj index 305627afd..9c4739788 100644 --- a/platform/macosx/love.xcodeproj/project.pbxproj +++ b/platform/macosx/love.xcodeproj/project.pbxproj @@ -8,16 +8,11 @@ /* Begin PBXBuildFile section */ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.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 */; }; - A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; }; A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; }; - A9255DEC1043188D00BA1496 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; }; A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255E021043195A00BA1496 /* Vorbis.framework */; }; A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F421043240F00BA1496 /* IL.framework */; }; A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F51104324D700BA1496 /* Ogg.framework */; }; - A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4710420B4A007D418B /* OpenGL.framework */; }; - A93E6E5410420B57007D418B /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; }; A93E6E5510420B57007D418B /* Lua.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; }; A93E6EED10420BA8007D418B /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A3410420AC0007D418B /* love.cpp */; }; A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; }; @@ -27,7 +22,10 @@ A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; }; FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; + FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; }; + FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; }; FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */; }; + FAC8E8D416F3C468004DADF3 /* OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAC8E8D316F3C468004DADF3 /* OSX.mm */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -48,6 +46,7 @@ dstSubfolderSpec = 10; files = ( FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */, + FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */, FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */, A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */, A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */, @@ -56,9 +55,7 @@ A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */, A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */, A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */, - A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */, A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */, - A911D3C915DFF25D005B7EB8 /* Game_Music_Emu.framework in Copy Frameworks */, ); name = "Copy Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -68,19 +65,14 @@ /* Begin PBXFileReference section */ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 8D1107320486CEB800E47090 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; }; - A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Game_Music_Emu.framework; path = /Library/Frameworks/Game_Music_Emu.framework; sourceTree = ""; }; - A9255DEA1043188D00BA1496 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = ""; }; - A9255DEB1043188D00BA1496 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = ""; }; A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; A9255F421043240F00BA1496 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = ""; }; A9255F51104324D700BA1496 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; A93E6A3410420AC0007D418B /* love.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = love.cpp; path = ../../src/love.cpp; sourceTree = ""; }; A93E6E4710420B4A007D418B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; A93E6E4810420B4A007D418B /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; - A93E6E5210420B57007D418B /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; }; A93E6E5310420B57007D418B /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; A97E3842132A9EDE00198A2F /* love-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "love-Info.plist"; sourceTree = ""; }; - A9B1AE451197293000D496EB /* love_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = love_Prefix.pch; sourceTree = ""; }; A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = ""; }; A9DEC1BF1046EFA60049C70C /* Love.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Love.icns; path = icons/Love.icns; sourceTree = ""; }; A9DEC1C01046EFA70049C70C /* LoveDocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = LoveDocument.icns; path = icons/LoveDocument.icns; sourceTree = ""; }; @@ -88,7 +80,10 @@ A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FA577A9316C7217800860150 /* love-framework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "love-framework.xcodeproj"; sourceTree = ""; }; + FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = ""; }; + FAC8E8D316F3C468004DADF3 /* OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSX.mm; sourceTree = ""; }; + FAC8E8D616F3C46E004DADF3 /* OSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSX.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -98,9 +93,8 @@ files = ( FA08F69616C766E000F007B5 /* love.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */, - A93E6E5410420B57007D418B /* SDL.framework in Frameworks */, A93E6E5510420B57007D418B /* Lua.framework in Frameworks */, + FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -110,9 +104,9 @@ 1058C7A0FEA54F0111CA2CBB /* Frameworks */ = { isa = PBXGroup; children = ( + FA9B4A0916E1579F00074F42 /* SDL2.framework */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, A93E6E4810420B4A007D418B /* FreeType.framework */, - A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */, A9255F421043240F00BA1496 /* IL.framework */, A9F16926109E7BAD00FC83D1 /* libmodplug.framework */, FA08F69116C765A200F007B5 /* love.framework */, @@ -122,7 +116,6 @@ FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */, A93E6E4710420B4A007D418B /* OpenGL.framework */, A9D307E9106635C3004FEDF8 /* physfs.framework */, - A93E6E5210420B57007D418B /* SDL.framework */, A9255E021043195A00BA1496 /* Vorbis.framework */, ); name = Frameworks; @@ -171,9 +164,8 @@ isa = PBXGroup; children = ( A93E6A3410420AC0007D418B /* love.cpp */, - A9255DEA1043188D00BA1496 /* SDLMain.m */, - A9255DEB1043188D00BA1496 /* SDLMain.h */, - A9B1AE451197293000D496EB /* love_Prefix.pch */, + FAC8E8D616F3C46E004DADF3 /* OSX.h */, + FAC8E8D316F3C468004DADF3 /* OSX.mm */, ); name = Source; sourceTree = ""; @@ -206,7 +198,7 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0500; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "love" */; compatibilityVersion = "Xcode 3.2"; @@ -261,7 +253,7 @@ buildActionMask = 2147483647; files = ( A93E6EED10420BA8007D418B /* love.cpp in Sources */, - A9255DEC1043188D00BA1496 /* SDLMain.m in Sources */, + FAC8E8D416F3C468004DADF3 /* OSX.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -279,15 +271,6 @@ ); GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = love_Prefix.pch; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL.framework/Headers, - ); INSTALL_PATH = /Applications; PRODUCT_NAME = love; }; @@ -303,15 +286,6 @@ "\"$(SRCROOT)/build/Release\"", "\"$(SRCROOT)/build/Debug\"", ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = love_Prefix.pch; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL.framework/Headers, - ); INSTALL_PATH = /Applications; PRODUCT_NAME = love; }; @@ -321,10 +295,13 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_ENABLE_MODULES = YES; FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = NO; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; @@ -346,14 +323,19 @@ "\"$(SRCROOT)/../../src/libraries\"", "\"$(SRCROOT)/../../src/modules\"", /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/FreeType.framework/Headers, - /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL2.framework/Headers, ); INFOPLIST_FILE = "love-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/../Libraries"; - MACOSX_DEPLOYMENT_TARGET = 10.5; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; + "OTHER_LDFLAGS[arch=x86_64]" = ( + "-pagezero_size", + 10000, + "-image_base", + 100000000, + ); PRODUCT_NAME = love; WARNING_CFLAGS = ( "-Wall", @@ -366,10 +348,14 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_ENABLE_MODULES = YES; DEPLOYMENT_POSTPROCESSING = NO; FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; GCC_INPUT_FILETYPE = automatic; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = NO; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; @@ -393,15 +379,20 @@ "\"$(SRCROOT)/../../src/libraries\"", "\"$(SRCROOT)/../../src/modules\"", /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/FreeType.framework/Headers, - /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL2.framework/Headers, ); INFOPLIST_FILE = "love-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/../Libraries"; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; LLVM_LTO = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; + MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = ""; + "OTHER_LDFLAGS[arch=x86_64]" = ( + "-pagezero_size", + 10000, + "-image_base", + 100000000, + ); PRODUCT_NAME = love; SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; WARNING_CFLAGS = ( diff --git a/platform/macosx/loveProj.xcconfig b/platform/macosx/loveProj.xcconfig deleted file mode 100644 index 73543b888..000000000 --- a/platform/macosx/loveProj.xcconfig +++ /dev/null @@ -1,8 +0,0 @@ - GCC_ENABLE_CPP_EXCEPTIONS = YES; - GCC_ENABLE_CPP_RTTI = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - PREBINDING = NO; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; \ No newline at end of file diff --git a/platform/macosx/loveTarget.xcconfig b/platform/macosx/loveTarget.xcconfig deleted file mode 100644 index 12fb0c000..000000000 --- a/platform/macosx/loveTarget.xcconfig +++ /dev/null @@ -1,7 +0,0 @@ - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = love_Prefix.pch; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = $(HOME)/Applications; - PRODUCT_NAME = love; - STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = Dynamic; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; diff --git a/platform/macosx/love_Prefix.pch b/platform/macosx/love_Prefix.pch deleted file mode 100644 index 877e839f1..000000000 --- a/platform/macosx/love_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'love' target in the 'love' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/platform/macosx/script.sh b/platform/macosx/script.sh deleted file mode 100644 index 3ce93d6d7..000000000 --- a/platform/macosx/script.sh +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh -#Use install_name_tool, make love to search libs in its own framework folder instead -#*very* hackish. -#IL -install_name_tool -change /usr/local/lib/libIL.dylib @executable_path/../Frameworks/IL.framework/Versions/A/IL build/Release/love.app/Contents/MacOS/love - -install_name_tool -change /usr/local/lib/libILU.dylib @executable_path/../Frameworks/IL.framework/Versions/A/IL build/Release/love.app/Contents/MacOS/love - -install_name_tool -change /usr/local/lib/libILUT.dylib @executable_path/../Frameworks/IL.framework/Versions/A/IL build/Release/love.app/Contents/MacOS/love - -install_name_tool -change /usr/local/lib/libIL.1.dylib @executable_path/../Frameworks/IL.framework/Versions/A/IL build/Release/love.app/Contents/MacOS/love - -install_name_tool -change /usr/local/lib/libILU.1.dylib @executable_path/../Frameworks/IL.framework/Versions/A/IL build/Release/love.app/Contents/MacOS/love - -install_name_tool -change /usr/local/lib/libILUT.1.dylib @executable_path/../Frameworks/IL.framework/Versions/A/IL build/Release/love.app/Contents/MacOS/love - -# FreeType -install_name_tool -change /Library/Frameworks/FreeType.framework/Versions/2.3/FreeType @executable_path/../Frameworks/FreeType.framework/Versions/2.3/FreeType build/Release/love.app/Contents/MacOS/love - -# SDL -install_name_tool -change /Library/Frameworks/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL build/Release/love.app/Contents/MacOS/love - -install_name_tool -change /Library/Frameworks/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL build/Release/love.app/Contents/Frameworks/SDL_mixer.framework/SDL_mixer - -# SDL_mixer -#install_name_tool -change /Library/Frameworks/SDL_mixer.framework/Versions/A/SDL_mixer @executable_path/../#Frameworks/SDL_mixer.framework/Versions/A/SDL_mixer build/Release/love.app/Contents/MacOS/love - -exit 0 \ No newline at end of file diff --git a/platform/msvc2010/liblove.vcxproj b/platform/msvc2010/liblove.vcxproj index 9071343ef..8bbf1d65a 100644 --- a/platform/msvc2010/liblove.vcxproj +++ b/platform/msvc2010/liblove.vcxproj @@ -144,7 +144,7 @@ Level3 Disabled - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories) + include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) true _DEBUG;DEBUG;%(PreprocessorDefinitions) false @@ -154,10 +154,11 @@ true - kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) - - + msvcrtd.lib;msvcprtd.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) + true lib\$(PlatformShortName)\Debug\MD\ + $(TargetDir)lib$(TargetName).pdb + $(TargetDir)lib$(TargetName).pgd LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -167,7 +168,7 @@ Level3 Disabled - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories) + include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) true _DEBUG;DEBUG;%(PreprocessorDefinitions) false @@ -177,10 +178,11 @@ true - kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) - - + msvcrtd.lib;msvcprtd.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) + true lib\$(PlatformShortName)\Debug\MD\ + $(TargetDir)lib$(TargetName).pdb + $(TargetDir)lib$(TargetName).pgd LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -192,7 +194,7 @@ MaxSpeed true true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories) + include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) true true NDEBUG;%(PreprocessorDefinitions) @@ -211,6 +213,12 @@ MachineX86 + + + + + true + true @@ -219,7 +227,7 @@ MaxSpeed true true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories) + include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) true true NDEBUG;%(PreprocessorDefinitions) @@ -238,6 +246,12 @@ MachineX64 + + + + + true + true @@ -246,7 +260,7 @@ MaxSpeed true true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories) + include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) true true NDEBUG;%(PreprocessorDefinitions) @@ -259,10 +273,11 @@ true true true - kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) - - + msvcrt.lib;msvcprt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) + true lib\$(PlatformShortName)\Release\MD\ + $(TargetDir)lib$(TargetName).pdb + $(TargetDir)lib$(TargetName).pgd LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -274,7 +289,7 @@ MaxSpeed true true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;%(AdditionalIncludeDirectories) + include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) true true NDEBUG;%(PreprocessorDefinitions) @@ -287,10 +302,11 @@ true true true - kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) - - + msvcrt.lib;msvcprt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) + true lib\$(PlatformShortName)\Release\MD\ + $(TargetDir)lib$(TargetName).pdb + $(TargetDir)lib$(TargetName).pgd LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -300,7 +316,6 @@ - @@ -356,6 +371,16 @@ + + + + + + + + + + @@ -370,6 +395,11 @@ + + + + + @@ -398,7 +428,6 @@ - @@ -406,38 +435,54 @@ + + - + - + - - + + + + + + + + + - + + + + + + + + @@ -490,18 +535,29 @@ + - + + + + + + + + - + + + + @@ -576,6 +632,18 @@ + + + + + + + + + + + + @@ -593,10 +661,15 @@ + + + + + @@ -635,39 +708,57 @@ + + - + - + - - + + + + + + + + + + + - + + + + + + + + @@ -721,19 +812,31 @@ + + + + + + + + + - + + + + diff --git a/platform/msvc2010/liblove.vcxproj.filters b/platform/msvc2010/liblove.vcxproj.filters index 3d36ad685..b8b835469 100644 --- a/platform/msvc2010/liblove.vcxproj.filters +++ b/platform/msvc2010/liblove.vcxproj.filters @@ -106,9 +106,6 @@ {72f85e75-dd35-4a93-9c39-258c8aee813b} - - {d39bd4fd-3bea-428a-813f-4b1c55aedac8} - {806ac1d0-ed5c-47d5-8cdc-60e3fdbfe412} @@ -136,6 +133,45 @@ {5d2c2149-93bf-42a6-b8b5-6ddbac9485a3} + + {5673936a-786e-40ee-96d2-1830e89c1532} + + + {dd0ef317-7117-4ddc-b8ef-aaf58130c7bd} + + + {d39bd4fd-3bea-428a-813f-4b1c55aedac8} + + + {d5e565d0-da66-4412-9144-dff8c7d82b2e} + + + {4bf8a9b0-db1a-4a6e-a157-a9eab128f5ca} + + + {ab75aa3d-8e32-45e0-b91b-ed3cb31f472e} + + + {86f5346b-8859-4c03-8c1f-3bd8d200b658} + + + {a9a12c5a-ff54-43c1-b0c6-ba1597af7b03} + + + {731671fa-d695-42c3-9d1c-9e227d9ebab4} + + + {2241f4ca-a51c-4d8d-be82-2b7dfd267b7b} + + + {731671fa-d695-42c3-9d1c-9e227d9ebab4} + + + {2241f4ca-a51c-4d8d-be82-2b7dfd267b7b} + + + {4127f9be-b9c3-45bf-968f-888df9d5bc35} + @@ -435,27 +471,18 @@ modules\graphics - - modules\graphics - modules\graphics modules\graphics - - modules\graphics - modules\graphics modules\graphics\opengl - - modules\graphics\opengl - modules\graphics\opengl @@ -480,9 +507,6 @@ modules\graphics\opengl - - modules\graphics\opengl - modules\graphics\opengl @@ -516,12 +540,6 @@ modules\image - - modules\image\devil - - - modules\image\devil - modules\joystick @@ -717,15 +735,6 @@ modules\sound\lullaby - - modules\thread - - - modules\thread - - - modules\thread - modules\timer @@ -744,15 +753,186 @@ common - - common - - - modules\math - modules\math + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread\sdl + + + modules\thread\sdl + + + modules\math + + + libraries\ddsparse + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image + + + modules\image + + + modules\math + + + modules\math + + + libraries\noise1234 + + + modules\math + + + modules\math + + + modules\window + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet\libenet + + + libraries\enet + + + modules\graphics\opengl + + + modules\joystick\sdl + + + modules\joystick\sdl + + + modules\mouse + + + modules\mouse + + + modules\mouse\sdl + + + modules\system + + + modules\system + + + modules\system\sdl + + + modules\joystick\sdl + + + modules\joystick\sdl + + + modules\mouse + + + modules\mouse + + + modules\mouse\sdl + + + modules\system + + + modules\system + + + modules\system\sdl + + + modules\graphics + + + modules\graphics\opengl + + + modules\graphics\opengl + + + modules\graphics\opengl + + + libraries\Wuff + + + libraries\Wuff + + + libraries\Wuff + + + libraries\Wuff + + + modules\sound\lullaby + @@ -1117,18 +1297,12 @@ modules\graphics - - modules\graphics - modules\graphics modules\graphics - - modules\graphics - modules\graphics @@ -1141,9 +1315,6 @@ modules\graphics\opengl - - modules\graphics\opengl - modules\graphics\opengl @@ -1168,9 +1339,6 @@ modules\graphics\opengl - - modules\graphics\opengl - modules\graphics\opengl @@ -1204,12 +1372,6 @@ modules\image - - modules\image\devil - - - modules\image\devil - modules\joystick @@ -1408,15 +1570,6 @@ modules\sound\lullaby - - modules\thread - - - modules\thread - - - modules\thread - modules\timer @@ -1435,12 +1588,207 @@ modules\love - - modules\math - modules\math + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread + + + modules\thread\sdl + + + modules\thread\sdl + + + modules\math + + + libraries\ddsparse + + + libraries\ddsparse + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image\magpie + + + modules\image + + + modules\image + + + modules\math + + + modules\math + + + libraries\noise1234 + + + modules\math + + + modules\math + + + modules\window + + + libraries\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + libraries\enet\libenet\include\enet + + + modules\graphics\opengl + + + modules\joystick + + + modules\joystick\sdl + + + modules\joystick\sdl + + + modules\mouse + + + modules\mouse + + + modules\mouse\sdl + + + modules\system + + + modules\system + + + modules\system\sdl + + + modules\joystick + + + modules\joystick\sdl + + + modules\joystick\sdl + + + modules\mouse + + + modules\mouse + + + modules\mouse\sdl + + + modules\system + + + modules\system + + + modules\system\sdl + + + modules\graphics + + + modules\graphics + + + modules\graphics\opengl + + + modules\graphics\opengl + + + modules\graphics\opengl + + + libraries\Wuff + + + libraries\Wuff + + + libraries\Wuff + + + libraries\Wuff + + + modules\sound\lullaby + diff --git a/platform/msvc2010/love.rc b/platform/msvc2010/love.rc index 1e91ecf7d..bb620fa11 100644 Binary files a/platform/msvc2010/love.rc and b/platform/msvc2010/love.rc differ diff --git a/platform/msvc2010/love.sln b/platform/msvc2010/love.sln index ef69a54a3..0bb8e3171 100644 --- a/platform/msvc2010/love.sln +++ b/platform/msvc2010/love.sln @@ -10,36 +10,36 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblove", "liblove.vcxproj" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug Dynamic|Win32 = Debug Dynamic|Win32 - Debug Dynamic|x64 = Debug Dynamic|x64 - Release Dynamic|Win32 = Release Dynamic|Win32 - Release Dynamic|x64 = Release Dynamic|x64 - Release Static|Win32 = Release Static|Win32 - Release Static|x64 = Release Static|x64 + Debug MD|Win32 = Debug MD|Win32 + Debug MD|x64 = Debug MD|x64 + Release MD|Win32 = Release MD|Win32 + Release MD|x64 = Release MD|x64 + Release MT|Win32 = Release MT|Win32 + Release MT|x64 = Release MT|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug Dynamic|Win32.ActiveCfg = Debug Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug Dynamic|Win32.Build.0 = Debug Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug Dynamic|x64.ActiveCfg = Debug Dynamic|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|Win32.ActiveCfg = Release Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|Win32.Build.0 = Release Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|x64.ActiveCfg = Release Dynamic|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|x64.Build.0 = Release Dynamic|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|Win32.Build.0 = Release Static|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|x64.ActiveCfg = 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.Build.0 = Debug Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|x64.ActiveCfg = Debug Dynamic|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Dynamic|Win32.ActiveCfg = Release Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Dynamic|Win32.Build.0 = Release Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Dynamic|x64.ActiveCfg = Release Dynamic|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Dynamic|x64.Build.0 = Release Dynamic|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Static|Win32.ActiveCfg = Release Static|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Static|Win32.Build.0 = Release Static|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Static|x64.ActiveCfg = Release Static|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release Static|x64.Build.0 = Release Static|x64 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug MD|Win32.ActiveCfg = Debug Dynamic|Win32 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug MD|Win32.Build.0 = Debug Dynamic|Win32 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug MD|x64.ActiveCfg = Debug Dynamic|x64 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|Win32.ActiveCfg = Release Dynamic|Win32 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|Win32.Build.0 = Release Dynamic|Win32 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|x64.ActiveCfg = Release Dynamic|x64 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|x64.Build.0 = Release Dynamic|x64 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|Win32.ActiveCfg = Release Static|Win32 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|Win32.Build.0 = Release Static|Win32 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|x64.ActiveCfg = Release Static|x64 + {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|x64.Build.0 = Release Static|x64 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug MD|Win32.ActiveCfg = Debug Dynamic|Win32 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug MD|Win32.Build.0 = Debug Dynamic|Win32 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug MD|x64.ActiveCfg = Debug Dynamic|x64 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|Win32.ActiveCfg = Release Dynamic|Win32 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|Win32.Build.0 = Release Dynamic|Win32 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|x64.ActiveCfg = Release Dynamic|x64 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|x64.Build.0 = Release Dynamic|x64 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|Win32.ActiveCfg = Release Static|Win32 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|Win32.Build.0 = Release Static|Win32 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|x64.ActiveCfg = Release Static|x64 + {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|x64.Build.0 = Release Static|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/platform/msvc2010/love.vcxproj b/platform/msvc2010/love.vcxproj index 190e435fb..1d956c3a7 100644 --- a/platform/msvc2010/love.vcxproj +++ b/platform/msvc2010/love.vcxproj @@ -135,8 +135,10 @@ true Windows lib\$(PlatformShortName)\Debug\MD\ - msvcrtd.lib;msvcprtd.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) + msvcrtd.lib;msvcprtd.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).pgd @@ -150,13 +152,16 @@ false + false true Windows - lib\$(PlatformShortName)\Debug\MT\ - msvcrtd.lib;msvcprtd.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua5.1.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) + lib\$(PlatformShortName)\Debug\MD\ + msvcrtd.lib;msvcprtd.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) true + $(TargetDir)$(TargetName).pgd + $(TargetDir)$(TargetName).pdb @@ -173,13 +178,12 @@ MachineX86 - - + true Windows true true lib\$(PlatformShortName)\Release\MD\ - msvcrt.lib;msvcprt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) + msvcrt.lib;msvcprt.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) true @@ -196,13 +200,12 @@ true - - + true Windows true true lib\$(PlatformShortName)\Release\MD\ - msvcrt.lib;msvcprt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) + msvcrt.lib;msvcprt.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) true @@ -220,9 +223,12 @@ Windows true true - libcmt.lib;libcpmt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua5.1.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) + libcmt.lib;libcpmt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) lib\$(PlatformShortName)\Release\MT\ true + NotSet + true + true @@ -239,9 +245,10 @@ Windows true true - libcmt.lib;libcpmt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;opengl32.lib;oldnames.lib;freetype2.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua5.1.lib;physfs.lib;SDLmain.lib;zlib.lib;DevIL.lib;mpg123.lib;OpenAL.lib;SDL.lib;%(AdditionalDependencies) + libcmt.lib;libcpmt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) lib\$(PlatformShortName)\Release\MT\ true + true diff --git a/platform/unix/Makefile.am b/platform/unix/Makefile.am index 11db97c4a..5bde88606 100644 --- a/platform/unix/Makefile.am +++ b/platform/unix/Makefile.am @@ -1,3 +1,24 @@ ACLOCAL_AMFLAGS = -I platform/unix/m4 SUBDIRS = src -EXTRA_DIST = changes.txt license.txt readme.txt +EXTRA_DIST = changes.txt license.txt readme.md \ + platform/unix/love.desktop.in +dist_man1_MANS = platform/unix/love.1 + +applicationsdir=$(datarootdir)/applications +mimeinfodir=$(datarootdir)/mime/packages +pixmapsdir=$(datarootdir)/pixmaps +mimeiconsdir=$(datarootdir)/icons/hicolor/scalable/mimetypes + +applications_DATA = platform/unix/love.desktop +dist_mimeinfo_DATA = platform/unix/love.xml +dist_pixmaps_DATA = platform/unix/love.svg +dist_mimeicons_DATA = platform/unix/application-x-love-game.svg + +platform/unix/love.desktop: platform/unix/love.desktop.in + $(MKDIR_P) platform/unix + rm -f $@ $@.tmp + $(SED) \ + -e "s|@bindir[@]|$(bindir)|" \ + ${srcdir}/$@.in > $@.tmp + chmod a-w $@.tmp + mv $@.tmp $@ diff --git a/platform/unix/game.svg b/platform/unix/application-x-love-game.svg similarity index 100% rename from platform/unix/game.svg rename to platform/unix/application-x-love-game.svg diff --git a/platform/unix/autobuild b/platform/unix/autobuild deleted file mode 100755 index b5a1be016..000000000 --- a/platform/unix/autobuild +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/bash - -# -# This script gets all needed packages, builds LOVE, makes deb and tar.gz -# and optionally uploads them to servers. -# -# Note: this script must be called in the same directory as the love -# folder resides. It also assumes that love has been checked out previously. -# -# Usage: -# -# autobuild [action [revision [version]]] -# -# action: -# -# There are only two recognized actions: -# -# build -- Causes files to be uploaded to tehlol servers. -# release -- Coming soon. -# -# All other actions will be ignored, so if you don not wish to upload -# files (but still build LOVE), you can write "test", for instance. -# -# revision: -# -# The revision that should be built. Should be a valid revision -# number or tip. If not specified, it defaults to tip. -# -# version: -# -# The display version that will appear in files, eg. love-version.tar.gz. -# If not specified, the script defaults to use the SVN revision number. -# -# Examples: -# -# autobuild -# (Builds HEAD, but does not upload) -# -# autobuild build -# (Builds tip and uploads to tehlol server with the current rev. as -# version number) -# -# autobuild build tip 1.0 -# (Builds tip and uploads it using the version 1.0) -# -# -# Passwords for servers must be in these external files: -# -# tehlol.com: pwtehlol -# sourceforge.net: pwsourceforge -# - -cd ../.. - -# Get required packages. -#sudo apt-get -y install subversion build-essential liblua5.1-dev \ -#libopenal-dev libsdl1.2-dev libfreetype6-dev \ -#libphysfs-dev libdevil-dev libtiff4-dev libmng-dev \ -#liblcms1-dev ftp-upload libmpg123-dev libmodplug-dev libpng12-dev - -# Check which revision to build. -if [ -z $2 ]; then - buildrev="tip" -else - buildrev=$2 -fi - -echo $buildrev - -# Upload to the appropriate revision. -hg pull -hg update -r $buildrev - -# Set the displayversion. -if [ -z $3 ]; then - if [ "$buildrev" == "tip" ]; then - # Get the current SVN version, use sed to remove any non-numbers. - currentversion=`hg log -l1 --template "{node|short}"` - currentdate=`date +%Y%m%d` - displayversion="$currentdate-$currentversion" - else - # The revision is already specified, so we'll use that as the - # display version. - displayversion="$buildrev" - fi -else - # If the param is present, it overrides everything else. - displayversion=$3 -fi - -echo $displayversion - -# Update version in configure. -# cat configure.in | sed "s/LOVE_VERSION/$displayversion/g" > configure.in -head -c 15 configure.in > configure.in.tmp -echo " [$displayversion])" >> configure.in.tmp -tail -n +2 configure.in >> configure.in.tmp -cp configure.in.tmp configure.in -rm configure.in.tmp - -# Build ... BUILD! -#sh platform/unix/gen-makefile -sh platform/unix/automagic -./configure -make -make dist - -# Move and rename the tar. -tar="love-$displayversion-linux-src.tar.gz" -mv "love-$displayversion.tar.gz" platform/unix/$tar - -# Create the deb. -cd platform/unix -sh make-package deb $displayversion - -machine=`uname -m` - -# Move and rename the deb. -deb="love-$displayversion-ubuntu-$machine.deb" -mv "love-$displayversion.deb" $deb - -# Copy and rename the binary. -binary="love-$displayversion-linux-$machine" -cp ../../src/love $binary - -# Deal with uploading. -#if [ "$1" == "build" ]; then -# curl -F build=@$deb -F press=ok http://love2d.org/builds/upload.php?upload -# curl -F build=@$tar -F press=ok http://love2d.org/builds/upload.php?upload -# curl -F build=@$binary -F press=ok http://love2d.org/builds/upload.php?upload -#fi - -if [ "$1" == "release" ]; then - echo "release" -fi diff --git a/platform/unix/automagic b/platform/unix/automagic index eca181b0d..6e5c68bb3 100755 --- a/platform/unix/automagic +++ b/platform/unix/automagic @@ -1,15 +1,24 @@ #!/bin/bash +log() { + echo "[automagic] " $@ +} + die() { - echo "Fatal: "$@ + log "Fatal: "$@ exit 1 } -AUTOHEADER=$(which autoheader) -AUTOCONF=$(which autoconf) -LIBTOOLIZE=$(which libtoolize) -ACLOCAL=$(which aclocal) -AUTOMAKE=$(which automake) +if [[ ! -d platform/unix ]]; then + log "Can't find the 'plaform/unix' folder, make sure you run this from the root of the repository." + exit 1 +fi + +AUTOHEADER=${AUTOHEADER:-$(which autoheader)} +AUTOCONF=${AUTOCONF:-$(which autoconf)} +LIBTOOLIZE=${LIBTOOLIZE:-$(which libtoolize)} +ACLOCAL=${ACLOCAL:-$(which aclocal)} +AUTOMAKE=${AUTOMAKE:-$(which automake)} [[ -x ${AUTOHEADER} ]] || die "Could not find autoheader. Install autoconf." [[ -x ${AUTOCONF} ]] || die "Could not find autoconf." @@ -18,29 +27,43 @@ AUTOMAKE=$(which automake) [[ -x ${AUTOMAKE} ]] || die "Could not find automake." automagic() { + log "Copying files..." >&2 cp platform/unix/configure.ac . cp platform/unix/Makefile.am . - if ! sh platform/unix/gen-makefile; then + log "Running genmodules..." >&2 + if ! bash platform/unix/genmodules "$1"; then echo "You should be doing this from the root directory of the project." exit 1 fi + log "Running autoheader..." >&2 ${AUTOHEADER} 2>&1 || return 1 # Gimmie config.h.in + + log "Running libtoolize..." >&2 ${LIBTOOLIZE} --force 2>&1 || return 1 + + log "Running aclocal..." >&2 ${ACLOCAL} 2>&1 || return 1 + + log "Running autoconf..." >&2 ${AUTOCONF} 2>&1 || return 1 + + log "Running automake..." >&2 ${AUTOMAKE} -a 2>&1 || return 1 } if [[ $1 == "-d" ]]; then - automagic + shift 1 + automagic "$@" 2>&1 else - automagic > /dev/null + (automagic "$@" > /dev/null) 2>&1 fi -if [ $? -eq 1 ]; then - echo "Failed, please contact the developers." +if [[ $? -eq 1 ]]; then + log "Failed, sadface." + log "You can make this script more verbose running it in debug mode (-d)" + log "This is generally a configuration error (I'm looking at you aclocal)" exit 1 else - echo "Success, carry on configuring." + log "Success, carry on configuring." fi diff --git a/platform/unix/configure.ac b/platform/unix/configure.ac index 8ba3bc264..4347329f0 100644 --- a/platform/unix/configure.ac +++ b/platform/unix/configure.ac @@ -10,75 +10,134 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LIBTOOL AC_PROG_CC AC_PROG_CXX +AC_PROG_SED +AC_PROG_MKDIR_P +AC_PROG_OBJCXX AC_C_BIGENDIAN -AC_SEARCH_LIBS([sqrt], [m], [], AC_MSG_ERROR([Can't LÖVE without C math library])) -AC_SEARCH_LIBS([SDL_Init], [SDL], [], AC_MSG_ERROR([Can't LÖVE without SDL])) -AC_SEARCH_LIBS([glLoadIdentity], [GL], [], AC_MSG_ERROR([Can't LÖVE without OpenGL])) -#AC_SEARCH_LIBS([gluOrtho2D], [GLU], [], AC_MSG_ERROR([Can't LÖVE without OpenGL Utility Library])) -AC_SEARCH_LIBS([alSourcePlay], [openal], [], AC_MSG_ERROR([Can't LÖVE without OpenAL])) -lua=lua -AC_ARG_WITH([luajit], - [AS_HELP_STRING([--with-luajit], [Use LuaJIT instead of lua and llvm-lua])], - [lua=luajit], - []) -AC_ARG_WITH([llvm-lua], - [AS_HELP_STRING([--with-llvm-lua], [Use llvm-lua instead of lua and LuaJIT])], - [lua=llvm-lua], - []) +AC_LANG([C++]) -AS_IF([test "$lua" = "lua"], - AC_SEARCH_LIBS( - [lua_pcall], - [lua lua5.1], - if test "$ac_cv_search_lua_pcall" = "-llua5.1"; then - AC_SUBST([INCLUDE_LUA], [-I/usr/include/lua5.1]) - fi, - AC_MSG_ERROR([Can't LÖVE without Lua]) - ) - ) -AS_IF([test "$lua" = "luajit"], - AC_SEARCH_LIBS( - [lua_pcall], - [luajit luajit-5.1], - AC_SUBST([INCLUDE_LUA], [-I/usr/include/luajit-2.0]), - AC_MSG_ERROR([Can't LÖVE without LuaJIT]) - ) - ) -AS_IF([test "$lua" = "llvm-lua"], - AC_SEARCH_LIBS( - [lua_pcall], - [llvm-lua], - [], - AC_MSG_ERROR([Can't LÖVE without llvm-lua]) - ) - ) +includes= -AC_SEARCH_LIBS([ilInit], [IL], [], AC_MSG_ERROR([Can't LÖVE without DevIL])) -AC_SEARCH_LIBS([FT_Load_Glyph], [freetype], [], AC_MSG_ERROR([Can't LÖVE without FreeType])) -AC_SEARCH_LIBS([PHYSFS_init], [physfs], [], AC_MSG_ERROR([Can't LÖVE without PhysicsFS])) -AC_SEARCH_LIBS([ModPlug_Load], [modplug], [], AC_MSG_ERROR([Can't LÖVE without ModPlug])) -AC_SEARCH_LIBS([ov_open], [vorbisfile], [], AC_MSG_ERROR([Can't LÖVE without VorbisFile])) +AC_DEFUN([ACLOVE_CXX_FLAG_TEST], # WARNING: NOT REENTRANT + [aclove_cxx_flag_test_save_cflags="$CXXFLAGS" + CXXFLAGS="$1" + AC_MSG_CHECKING([whether $CXX supports flag $1]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], + [AC_MSG_RESULT([yes])]; $2, + [AC_MSG_RESULT([no]); $3]) + CXXFLAGS="$aclove_cxx_flag_test_save_cflags"]) +AC_DEFUN([LOVE_MSG_ERROR], + [AC_MSG_ERROR([LÖVE needs "$1"[,] please install "$1" with development files and try again])]) + +# C++11 support +cxx11name="no" +ACLOVE_CXX_FLAG_TEST([-std=c++0x], cxx11name="c++0x", []) +ACLOVE_CXX_FLAG_TEST([-std=c++11], cxx11name="c++11", []) +AS_VAR_IF([cxx11name], [no], AC_MSG_ERROR([LÖVE needs a C++ compiler with C++11 support]), CXXFLAGS="$CXXFLAGS -std=$cxx11name") + +# Allow people on OSX to use autotools, they need their platform files +AC_ARG_ENABLE([osx], + AC_HELP_STRING([--enable-osx], [Compile platform-specific files for OSX]), [], [enable_osx=no]) +AS_VAR_IF([enable_osx], [no], [], #else + ac_cv_search_glLoadIdentity="-framework OpenGL" + AC_SUBST([LDFLAGS], ["${LDFLAGS} -framework CoreFoundation -framework Cocoa"]) + AC_SUBST([CPPFLAGS], ["${CPPFLAGS} -I../platform/macosx"])) + +# --with-lua and --with-luaversion +AC_ARG_WITH([lua], [AS_HELP_STRING([--with-lua], [Select the lua implementation])], + [], [with_lua=luajit]) +AC_ARG_WITH([luaversion], [AS_HELP_STRING([--with-luaversion], [Select the lua version])], + [], [with_luaversion=5.1]) + +# pkg-config libraries +AM_PATH_SDL2([], [], [LOVE_MSG_ERROR([SDL 2])]) +PKG_CHECK_MODULES([lua], [${with_lua}${with_luaversion}], [lua_found=yes], + [PKG_CHECK_MODULES([lua], [${with_lua}], [lua_found=yes], [lua_found=no])]) +PKG_CHECK_MODULES([freetype2], [freetype2], [], [LOVE_MSG_ERROR([FreeType2])]) +PKG_CHECK_MODULES([openal], [openal], [], [LOVE_MSG_ERROR([OpenAL])]) +PKG_CHECK_MODULES([devil], [IL], [], [LOVE_MSG_ERROR([DevIL])]) +PKG_CHECK_MODULES([libmodplug], [libmodplug], [], [LOVE_MSG_ERROR([libmodplug])]) +PKG_CHECK_MODULES([vorbisfile], [vorbisfile], [], [LOVE_MSG_ERROR([libvorbis and libvorbisfile])]) + +# Other libraries +AC_SEARCH_LIBS([sqrt], [m], [], [LOVE_MSG_ERROR([the C math library])]) +AC_SEARCH_LIBS([PHYSFS_init], [physfs], [], [LOVE_MSG_ERROR([PhysicsFS])]) +AC_SEARCH_LIBS([glLoadIdentity], [GL], [], [LOVE_MSG_ERROR([OpenGL])]) + +# Lua, treated seperately because of --with-lua +AS_VAR_IF([with_luaversion], [5.2], [luatest=lua_version], [luatest=lua_pcall]) # use lua_version for 5.2 +AS_VAR_IF([lua_found], [yes], + #if + [ + luaheaders_found=yes + AC_MSG_CHECKING([for library containing ${luatest}]) + AC_MSG_RESULT([${lua_LIBS}])], + #else + [ + AC_MSG_WARN([Could not find pkg-config definition for ${with_lua}${with_luaversion} or ${with_lua}, falling back to manual detection]) + AC_SEARCH_LIBS([$luatest], ["${with_lua}${with_luaversion}" "${with_lua}"], [], + [LOVE_MSG_ERROR([$with_lua])]) + luaheaders_found=no + AC_CHECK_HEADER(["${with_lua}${with_luaversion}/lua.h"], [luaheaders_found=yes includes="$includes -I/usr/include/${with_lua}${with_luaversion}"], []) + AC_CHECK_HEADER(["${with_lua}/lua.h"], [luaheaders_found=yes includes="$includes -I/usr/include/${with_lua}"], [])]) +AS_VAR_IF([luaheaders_found], [yes], [], #else + [ + AC_MSG_WARN([Could not locate lua headers for ${with_lua}${with_luaversion} or ${with_lua}, you probably need to specify them with CPPFLAGS])]) + +# mpg123, treated seperately because it can be disabled (default on) +# also not pkg-config because of the FILE_OFFSET_BITS.. bit AC_ARG_ENABLE([mpg123], AC_HELP_STRING([--disable-mpg123], [Disable mp3 support, for patent-free builds]), [], [enable_mpg123=yes]) -AS_IF([test "x$enable_mpg123" != xno], - AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [], AC_MSG_ERROR([Can't LÖVE without Mpg123])), - AC_DEFINE([LOVE_NOMPG123], [], [Build without mpg123])) -AS_IF([test "x$enable_mpg123" != xno], - AC_SEARCH_LIBS([mpg123_seek_64], [mpg123], AC_SUBST([FILE_OFFSET],[-D_FILE_OFFSET_BITS=64]), AC_SUBST([FILE_OFFSET],[]))) - -AC_ARG_ENABLE([exe], AC_HELP_STRING([--disable-exe], [Disable building of executable launcher]), [], [enable_exe=yes]) -AS_IF([test "x$enable_exe" != xno], - AC_DEFINE([LOVE_BUILD_EXE], [], [Don't build launcher])) -AM_CONDITIONAL([LOVE_BUILD_EXE], [test "x$enable_exe" != xno]) +AS_VAR_IF([enable_mpg123], [no], + AC_DEFINE([LOVE_NOMPG123], [], [Build without mpg123]), + # else + AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [], + [LOVE_MSG_ERROR([libmpg123])]) + AC_SEARCH_LIBS([mpg123_seek_64], [mpg123], + AC_SUBST([FILE_OFFSET],[-D_FILE_OFFSET_BITS=64]), + AC_SUBST([FILE_OFFSET],[]))) +# GME, treated seperately because it can be enabled (default off) AC_ARG_ENABLE([gme], AC_HELP_STRING([--enable-gme], [Enable GME support, for more chiptuney goodness]), [], [enable_gme=no]) -AS_IF([test "x$enable_gme" == xyes], - AC_SEARCH_LIBS([gme_open_data], [gme], [], AC_MSG_ERROR([Can't LÖVE without gme]))) -AS_IF([test "x$enable_gme" == xyes], - AC_DEFINE([LOVE_SUPPORT_GME], [], [Enable gme])) +AS_VAR_IF([enable_gme], [yes], + AC_SEARCH_LIBS([gme_open_data], [gme], [], [LOVE_MSG_ERROR([gme])]) + AC_DEFINE([LOVE_SUPPORT_GME], [], [Enable gme]) + AC_CHECK_HEADER([gme/gme.h], [includes="$includes -I/usr/include/gme"], [])) + +# libenet check for socklen_t +AC_CHECK_TYPE([socklen_t], [AC_DEFINE([HAS_SOCKLEN_T], [1], [Define if socklen_t exists.] )], , + #include + #include +) + +# Optionally build the executable (default on) +AC_ARG_ENABLE([exe], + AC_HELP_STRING([--disable-exe], [Disable building of executable launcher]), [], [enable_exe=yes]) + +AS_VAR_IF([enable_exe], [no], [], #else + AC_DEFINE([LOVE_BUILD_EXE], [], [Skip building launcher])) + +AM_CONDITIONAL([LOVE_BUILD_EXE], [test "x$enable_exe" != xno]) +AM_CONDITIONAL([LOVE_NOMPG123], [test "x$enable_mpg123" == xno]) +AM_CONDITIONAL([LOVE_TARGET_OSX], [test "x$enable_osx" != xno]) + +# Automatic script file rebuilding +AC_CHECK_PROGS([LUA_EXECUTABLE], ["${with_lua}${with_luaversion}" "${with_lua}" "lua"], [:]) +AS_VAR_IF([LUA_EXECUTABLE], [:], + [AC_MSG_WARN([Did not find a lua executable, you may need to update the scripts manually if you change them])], []) + +# Set our includes as automake variable +AC_SUBST([LOVE_INCLUDES], ["$includes"]) + +m4_include([configure-modules.ac]) AC_CONFIG_FILES([ Makefile src/Makefile + platform/unix/debian/control + platform/unix/debian/changelog + platform/unix/debian/rules ]) AC_OUTPUT + +chmod 755 platform/unix/debian/rules diff --git a/platform/unix/debian b/platform/unix/debian deleted file mode 100644 index 92811065f..000000000 --- a/platform/unix/debian +++ /dev/null @@ -1,11 +0,0 @@ -Package: love -Version: %VERSION% -Section: games -Priority: optional -Architecture: %ARCHITECTURE% -Essential: no -Depends: libdevil1c2, libfreetype6, libgl1-mesa-glx, liblua5.1-0, libphysfs1, libsdl1.2debian, libopenal1, libogg0, libvorbis0a, libvorbisfile3, libmodplug0c2, libmpg123-0 -Installed-Size: %INSTALLSIZE% -Maintainer: Bart van Strien [bart.bes@gmail.com] -Provides: love -Description: LOVE is a free 2D game engine which enables easy game creation in Lua. diff --git a/platform/unix/debian/changelog.in b/platform/unix/debian/changelog.in new file mode 100644 index 000000000..4901a576a --- /dev/null +++ b/platform/unix/debian/changelog.in @@ -0,0 +1,5 @@ +love@LOVE_SUFFIX@ (0.9.0~ppatest5) precise; urgency=medium + + * Upstream testing release + + -- Bart van Strien Sat, 2 Nov 2013 16:23:40 +0100 diff --git a/platform/unix/debian/compat b/platform/unix/debian/compat new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/platform/unix/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/unix/debian/control.in b/platform/unix/debian/control.in new file mode 100644 index 000000000..d79d3a375 --- /dev/null +++ b/platform/unix/debian/control.in @@ -0,0 +1,59 @@ +Source: love@LOVE_SUFFIX@ +Section: games +Priority: extra +Maintainer: Bart van Strien +Build-Depends: debhelper (>= 9), + autotools-dev, + pkg-config, + libdevil-dev, + libfreetype6-dev, + libluajit-5.1-dev, + libphysfs-dev, + libsdl2-dev (>= 2.0.0), + libopenal-dev, + libogg-dev, + libvorbis-dev, + libflac-dev, + libflac++-dev, + libmodplug-dev, + libmpg123-dev, + libmng-dev +Standards-Version: 3.9.3 +Homepage: http://love2d.org + +Package: liblove@LOVE_SUFFIX@ +Architecture: any +Multi-Arch: same +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, + ${shlibs:Depends}, + libdevil1c2, + libmng1, + libfreetype6, + libgl1-mesa-glx, + libluajit-5.1-2, + libphysfs-1.0-0, + libsdl2 (>= 2.0.0), + libopenal1, + libogg0, + libvorbis0a, + libvorbisfile3, + libmodplug1, + libmpg123-0 +Description: LOVE is a free 2D game engine which enables easy game creation in Lua. + +Package: love@LOVE_SUFFIX@ +Architecture: any +Multi-Arch: same +Depends: ${misc:Depends}, + liblove@LOVE_SUFFIX@ (= ${binary:Version}) +Description: LOVE is a free 2D game engine which enables easy game creation in Lua. + +Package: love@LOVE_SUFFIX@-dbg +Priority: extra +Section: debug +Architecture: any +Multi-Arch: same +Depends: ${misc:Depends}, + love@LOVE_SUFFIX@ (= ${binary:Version}), +Description: LOVE is a free 2D game engine which enables easy game creation in Lua. diff --git a/platform/unix/debian/copyright b/platform/unix/debian/copyright new file mode 100644 index 000000000..96a64fe66 --- /dev/null +++ b/platform/unix/debian/copyright @@ -0,0 +1,20 @@ +Copyright (c) 2006-2013 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. diff --git a/platform/unix/debian/docs b/platform/unix/debian/docs new file mode 100644 index 000000000..6f69fe099 --- /dev/null +++ b/platform/unix/debian/docs @@ -0,0 +1,2 @@ +changes.txt +license.txt diff --git a/platform/unix/debian/liblove-unstable.install b/platform/unix/debian/liblove-unstable.install new file mode 100644 index 000000000..10a01ed09 --- /dev/null +++ b/platform/unix/debian/liblove-unstable.install @@ -0,0 +1 @@ +usr/lib/*/liblove-unstable.so.* diff --git a/platform/unix/debian/liblove.install b/platform/unix/debian/liblove.install new file mode 100644 index 000000000..93beb2897 --- /dev/null +++ b/platform/unix/debian/liblove.install @@ -0,0 +1 @@ +usr/lib/*/liblove.so.* diff --git a/platform/unix/debian/love-unstable.install b/platform/unix/debian/love-unstable.install new file mode 100644 index 000000000..77ebbd101 --- /dev/null +++ b/platform/unix/debian/love-unstable.install @@ -0,0 +1 @@ +usr/bin/love-unstable diff --git a/platform/unix/debian/love.install b/platform/unix/debian/love.install new file mode 100644 index 000000000..487155e20 --- /dev/null +++ b/platform/unix/debian/love.install @@ -0,0 +1 @@ +usr/bin/love diff --git a/platform/unix/debian/love.manpages b/platform/unix/debian/love.manpages new file mode 100644 index 000000000..a510eb2e1 --- /dev/null +++ b/platform/unix/debian/love.manpages @@ -0,0 +1 @@ +platform/unix/love.1 diff --git a/platform/unix/debian/rules.in b/platform/unix/debian/rules.in new file mode 100755 index 000000000..9ed42c92f --- /dev/null +++ b/platform/unix/debian/rules.in @@ -0,0 +1,16 @@ +#!/usr/bin/make -f + +DEB_HOST_ARCH_CPU ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_CPU) +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +override_dh_auto_configure: + dh_auto_configure -- --with-lua=luajit + +override_dh_link: + dh_link -plove@LOVE_SUFFIX@-dev usr/lib/$(DEB_HOST_MULTIARCH)/liblove@LOVE_SUFFIX@.so.0.0.0 usr/lib/$(DEB_HOST_MULTIARCH)/liblove@LOVE_SUFFIX@.so + +override_dh_strip: + dh_strip --dbg-package=love@LOVE_SUFFIX@-dbg + +%: + dh $@ --parallel diff --git a/platform/unix/debian/source/format b/platform/unix/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/platform/unix/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/platform/unix/exclude b/platform/unix/exclude index 931966fe6..b233a4d14 100644 --- a/platform/unix/exclude +++ b/platform/unix/exclude @@ -1,24 +1,5 @@ -\./modules/native/tcc/libtcc/tccelf\.c -\./modules/native/tcc/libtcc/x86_64-gen\.c -\./modules/native/tcc/libtcc/tccasm\.c -\./modules/native/tcc/libtcc/tccpp\.c -\./modules/native/tcc/libtcc/il-gen\.c -\./modules/native/tcc/libtcc/c67-gen\.c -\./modules/native/tcc/libtcc/tcc\.c -\./modules/native/tcc/libtcc/elf\.h -\./modules/native/tcc/libtcc/tcccoff\.c -\./modules/native/tcc/libtcc/config\.h -\./modules/native/tcc/libtcc/i386-asm\.h -\./modules/native/tcc/libtcc/tccpe\.c -\./modules/native/tcc/libtcc/tcctok\.h -\./modules/native/tcc/libtcc/arm-gen\.c -\./modules/native/tcc/libtcc/i386-asm\.c -\./modules/native/tcc/libtcc/i386-gen\.c -\./modules/native/tcc/libtcc/tccgen\.c -\./modules/native/tcc/libtcc/tcc\.h -\./modules/native/tcc/libtcc/il-opcodes\.h -\./modules/native/tcc/libtcc/coff\.h -\./modules/native/tcc/libtcc/stab\.h \./libraries/luasocket/libluasocket/wsocket\.* \./modules/sound/lullaby/FLACDecoder\.* \./love\.cpp +\./modules/sound/lullaby/Mpg123Decoder\.cpp +\./modules/sound/lullaby/Mpg123Decoder\.h diff --git a/platform/unix/gen-makefile b/platform/unix/gen-makefile index dc4ab7bf7..757653e2c 100644 --- a/platform/unix/gen-makefile +++ b/platform/unix/gen-makefile @@ -1,10 +1,12 @@ #!/bin/bash echo Generating src/Makefile.am ... -cd src -inc_current=. +inc_current='$(srcdir)' inc_modules="$inc_current/modules" inc_libraries="$inc_current/libraries" -echo "AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I/usr/include/AL -I/usr/include/freetype2 \$(INCLUDE_LUA) -I/usr/include/SDL \$(FILE_OFFSET) -I/usr/include/gme + +cat > src/Makefile.am << EOF +AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I$inc_libraries/enet/libenet/include \$(LOVE_INCLUDES) \$(FILE_OFFSET) +AM_CXXFLAGS = \$(SDL_CFLAGS) AUTOMAKE_OPTIONS = subdir-objects SUBDIRS = @@ -16,13 +18,21 @@ love_LDADD = liblove.la love_SOURCES = love.cpp endif +# Compile scripts +#scripts/%.lua.h: scripts/%.lua +# cd scripts; \ +# lua auto.lua \$* +#TODO: Figure out how to only do this on gnu make, and detect which lua +# executable to run + # libLÖVE lib_LTLIBRARIES = liblove.la -liblove_la_LDFLAGS = -module -export-dynamic \$(LDFLAGS) -liblove_la_SOURCES = \\" > Makefile.am.tmp -find . \( \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" -o -iname "*.lch" \) \) -exec echo '{}' \\ \; >> Makefile.am.tmp -cat Makefile.am.tmp | grep -v -f"../platform/unix/exclude" | head -c -3 > Makefile.am -#head -c -3 Makefile.am.tmp > Makefile.am -rm Makefile.am.tmp +liblove_la_LDFLAGS = -module -export-dynamic \$(LDFLAGS) \$(SDL_LIBS) +EOF + +platform/unix/genmodules >> src/Makefile.am + +printf "\n" >> src/Makefile.am + cd .. -echo src/Makefile.am is updated! \^.^ +echo "src/Makefile.am is updated! ^.^" diff --git a/platform/unix/genmodules b/platform/unix/genmodules new file mode 100644 index 000000000..5be29fae5 --- /dev/null +++ b/platform/unix/genmodules @@ -0,0 +1,168 @@ +#!/bin/bash + +love_suffix="$1" +love_amsuffix="$(echo "$love_suffix" | sed 's/\-/_/g' | sed 's/\./_/g')" + +flags="" +upper() +{ + echo "$@" | tr '[:lower:]' '[:upper:]' +} + +implfind() +{ + find "$1" -maxdepth 1 -type d -exec basename '{}' \; | grep -v "^\." | tail -n +2 +} + +sourcefind() +{ + find "$1" $2 -type f \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" -o -iname "*.lch" \) | awk "{print \"./$prefix\"\$0\" \\\\\"}" | grep -v -f"$LOVEROOT/platform/unix/exclude" +} + +handlemodule() +{ + module="$1" + DEFINENAME="LOVE_MODULE_$(upper "$module")" + printf "$DEFINENAME" +} + +handleimpl() +{ + module="$1" + implementation="$2" + name="$3" + + printf "if $name\n" + FILES="$(sourcefind "$module/$implementation" | sed "s/^/ /")" + if [[ "x$FILES" != "x" ]]; then + printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n" + printf "${FILES:0:${#FILES}-2}\n" + fi + printf "endif\n\n" +} + +genmodules() +{ + LOVEROOT="$(pwd)" + cd src + + printf "liblove${love_amsuffix}_la_SOURCES = \\\\\n" + sourcefind "common" | sed "s/^/ /" + FILES="$(sourcefind "scripts" | sed "s/^/ /")" + printf "${FILES:0:${#FILES}-2}\n\n" + + cd modules + prefix="modules/" + for module in *; do + NAME=$(handlemodule "$module") + flags="$flags module-$module" + + printf "if $NAME\n" + + for implementation in $(implfind "$module"); do + flags="$flags implementation-$module-$implementation" + handleimpl "$module" "$implementation" "LOVE_IMPLEMENTATION_$(upper "$module")_$(upper "$implementation")" + done + + FILES="$(sourcefind "$module" "-maxdepth 1" | sed "s/^/ /")" + if [[ "x$FILES" != "x" ]]; then + printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n" + printf "${FILES:0:${#FILES}-2}\n" + fi + + printf "endif\n\n" + done + + cd ../libraries + prefix="libraries/" + for library in *; do + NAME="LOVE_LIBRARY_$(upper "$library")" + flags="$flags library-$library" + + printf "if $NAME\n" + printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n" + FILES="$(sourcefind "$library" | sed "s/^/ /")" + printf "${FILES:0:${#FILES}-2}\nendif\n\n" + done + cd ../.. +} + +genflags() +{ + for flag in $flags; do + prettyflag="$(echo "$flag" | sed 's/-/ love./' | sed 's/-/./g')" + varflag="enable_$(echo "$flag" | sed 's/^[^-]*-//' | sed 's/[^a-zA-Z0-9]/_/')" + defineflag="LOVE_ENABLE_$(upper $(echo $flag | sed 's/^[^-]*-//' | sed 's/-/_/g'))" + amflag="$(upper $(echo love-$flag | sed 's/-/_/g'))" + printf "AC_ARG_ENABLE([$flag], [ --disable-$flag Turn off $prettyflag], [], [$varflag=true])\n" + printf "AH_TEMPLATE([$defineflag], [])\n" + printf "if test x\"\$$varflag\" == xtrue; then\n" + printf " AC_DEFINE([$defineflag], [])\n" + printf "fi\n" + printf "AM_CONDITIONAL([$amflag], [test x\$$varflag == xtrue])\n\n" + done +} + +echo Generating src/Makefile.am ... +inc_current='$(srcdir)' +inc_modules="$inc_current/modules" +inc_libraries="$inc_current/libraries" + +cat > src/Makefile.am << EOF +AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I$inc_libraries/enet/libenet/include \$(LOVE_INCLUDES) \$(FILE_OFFSET)\ + \$(SDL_CFLAGS) \$(lua_CFLAGS) \$(freetype2_CFLAGS)\ + \$(openal_CFLAGS) \$(devil_CFLAGS) \$(libmodplug_CFLAGS)\ + \$(vorbisfile_CFLAGS) +AUTOMAKE_OPTIONS = subdir-objects +SUBDIRS = +SUFFIXES = .lua .lua.h + +if LOVE_BUILD_EXE +# LÖVE executable +bin_PROGRAMS = love${love_suffix} +#love_LDFLAGS = +love${love_amsuffix}_LDADD = liblove${love_suffix}.la \$(lua_LIBS) +love${love_amsuffix}_SOURCES = love.cpp + +if LOVE_TARGET_OSX +love${love_amsuffix}_LIBTOOLFLAGS = --tag=OBJCXX +love${love_amsuffix}_SOURCES += \\ + ../platform/macosx/OSX.h \\ + ../platform/macosx/OSX.mm +else +love${love_amsuffix}_LIBTOOLFLAGS = --tag=CXX +endif +endif + +# Compile scripts +.lua.lua.h: + cd scripts; \ + \$(LUA_EXECUTABLE) auto.lua \$< + +# libLÖVE +lib_LTLIBRARIES = liblove${love_suffix}.la +liblove${love_amsuffix}_la_LDFLAGS = -module -export-dynamic \$(LDFLAGS) +liblove${love_amsuffix}_la_LIBADD = \ + \$(SDL_LIBS) \$(freetype2_LIBS) \$(lua_LIBS)\ + \$(openal_LIBS) \$(devil_LIBS) \$(libmodplug_LIBS)\ + \$(vorbisfile_LIBS) +EOF + +genmodules >> src/Makefile.am + +cat >> src/Makefile.am << EOF +if !LOVE_NOMPG123 +liblove${love_amsuffix}_la_SOURCES += \\ + ./modules/sound/lullaby/Mpg123Decoder.cpp \\ + ./modules/sound/lullaby/Mpg123Decoder.h +endif +EOF + +echo "src/Makefile.am is updated! ^.^" + +echo "Generating configure-modules.ac" +genflags > configure-modules.ac +cat >> configure-modules.ac << EOF +AC_SUBST([LOVE_SUFFIX], [${love_suffix}]) +EOF +echo "configure-modules.ac is updated! ^.^" diff --git a/platform/unix/get-libs b/platform/unix/get-libs deleted file mode 100644 index 91d108066..000000000 --- a/platform/unix/get-libs +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# Get required packages. -sudo apt-get -y install subversion build-essential automake autoconf libtool \ -liblua5.1-dev libopenal-dev libsdl1.2-dev libfreetype6-dev \ -libphysfs-dev libdevil-dev libtiff4-dev libmng-dev \ -liblcms1-dev ftp-upload libmpg123-dev libmodplug-dev libpng12-dev \ -libvorbis-dev diff --git a/platform/unix/love.1 b/platform/unix/love.1 new file mode 100644 index 000000000..0abaa5577 --- /dev/null +++ b/platform/unix/love.1 @@ -0,0 +1,26 @@ +.\" (c) 2008-2011 Miriam Ruiz +.\" +.\" This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damagesarising 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. +.\" +.\" Modifications: +.\" - Update version to 0.9 and remove reference to doc dir - Bart van Strien, 2013 +.TH "LÖVE" "1" "0.9" "" "" +.SH "NAME" +love \- 2D game development framework +.SH "SYNOPSIS" +.B love +<\fIgame.love\fR> +.SH "DESCRIPTION" +LÖVE was created to be a user\-friendly engine in which simple (or complicated) games could be made without having extensive knowledge of system or graphics functions and without having to dedicate time towards developing the same engine features time and time again. +.P +Developed with cross\-platform implementation in mind, it utilizes the latest open source libraries to deliver a similar game experience, independent of operating system. By relying on the Lua scripting language for game\-specific programming, it allows even the novice game creator to quickly and efficiently develop an idea into a fully working game. +.SH "SEE ALSO" +You can find more information at \fIhttp://love2d.org/\fR diff --git a/platform/unix/love.desktop b/platform/unix/love.desktop.in similarity index 84% rename from platform/unix/love.desktop rename to platform/unix/love.desktop.in index 65e141b48..3a9e2df12 100644 --- a/platform/unix/love.desktop +++ b/platform/unix/love.desktop.in @@ -2,10 +2,9 @@ Name=LÖVE Comment=The unquestionably awesome 2D game engine MimeType=application/x-love-game; -Exec=/usr/bin/love +Exec=@bindir@/love Type=Application Categories=Development;Game; Terminal=false -Icon=love.svg +Icon=love NoDisplay=true - diff --git a/platform/unix/app.svg b/platform/unix/love.svg similarity index 100% rename from platform/unix/app.svg rename to platform/unix/love.svg diff --git a/platform/unix/make-package b/platform/unix/make-package deleted file mode 100755 index b182657cd..000000000 --- a/platform/unix/make-package +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -echo -echo "Packing LÖVE to go v1.2" -echo - -arch="i386" - -if [ "`uname -m | grep -c -G x86_64`" != 0 ]; then - arch="amd64" -elif [ "`uname -m | grep -c -G ppc`" != 0 ]; then - arch="ppc" -fi - -if [ -z "$2" ]; then - echo "Syntax: ./make-package " - echo "Example: ./make-package deb 0.3.0-1" - echo "All files will be created in this folder." - echo - exit 0 -fi -case "$1" in - deb ) - strip ../../src/love - mkdir deb - mkdir deb/DEBIAN - cat debian | sed "s/%VERSION%/$2/" | sed "s/%ARCHITECTURE%/$arch/g" > deb/DEBIAN/tmp - cat deb/DEBIAN/tmp - sed "s/%INSTALLSIZE%/`ls -l ../../src/love | awk '{ sum += $5 } END { printf "%.2f", sum / 1000 }'`/" < deb/DEBIAN/tmp > deb/DEBIAN/control - rm deb/DEBIAN/tmp - cp postinst deb/DEBIAN/postinst - cp postrm deb/DEBIAN/postrm - mkdir deb/usr - mkdir deb/usr/bin - cp ../../src/love deb/usr/bin/love - mkdir deb/usr/share - mkdir deb/usr/share/mime - mkdir deb/usr/share/mime/packages - cp love.xml deb/usr/share/mime/packages - mkdir deb/usr/share/icons - mkdir deb/usr/share/icons/gnome - mkdir deb/usr/share/icons/gnome/scalable - mkdir deb/usr/share/icons/gnome/scalable/apps - cp app.svg deb/usr/share/icons/gnome/scalable/apps/love.svg - mkdir deb/usr/share/icons/gnome/scalable/mimetypes - cp game.svg deb/usr/share/icons/gnome/scalable/mimetypes/gnome-mime-application-x-love-game.svg - mkdir deb/usr/share/applications - cp love.desktop deb/usr/share/applications - dpkg -b deb love-$2.deb && \ - echo " * love-$2.deb created" - rm -rf deb - ;; - src ) - cd ../../../ - tar -czf love/platform/unix/love-$2-src.tar.gz --exclude=*.o --exclude=.* love/demos/* love/*.txt love/src/ && \ - echo " * love-$2-src.tar.gz created" - tar -cjf love/platform/unix/love-$2-src.tar.bz2 --exclude=*.o --exclude=.* love/demos/* love/*.txt love/src/ && \ - echo " * love-$2-src.tar.bz2 created" - zip -9q love/platform/unix/love-$2-src.zip love/*.txt love/demos/* `find love/src/* | grep -viE *.o` && \ - echo " * love-$2-src.zip created" - ;; - * ) - echo "Unknown package type: $1" - echo "Valid types: deb src" -esac -echo diff --git a/readme.md b/readme.md index 0252d80b5..3405073d1 100644 --- a/readme.md +++ b/readme.md @@ -10,15 +10,19 @@ Compilation ----------- ###Windows -Use the project files for Visual Studio 2010 located in the platform dir. +Follow the instructions at the [megasource][megasource] repository page. ###*nix -Run platform/unix/automagic, then run ./configure and make. +Run `platform/unix/automagic` from the repository root, then run ./configure and make. -###OSX -Use the XCode project in platform/macosx. + $ platform/unix/automagic + $ ./configure + $ make -For both Windows and OSX there are dependencies available [here][dependencies]. +###Mac OS X +Download the required frameworks from [here][dependencies] and place them in `/Library/Frameworks/`. + +Then use the Xcode project found at `platform/macosx/love.xcodeproj`. Repository information ---------------------- @@ -37,15 +41,14 @@ and there's a ppa for ubuntu, [ppa:bartbes/love-stable][stableppa]. There are also unstable/nightly builds: -- For windows they are located [here][winbuilds]. +- Most can be found [here][builds]. - For ubuntu linux they are in [ppa:bartbes/love-unstable][unstableppa] - For arch linux there's [love-hg][aur] in the AUR. -- For other linuxes and OSX there are currently no official builds. Dependencies ------------ -- SDL +- SDL2 - OpenGL - OpenAL - Lua / LuaJIT / LLVM-lua @@ -61,7 +64,8 @@ Dependencies [forums]: http://love2d.org/forums [irc]: irc://irc.oftc.net/love [dependencies]: http://love2d.org/sdk -[winbuilds]: http://love2d.org/builds +[megasource]: https://bitbucket.org/rude/megasource +[builds]: http://love2d.org/builds [stableppa]: https://launchpad.net/~bartbes/+archive/love-stable [unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable [aur]: http://aur.archlinux.org/packages.php?ID=35279 diff --git a/src/common/Data.h b/src/common/Data.h index 89068d8bc..ea31e69e7 100644 --- a/src/common/Data.h +++ b/src/common/Data.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/EnumMap.h b/src/common/EnumMap.h index 1b105f561..3586c35e3 100644 --- a/src/common/EnumMap.h +++ b/src/common/EnumMap.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/Exception.cpp b/src/common/Exception.cpp index 8b5e5956d..9f8a58b32 100644 --- a/src/common/Exception.cpp +++ b/src/common/Exception.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,8 +23,6 @@ #include -using namespace std; - namespace love { diff --git a/src/common/Exception.h b/src/common/Exception.h index 90dd3b49e..49d9961d3 100644 --- a/src/common/Exception.h +++ b/src/common/Exception.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/Matrix.cpp b/src/common/Matrix.cpp index 96cfcf654..a8a8c5e68 100644 --- a/src/common/Matrix.cpp +++ b/src/common/Matrix.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -104,7 +104,7 @@ void Matrix::setTranslation(float x, float y) void Matrix::setRotation(float rad) { setIdentity(); - float c = cos(rad), s = sin(rad); + float c = cosf(rad), s = sinf(rad); e[0] = c; e[4] = -s; e[1] = s; @@ -128,7 +128,7 @@ void Matrix::setShear(float kx, float ky) void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) { memset(e, 0, sizeof(float)*16); // zero out matrix - float c = cos(angle), s = sin(angle); + float c = cosf(angle), s = sinf(angle); // matrix multiplication carried out on paper: // |1 x| |c -s | |sx | | 1 ky | |1 -ox| // | 1 y| |s c | | sy | |kx 1 | | 1 -oy| @@ -181,7 +181,7 @@ void Matrix::shear(float kx, float ky) // | e2 e6 e10 e14 | // | e3 e7 e11 e15 | -void Matrix::transform(vertex *dst, const vertex *src, int size) const +void Matrix::transform(Vertex *dst, const Vertex *src, int size) const { for (int i = 0; i registry; + typedef std::map ModuleRegistry; + + // The registry must be dynamically managed, because some modules + // (the math module) are static globals that are not guaranteed to + // be destroyed before other static globals. + ModuleRegistry *registry = nullptr; + + ModuleRegistry ®istryInstance() + { + if (!registry) + registry = new ModuleRegistry; + + return *registry; + } + + void freeEmptyRegistry() + { + if (registry && registry->empty()) + { + delete registry; + registry = nullptr; + } + } + } // anonymous namespace namespace love { - void Module::registerInstance(Module *instance) + +Module::~Module() +{ + ModuleRegistry ®istry = registryInstance(); + + // We can't use the overridden Module::getName() in this destructor. + for (auto it = registry.begin(); it != registry.end(); ++it) { - if (instance == NULL) - throw Exception("Module instance is NULL"); - - std::string name(instance->getName()); - - std::map::iterator it = registry.find(name); - - if (registry.end() != it) + if (it->second == this) { - if (it->second == instance) - return; - throw Exception("Module %s already registered!", instance->getName()); + registry.erase(it); + break; } - - registry.insert(make_pair(name, instance)); } - Module *Module::getInstance(const char *name) + freeEmptyRegistry(); +} + +void Module::registerInstance(Module *instance) +{ + if (instance == nullptr) + throw Exception("Module instance is null"); + + std::string name(instance->getName()); + + ModuleRegistry ®istry = registryInstance(); + + auto it = registry.find(name); + + if (it != registry.end()) { - std::map::iterator it = registry.find(std::string(name)); - - if (registry.end() == it) - return NULL; - - return it->second; + if (it->second == instance) + return; + throw Exception("Module %s already registered!", instance->getName()); } -} // namespace love + + registry.insert(make_pair(name, instance)); +} + +Module *Module::getInstance(const std::string &name) +{ + ModuleRegistry ®istry = registryInstance(); + + auto it = registry.find(name); + + if (registry.end() == it) + return nullptr; + + return it->second; +} + +Module *Module::findInstance(const std::string &name) +{ + ModuleRegistry ®istry = registryInstance(); + + for (auto it = registry.begin(); it != registry.end(); ++it) + { + if (it->first.find(name) == 0) + return it->second; + } + + return nullptr; +} + +} // love diff --git a/src/common/Module.h b/src/common/Module.h index 96eecdf8d..feea22af8 100644 --- a/src/common/Module.h +++ b/src/common/Module.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,7 +22,6 @@ #define LOVE_MODULE_H // LOVE -#include "runtime.h" #include "Exception.h" #include "Object.h" @@ -38,7 +37,7 @@ public: /** * Destructor. **/ - virtual ~Module() {}; + virtual ~Module(); /** * Gets the name of the module. This is used in case of errors @@ -59,9 +58,18 @@ public: * 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. + * @return Module instance or NULL if the module is not registered. */ - static Module *getInstance(const char *name); + static Module *getInstance(const std::string &name); + + /** + * Find the first module instance from the internal registry whose name + * starts with the supplied name. May return NULL if module is not + * registered or the supplied name is not part of any module name. + * @param name The partial name of the module. + * @return Module instance or NULL if the module is not registered. + **/ + static Module *findInstance(const std::string &name); }; // Module diff --git a/src/common/Object.cpp b/src/common/Object.cpp index 9a0421394..577f7dfa2 100644 --- a/src/common/Object.cpp +++ b/src/common/Object.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/Object.h b/src/common/Object.h index e062fb478..348da1b63 100644 --- a/src/common/Object.h +++ b/src/common/Object.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -65,6 +65,33 @@ public: **/ virtual void release(); + /** + * Meant to be used as a temporary object. Facilitates safer and cleaner + * code to release objects by doing so when the AutoRelease object is + * destroyed (e.g. goes out of scope.) + **/ + class AutoRelease + { + public: + + AutoRelease(Object *obj) + : object(obj) + { + } + + ~AutoRelease() + { + if (object) + object->release(); + } + + private: + + AutoRelease() {} + Object *object; + + }; // AutoRelease + private: // The reference count. diff --git a/src/common/Reference.cpp b/src/common/Reference.cpp index 89c4bc2ed..38e28e099 100644 --- a/src/common/Reference.cpp +++ b/src/common/Reference.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,12 +26,14 @@ namespace love const char REFERENCE_TABLE_NAME[] = "love-references"; Reference::Reference() - : L(0), idx(LUA_REFNIL) + : L(0) + , idx(LUA_REFNIL) { } Reference::Reference(lua_State *L) - : L(0), idx(LUA_REFNIL) + : L(L) + , idx(LUA_REFNIL) { ref(L); } diff --git a/src/common/Reference.h b/src/common/Reference.h index 59cc9a72e..5d7341b20 100644 --- a/src/common/Reference.h +++ b/src/common/Reference.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/StringMap.h b/src/common/StringMap.h index 682626519..116a45658 100644 --- a/src/common/StringMap.h +++ b/src/common/StringMap.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -70,7 +70,7 @@ public: for (unsigned i = 0; i < MAX; ++i) { - unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? + unsigned str_i = (str_hash + i) % MAX; if (!records[str_i].set) return false; diff --git a/src/common/Variant.cpp b/src/common/Variant.cpp index 15e55d59d..f37e5c7b6 100644 --- a/src/common/Variant.cpp +++ b/src/common/Variant.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,7 +26,7 @@ namespace love extern StringMap types; -love::Type extractudatatype(lua_State *L, int idx) +static love::Type extractudatatype(lua_State *L, int idx) { Type t = INVALID_ID; if (!lua_isuserdata(L, idx)) @@ -42,21 +42,39 @@ love::Type extractudatatype(lua_State *L, int idx) return t; } -Variant::Variant(bool boolean) +static inline void delete_table(std::vector > *table) +{ + while (!table->empty()) + { + std::pair &kv = table->back(); + kv.first->release(); + kv.second->release(); + table->pop_back(); + } + delete table; +} + +Variant::Variant() + : type(NIL) + , data() +{ +} + +Variant::Variant(bool boolean) + : type(BOOLEAN) { - type = BOOLEAN; data.boolean = boolean; } Variant::Variant(double number) + : type(NUMBER) { - type = NUMBER; data.number = number; } Variant::Variant(const char *string, size_t len) + : type(STRING) { - type = STRING; char *buf = new char[len+1]; memset(buf, 0, len+1); memcpy(buf, string, len); @@ -65,21 +83,21 @@ Variant::Variant(const char *string, size_t len) } Variant::Variant(char c) + : type(CHARACTER) { - type = CHARACTER; data.character = c; } Variant::Variant(void *userdata) + : type(LUSERDATA) { - type = LUSERDATA; data.userdata = userdata; } Variant::Variant(love::Type udatatype, void *userdata) + : type(FUSERDATA) + , udatatype(udatatype) { - type = FUSERDATA; - this->udatatype = udatatype; if (udatatype != INVALID_ID) { Proxy *p = (Proxy *) userdata; @@ -91,6 +109,13 @@ Variant::Variant(love::Type udatatype, void *userdata) data.userdata = userdata; } +// Variant gets ownership of the vector. +Variant::Variant(std::vector > *table) + : type(TABLE) +{ + data.table = table; +} + Variant::~Variant() { switch (type) @@ -101,16 +126,21 @@ Variant::~Variant() case FUSERDATA: ((love::Object *) data.userdata)->release(); break; + case TABLE: + delete_table(data.table); default: break; } } -Variant *Variant::fromLua(lua_State *L, int n) +Variant *Variant::fromLua(lua_State *L, int n, bool allowTables) { Variant *v = NULL; size_t len; const char *str; + if (n < 0) // Fix the stack position, we might modify it later + n += lua_gettop(L) + 1; + switch (lua_type(L, n)) { case LUA_TBOOLEAN: @@ -129,6 +159,45 @@ Variant *Variant::fromLua(lua_State *L, int n) case LUA_TUSERDATA: v = new Variant(extractudatatype(L, n), lua_touserdata(L, n)); break; + case LUA_TNIL: + v = new Variant(); + break; + case LUA_TTABLE: + if (allowTables) + { + bool success = true; + std::vector > *table = new std::vector >(); + lua_pushnil(L); + while (lua_next(L, n)) + { + Variant *key = fromLua(L, -2, false); + if (!key) + { + success = false; + lua_pop(L, 2); + break; + } + + Variant *value = fromLua(L, -1, false); + if (!value) + { + delete key; + success = false; + lua_pop(L, 2); + break; + } + + table->push_back(std::make_pair(key, value)); + + lua_pop(L, 1); + } + + if (success) + v = new Variant(table); + else + delete_table(table); + } + break; } return v; } @@ -158,7 +227,7 @@ void Variant::toLua(lua_State *L) const char *name = NULL; love::types.find(udatatype, name); ((love::Object *) data.userdata)->retain(); - luax_newtype(L, name, flags, data.userdata); + luax_pushtype(L, name, flags, (love::Object *) data.userdata); } else lua_pushlightuserdata(L, data.userdata); @@ -166,6 +235,17 @@ void Variant::toLua(lua_State *L) // sadly, however, it's the most // I can do (at the moment). break; + case TABLE: + lua_newtable(L); + for (size_t i = 0; i < data.table->size(); ++i) + { + std::pair &kv = data.table->at(i); + kv.first->toLua(L); + kv.second->toLua(L); + lua_settable(L, -3); + } + break; + case NIL: default: lua_pushnil(L); break; diff --git a/src/common/Variant.h b/src/common/Variant.h index 3bc792852..4592a2fa9 100644 --- a/src/common/Variant.h +++ b/src/common/Variant.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -25,6 +25,8 @@ #include "common/Object.h" #include +#include +#include namespace love { @@ -33,15 +35,17 @@ class Variant : public love::Object { public: + Variant(); Variant(bool boolean); Variant(double number); Variant(const char *string, size_t len); Variant(char c); Variant(void *userdata); Variant(love::Type udatatype, void *userdata); + Variant(std::vector > *table); virtual ~Variant(); - static Variant *fromLua(lua_State *L, int n); + static Variant *fromLua(lua_State *L, int n, bool allowTables = true); void toLua(lua_State *L); private: @@ -53,7 +57,9 @@ private: CHARACTER, STRING, LUSERDATA, - FUSERDATA + FUSERDATA, + NIL, + TABLE } type; union { @@ -66,6 +72,7 @@ private: size_t len; } string; void *userdata; + std::vector > *table; } data; love::Type udatatype; bits flags; diff --git a/src/common/Vector.cpp b/src/common/Vector.cpp index 41c7f56c4..8e0ae515b 100644 --- a/src/common/Vector.cpp +++ b/src/common/Vector.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/Vector.h b/src/common/Vector.h index 01575888e..8342af987 100644 --- a/src/common/Vector.h +++ b/src/common/Vector.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -59,24 +59,33 @@ public: * Gets the length of the Vector. * @return The length of the Vector. * - * This method requires sqrt() and should be used + * This method requires sqrtf() and should be used * carefully. **/ float getLength() const; /** * Normalizes the Vector. + * @param length Desired length of the vector. * @return The old length of the Vector. **/ - float normalize(); + float normalize(float length = 1.0); /** - * Gets a normal to the Vector. + * Gets a vector perpendicular to the Vector. + * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) * @return A normal to the Vector. **/ - Vector getNormal() const; + /** + * Gets a vector perpendicular to the Vector. + * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) + * @param scale factor to apply. + * @return A normal to the Vector. + **/ + Vector getNormal(float scale) const; + /** * Adds a Vector to this Vector. * @param v The Vector we want to add to this Vector. @@ -164,13 +173,13 @@ public: /** * Sets the x value of the Vector. - * @param The x value of the Vector. + * @param x The x value of the Vector. **/ void setX(float x); /** * Sets the x value of the Vector. - * @param The x value of the Vector. + * @param y The x value of the Vector. **/ void setY(float y); @@ -178,7 +187,7 @@ public: inline float Vector::getLength() const { - return sqrt(x*x + y*y); + return sqrtf(x*x + y*y); } inline Vector Vector::getNormal() const @@ -186,15 +195,20 @@ inline Vector Vector::getNormal() const return Vector(-y, x); } -inline float Vector::normalize() +inline Vector Vector::getNormal(float scale) const +{ + return Vector(-y * scale, x * scale); +} + +inline float Vector::normalize(float length) { - float len = getLength(); + float length_current = getLength(); - if (len > 0) - (*this) /= len; + if (length_current > 0) + (*this) *= length / length_current; - return len; + return length_current; } /** diff --git a/src/common/b64.cpp b/src/common/b64.cpp index 338833acc..c40091879 100644 --- a/src/common/b64.cpp +++ b/src/common/b64.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -25,7 +25,7 @@ namespace love static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; -void b64_decode_block(char in[4], char out[3]) +static void b64_decode_block(char in[4], char out[3]) { out[0] = (char)(in[0] << 2 | in[1] >> 4); out[1] = (char)(in[1] << 4 | in[2] >> 2); @@ -39,7 +39,7 @@ char *b64_decode(const char *src, int slen, int &size) char *dst = new char[size]; char *d = dst; - char in[4], out[3], v; + char in[4] = {0}, out[3], v; int i, len, pos = 0; while (pos <= slen) diff --git a/src/common/b64.h b/src/common/b64.h index e0c82d635..99685cdac 100644 --- a/src/common/b64.h +++ b/src/common/b64.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/config.h b/src/common/config.h index b0109462d..063b9611c 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -30,9 +30,7 @@ #endif #if defined(__APPLE__) # define LOVE_MACOSX 1 -#endif -#if defined(macintosh) -# define LOVE_MACOS 1 +# include #endif // Endianness. @@ -74,7 +72,7 @@ #endif #if defined(LOVE_MACOSX) -# define LOVE_LEGENDARY_LIBSTDCXX_HACK +# define LOVE_LEGENDARY_APP_ARGV_HACK #endif // Autotools config.h @@ -88,6 +86,47 @@ # undef LOVE_BIG_ENDIAN # define LOVE_LITTLE_ENDIAN 1 # endif +#else +# define LOVE_ENABLE_AUDIO +# define LOVE_ENABLE_AUDIO_NULL +# define LOVE_ENABLE_AUDIO_OPENAL +# define LOVE_ENABLE_BOX2D +# define LOVE_ENABLE_DDSPARSE +# define LOVE_ENABLE_ENET +# define LOVE_ENABLE_EVENT +# define LOVE_ENABLE_EVENT_SDL +# define LOVE_ENABLE_FILESYSTEM +# define LOVE_ENABLE_FILESYSTEM_PHYSFS +# define LOVE_ENABLE_FONT +# define LOVE_ENABLE_FONT_FREETYPE +# define LOVE_ENABLE_GRAPHICS +# define LOVE_ENABLE_GRAPHICS_OPENGL +# define LOVE_ENABLE_IMAGE +# define LOVE_ENABLE_IMAGE_MAGPIE +# define LOVE_ENABLE_JOYSTICK +# define LOVE_ENABLE_JOYSTICK_SDL +# define LOVE_ENABLE_KEYBOARD +# define LOVE_ENABLE_KEYBOARD_SDL +# define LOVE_ENABLE_LOVE +# define LOVE_ENABLE_LUASOCKET +# define LOVE_ENABLE_MATH +# define LOVE_ENABLE_MOUSE +# define LOVE_ENABLE_MOUSE_SDL +# define LOVE_ENABLE_NOISE1234 +# define LOVE_ENABLE_PHYSICS +# define LOVE_ENABLE_PHYSICS_BOX2D +# define LOVE_ENABLE_SOUND +# define LOVE_ENABLE_SOUND_LULLABY +# define LOVE_ENABLE_SYSTEM +# define LOVE_ENABLE_SYSTEM_SDL +# define LOVE_ENABLE_THREAD +# define LOVE_ENABLE_THREAD_SDL +# define LOVE_ENABLE_TIMER +# define LOVE_ENABLE_TIMER_SDL +# define LOVE_ENABLE_UTF8 +# define LOVE_ENABLE_WINDOW +# define LOVE_ENABLE_WINDOW_SDL +# define LOVE_ENABLE_WUFF #endif #endif // LOVE_CONFIG_H diff --git a/src/common/delay.cpp b/src/common/delay.cpp index 95f0c8886..932231e6f 100644 --- a/src/common/delay.cpp +++ b/src/common/delay.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,7 +19,8 @@ **/ #include "delay.h" -#include + +#include namespace love { diff --git a/src/common/delay.h b/src/common/delay.h index 27d024177..aa574ca30 100644 --- a/src/common/delay.h +++ b/src/common/delay.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,6 +26,6 @@ namespace love void delay(unsigned int ms); -}; // namespace love +} // namespace love #endif // DELAY_H_ diff --git a/src/common/int.h b/src/common/int.h index 3769370bb..ac57f89ec 100644 --- a/src/common/int.h +++ b/src/common/int.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/math.cpp b/src/common/math.cpp deleted file mode 100644 index 41c881518..000000000 --- a/src/common/math.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "math.h" -#include -#include - -namespace -{ - // The Box–Muller 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::infinity(); -} - -namespace love -{ - -float random_normal(float o) -{ - // number in cache? - if (last_randnormal != std::numeric_limits::infinity()) - { - float r = last_randnormal; - last_randnormal = std::numeric_limits::infinity(); - return r * o; - } - - // else: generate numbers using the Box-Muller transform - float a = sqrt(-2.0f * log(1. - random())); - float b = float(LOVE_M_PI) * 2.0f * (1. - random()); - last_randnormal = a * cos(b); - return a * sin(b) * o; -} - -} // namespace love diff --git a/src/common/math.h b/src/common/math.h index 611aba010..7fe57a217 100644 --- a/src/common/math.h +++ b/src/common/math.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -61,11 +61,19 @@ namespace love { -struct vertex +struct Vertex { - unsigned char r, g, b, a; float x, y; float s, t; + unsigned char r, g, b, a; +}; + +struct Triangle +{ + Triangle(const Vertex &x, const Vertex &y, const Vertex &z) + : a(x), b(y), c(z) + {} + Vertex a, b, c; }; inline int next_p2(int x) @@ -81,42 +89,6 @@ inline float next_p2(float x) return static_cast(next_p2(static_cast(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 #endif // LOVE_MATH_H diff --git a/src/common/runtime.cpp b/src/common/runtime.cpp index 84d4faae0..55c216adb 100644 --- a/src/common/runtime.cpp +++ b/src/common/runtime.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,6 +18,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +#include "config.h" #include "runtime.h" // LOVE @@ -27,14 +28,17 @@ #include "StringMap.h" #include -// STD +// C++ +#include #include +#include namespace love { static thread::Mutex *gcmutex = 0; void *_gcmutex = 0; + /** * Called when an object is collected. The object is released * once in this function, possibly deleting it. @@ -46,13 +50,21 @@ static int w__gc(lua_State *L) gcmutex = thread::newMutex(); _gcmutex = (void *) gcmutex; } + Proxy *p = (Proxy *)lua_touserdata(L, 1); Object *t = (Object *)p->data; - if (p->own) - { - thread::Lock lock(gcmutex); + + thread::Lock lock(gcmutex); + + int numretains = p->retains; + if (numretains >= 0) + numretains = std::min(numretains, t->getReferenceCount()); + + for (int i = numretains; i > 0; i--) t->release(); - } + + // Signal that this Proxy is dead. + p->retains = -1; return 0; } @@ -78,7 +90,7 @@ static int w__eq(lua_State *L) return 1; } -Reference *luax_refif (lua_State *L, int type) +Reference *luax_refif(lua_State *L, int type) { Reference *r = 0; @@ -130,11 +142,39 @@ std::string luax_checkstring(lua_State *L, int idx) return std::string(str, len); } -void luax_pushstring(lua_State *L, std::string str) +void luax_pushstring(lua_State *L, const std::string &str) { lua_pushlstring(L, str.data(), str.size()); } +bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue) +{ + lua_getfield(L, table_index, key); + + bool retval; + if (lua_isnoneornil(L, -1)) + retval = defaultValue; + else + retval = lua_toboolean(L, -1); + + lua_pop(L, 1); + return retval; +} + +int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue) +{ + lua_getfield(L, table_index, key); + + int retval; + if (!lua_isnumber(L, -1)) + retval = defaultValue; + else + retval = (int) lua_tointeger(L, -1); + + lua_pop(L, 1); + return retval; +} + int luax_assert_argc(lua_State *L, int min) { int argc = lua_gettop(L); @@ -151,20 +191,44 @@ int luax_assert_argc(lua_State *L, int min, int max) return 0; } -int luax_assert_function(lua_State *L, int n) +int luax_assert_function(lua_State *L, int idx) { - if (!lua_isfunction(L, n)) + if (!lua_isfunction(L, idx)) return luaL_error(L, "Argument must be of type \"function\"."); return 0; } +int luax_assert_nilerror(lua_State *L, int idx) +{ + if (lua_isnoneornil(L, idx)) + { + if (lua_isstring(L, idx + 1)) + return luaL_error(L, lua_tostring(L, idx + 1)); + else + return luaL_error(L, "assertion failed!"); + } + return 0; +} + +void luax_setfuncs(lua_State *L, const luaL_Reg *l) +{ + if (l == 0) + return; + + for (; l->name != 0; l++) + { + lua_pushcfunction(L, l->func); + lua_setfield(L, -2, l->name); + } +} + int luax_register_module(lua_State *L, const WrappedModule &m) { // Put a reference to the C++ module in Lua. - luax_getregistry(L, REGISTRY_MODULES); + luax_insistregistry(L, REGISTRY_MODULES); Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); - p->own = true; + p->retains = 1; p->data = m.module; p->flags = m.flags; @@ -185,7 +249,8 @@ int luax_register_module(lua_State *L, const WrappedModule &m) lua_newtable(L); // Register all the functions. - luaL_register(L, 0, m.functions); + if (m.functions != 0) + luax_setfuncs(L, m.functions); // Register types. if (m.types != 0) @@ -214,6 +279,36 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name) int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f) { + // Verify that this type name has a matching Type ID and type name mapping. + love::Type ltype; + if (!love::getType(tname, ltype)) + printf("Missing type entry for type name: %s\n", tname); + + // Get the place for storing and re-using instantiated love types. + luax_getregistry(L, REGISTRY_TYPES); + + // Create registry._lovetypes if it doesn't exist yet. + if (!lua_istable(L, -1)) + { + lua_newtable(L); + lua_replace(L, -2); + + // Create a metatable. + lua_newtable(L); + + // metatable.__mode = "v". Weak userdata values. + lua_pushliteral(L, "v"); + lua_setfield(L, -2, "__mode"); + + // setmetatable(newtable, metatable) + lua_setmetatable(L, -2); + + // registry._lovetypes = newtable + lua_setfield(L, LUA_REGISTRYINDEX, "_lovetypes"); + } + else + lua_pop(L, 1); + luaL_newmetatable(L, tname); // m.__index = m @@ -243,7 +338,7 @@ int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f) lua_setfield(L, -2, "typeOf"); if (f != 0) - luaL_register(L, 0, f); + luax_setfuncs(L, f); lua_pop(L, 1); // Pops metatable. return 0; @@ -283,6 +378,13 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos) lua_getfield(L, -1, "loaders"); + // Lua 5.2 renamed package.loaders to package.searchers. + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_getfield(L, -1, "searchers"); + } + if (lua_isnil(L, -1)) return luaL_error(L, "Can't register searcher: package.loaders table does not exist."); @@ -292,18 +394,74 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos) return 0; } -void luax_newtype(lua_State *L, const char *name, bits flags, void *data, bool own) +void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own) { Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); - u->data = data; + u->data = (void *) data; u->flags = flags; - u->own = own; + u->retains = own ? 1 : 0; luaL_newmetatable(L, name); lua_setmetatable(L, -2); } +void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own) +{ + // Fetch the registry table of instantiated types. + luax_getregistry(L, REGISTRY_TYPES); + + // The table might not exist - it should be insisted in luax_register_type. + if (!lua_istable(L, -1)) + { + lua_pop(L, 1); + return luax_rawnewtype(L, name, flags, data, own); + } + + // Get the value of lovetypes[data] on the stack. + lua_pushlightuserdata(L, (void *) data); + lua_gettable(L, -2); + + // If the Proxy userdata isn't in the instantiated types table yet, add it. + if (lua_type(L, -1) != LUA_TUSERDATA) + { + lua_pop(L, 1); + + luax_rawnewtype(L, name, flags, data, own); + + lua_pushlightuserdata(L, (void *) data); + lua_pushvalue(L, -2); + + // lovetypes[data] = Proxy. + lua_settable(L, -4); + + // Remove the lovetypes table from the stack. + lua_remove(L, -2); + + // The Proxy userdata remains at the top of the stack. + return; + } + + // Remove the lovetypes table from the stack. + lua_remove(L, -2); + + // If the object should be released on GC and we already have a stored + // Proxy, we should tell the Proxy that the object was retained again. + if (own) + { + Proxy *p = (Proxy *) lua_touserdata(L, -1); + + thread::EmptyLock lock; + if (gcmutex) + lock.setLock(gcmutex); + + if (p->retains >= 0) + ++(p->retains); + } + + // Keep the Proxy userdata on the stack. +} + bool luax_istype(lua_State *L, int idx, love::bits type) { if (lua_isuserdata(L, idx) == 0) @@ -331,7 +489,9 @@ int luax_convobj(lua_State *L, int idx, const char *mod, const char *fn) // Convert string to a file. luax_getfunction(L, mod, fn); lua_pushvalue(L, idx); // The initial argument. - lua_call(L, 1, 1); // Call the function, one arg, one return value. + lua_call(L, 1, 2); // Call the function, one arg, one return value (plus optional errstring.) + luax_assert_nilerror(L, -2); // Make sure the function returned something. + lua_pop(L, 1); // Pop the second return value now that we don't need it. lua_replace(L, idx); // Replace the initial argument with the new object. return 0; } @@ -343,7 +503,9 @@ int luax_convobj(lua_State *L, int idxs[], int n, const char *mod, const char *f { lua_pushvalue(L, idxs[i]); // The arguments. } - lua_call(L, n, 1); // Call the function, n args, one return value. + lua_call(L, n, 2); // Call the function, n args, one return value (plus optional errstring.) + luax_assert_nilerror(L, -2); // Make sure the function returned something. + lua_pop(L, 1); // Pop the second return value now that we don't need it. lua_replace(L, idxs[0]); // Replace the initial argument with the new object. return 0; } @@ -372,16 +534,6 @@ int luax_pconvobj(lua_State *L, int idxs[], int n, const char *mod, const char * return ret; } -int luax_strtofile(lua_State *L, int idx) -{ - return luax_convobj(L, idx, "filesystem", "newFile"); -} - -int luax_filetodata(lua_State *L, int idx) -{ - return luax_convobj(L, idx, "filesystem", "read"); -} - int luax_insist(lua_State *L, int idx, const char *k) { // Convert to absolute index if necessary. @@ -429,7 +581,20 @@ int luax_insistlove(lua_State *L, const char *k) return 1; } -int luax_getregistry(lua_State *L, Registry r) +int luax_getlove(lua_State *L, const char *k) +{ + lua_getglobal(L, "love"); + + if (!lua_isnil(L, -1)) + { + lua_getfield(L, -1, k); + lua_replace(L, -2); + } + + return 1; +} + +int luax_insistregistry(lua_State *L, Registry r) { switch (r) { @@ -437,11 +602,57 @@ int luax_getregistry(lua_State *L, Registry r) return luax_insistlove(L, "_gc"); case REGISTRY_MODULES: return luax_insistlove(L, "_modules"); + case REGISTRY_TYPES: + return luax_insist(L, LUA_REGISTRYINDEX, "_lovetypes"); default: return luaL_error(L, "Attempted to use invalid registry."); } } +int luax_getregistry(lua_State *L, Registry r) +{ + switch (r) + { + case REGISTRY_GC: + return luax_getlove(L, "_gc"); + case REGISTRY_MODULES: + return luax_getlove(L, "_modules"); + case REGISTRY_TYPES: + lua_getfield(L, LUA_REGISTRYINDEX, "_lovetypes"); + return 1; + default: + return luaL_error(L, "Attempted to use invalid registry."); + } +} + +extern "C" int luax_typerror(lua_State *L, int narg, const char *tname) +{ + int argtype = lua_type(L, narg); + const char *argtname = 0; + + // We want to use the love type name for userdata, if possible. + if (argtype == LUA_TUSERDATA && luaL_getmetafield(L, narg, "__tostring") != 0) + { + lua_pushvalue(L, narg); + if (lua_pcall(L, 1, 1, 0) == 0 && lua_type(L, -1) == LUA_TSTRING) + { + argtname = lua_tostring(L, -1); + + // Non-love userdata might have a tostring metamethod which doesn't + // describe its type, so we only use __tostring for love types. + love::Type t; + if (!love::getType(argtname, t)) + argtname = 0; + } + } + + if (argtname == 0) + argtname = lua_typename(L, argtype); + + const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, argtname); + return luaL_argerror(L, narg, msg); +} + StringMap::Entry typeEntries[] = { {"Invalid", INVALID_ID}, @@ -460,15 +671,26 @@ StringMap::Entry typeEntries[] = // Graphics {"Drawable", GRAPHICS_DRAWABLE_ID}, + {"Texture", GRAPHICS_TEXTURE_ID}, {"Image", GRAPHICS_IMAGE_ID}, {"Quad", GRAPHICS_QUAD_ID}, {"Font", GRAPHICS_FONT_ID}, {"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID}, {"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID}, {"Canvas", GRAPHICS_CANVAS_ID}, + {"Shader", GRAPHICS_SHADER_ID}, + {"Mesh", GRAPHICS_MESH_ID}, // Image {"ImageData", IMAGE_IMAGE_DATA_ID}, + {"CompressedData", IMAGE_COMPRESSED_DATA_ID}, + + // Joystick + {"Joystick", JOYSTICK_JOYSTICK_ID}, + + // Math + {"RandomGenerator", MATH_RANDOM_GENERATOR_ID}, + {"BezierCurve", MATH_BEZIER_CURVE_ID}, // Audio {"Source", AUDIO_SOURCE_ID}, @@ -477,13 +699,19 @@ StringMap::Entry typeEntries[] = {"SoundData", SOUND_SOUND_DATA_ID}, {"Decoder", SOUND_DECODER_ID}, + // Mouse + {"Cursor", MOUSE_CURSOR_ID}, + // Physics {"World", PHYSICS_WORLD_ID}, {"Contact", PHYSICS_CONTACT_ID}, {"Body", PHYSICS_BODY_ID}, + {"Fixture", PHYSICS_FIXTURE_ID}, {"Shape", PHYSICS_SHAPE_ID}, {"CircleShape", PHYSICS_CIRCLE_SHAPE_ID}, {"PolygonShape", PHYSICS_POLYGON_SHAPE_ID}, + {"EdgeShape", PHYSICS_EDGE_SHAPE_ID}, + {"ChainShape", PHYSICS_CHAIN_SHAPE_ID}, {"Joint", PHYSICS_JOINT_ID}, {"MouseJoint", PHYSICS_MOUSE_JOINT_ID}, {"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID}, @@ -491,6 +719,11 @@ StringMap::Entry typeEntries[] = {"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID}, {"PulleyJoint", PHYSICS_PULLEY_JOINT_ID}, {"GearJoint", PHYSICS_GEAR_JOINT_ID}, + {"FrictionJoint", PHYSICS_FRICTION_JOINT_ID}, + {"WeldJoint", PHYSICS_WELD_JOINT_ID}, + {"RopeJoint", PHYSICS_ROPE_JOINT_ID}, + {"WheelJoint", PHYSICS_WHEEL_JOINT_ID}, + {"MotorJoint", PHYSICS_MOTOR_JOINT_ID}, // Thread {"Thread", THREAD_THREAD_ID}, @@ -498,12 +731,23 @@ StringMap::Entry typeEntries[] = // The modules themselves. Only add abstracted modules here. {"filesystem", MODULE_FILESYSTEM_ID}, + {"graphics", MODULE_GRAPHICS_ID}, {"image", MODULE_IMAGE_ID}, {"sound", MODULE_SOUND_ID}, }; StringMap types(typeEntries, sizeof(typeEntries)); +bool getType(const char *in, love::Type &out) +{ + return types.find(in, out); +} + +bool getType(love::Type in, const char *&out) +{ + return types.find(in, out); +} + Type luax_type(lua_State *L, int idx) { Type t = INVALID_ID; diff --git a/src/common/runtime.h b/src/common/runtime.h index db3bb4fd1..8f99f259f 100644 --- a/src/common/runtime.h +++ b/src/common/runtime.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,9 +23,11 @@ // LOVE #include "types.h" +#include "Object.h" // Lua extern "C" { + #define LUA_COMPAT_ALL #include #include #include @@ -40,16 +42,16 @@ class Reference; // Exposed mutex of the GC extern void *_gcmutex; -extern unsigned int _gcthread; /** * Registries represent special tables which can be accessed with - * luax_getregistry. + * luax_insistregistry and luax_getregistry. **/ enum Registry { REGISTRY_GC = 1, REGISTRY_MODULES, + REGISTRY_TYPES }; /** @@ -63,11 +65,11 @@ struct Proxy // Holds type information (see types.h). bits flags; - // The light userdata. + // The light userdata (pointer to the love::Object). void *data; - // True if Lua should delete on GC. - bool own; + // The number of times release() should be called on GC. + int retains; }; /** @@ -98,7 +100,7 @@ struct WrappedModule * * In any case, the top stack element is popped, regardless of its type. **/ -Reference *luax_refif (lua_State *L, int type); +Reference *luax_refif(lua_State *L, int type); /** * Prints the current contents of the stack. Only useful for debugging. @@ -156,7 +158,33 @@ std::string luax_checkstring(lua_State *L, int idx); * @param L The Lua state. * @param str The string to push. **/ -void luax_pushstring(lua_State *L, std::string str); +void luax_pushstring(lua_State *L, const std::string &str); + + +bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue); +int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue); + +/** + * Convert the value at the specified index to an Lua number, and then + * convert to a float. + * + * @param L The Lua state. + * @param idx The index on the stack. + */ +inline float luax_tofloat(lua_State *L, int idx) +{ + return static_cast(lua_tonumber(L, idx)); +} + +/** + * Like luax_tofloat, but checks that the value is a number. + * + * @see luax_tofloat + */ +inline float luax_checkfloat(lua_State *L, int idx) +{ + return static_cast(luaL_checknumber(L, idx)); +} /** * Require at least 'min' number of items on the stack. @@ -182,6 +210,22 @@ int luax_assert_argc(lua_State *L, int min, int max); **/ int luax_assert_function(lua_State *L, int idx); +/** + * Require that the value at idx is not nil. If it is, the function throws an + * error using an optional error string at idx+1. + * @param L The Lua state. + * @param idx The index on the stack. + **/ +int luax_assert_nilerror(lua_State *L, int idx); + +/** + * Registers all functions in the array l (see luaL_Reg) into the table at the + * top of the stack. + * Similar to Lua 5.2's luaL_setfuncs without the upvalues, and to Lua 5.1's + * luaL_register without the library name. + **/ +void luax_setfuncs(lua_State *L, const luaL_Reg *l); + /** * Register a module in the love table. The love table will be created if it does not exist. * @param L The Lua state. @@ -222,14 +266,29 @@ int luax_table_insert(lua_State *L, int tindex, int vindex, int pos = -1); int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1); /** - * Creates a new Lua-accessible object of the given type, and put it on the stack. + * Pushes a Lua representation of the given object onto the stack, creating and + * storing the Lua representation in a weak table if it doesn't exist yet. * @param L The Lua state. - * @param name The name of the type. This must match the used earlier with luax_register_type. - * @param flags The type information. + * @param name The name of the type. This must match the name used with luax_register_type. + * @param flags The type information of the object. * @param data The pointer to the actual object. - * @own Set this to true (default) if the object should be released upon garbage collection. + * @param own Set this to true (default) if the object should be released upon garbage collection. **/ -void luax_newtype(lua_State *L, const char *name, bits flags, void *data, bool own = true); +void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true); + +/** + * Creates a new Lua representation of the given object *without* checking if it + * exists yet, and *without* storing it in a weak table. + * This should only be used when performance is an extreme concern and the + * object is not ever expected to be pushed to Lua again, as it prevents the + * Lua-side objects from working in all cases when used as keys in tables. + * @param L The Lua state. + * @param name The name of the type. This must match the name used with luax_register_type. + * @param flags The type information of the object. + * @param data The pointer to the actual object. + * @param own Set this to true (default) if the object should be released upon garbage collection. + **/ +void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true); /** * Checks whether the value at idx is a certain type. @@ -305,50 +364,30 @@ int luax_insistglobal(lua_State *L, const char *k); int luax_insistlove(lua_State *L, const char *k); /** - * Gets (creates if needed) the specified Registry, and puts it on top - * of the stack. + * Pushes the table 'k' in the love table onto the stack. Pushes nil if the + * table doesn't exist. + * @param k The name of the table we want to get. + **/ +int luax_getlove(lua_State *L, const char *k); + +/** + * Gets (creates if needed) the specified Registry, and pushes it into the + * stack. + * @param L The Lua state. + * @param r The Registry to get. + **/ +int luax_insistregistry(lua_State *L, Registry r); + +/** + * Gets the specified Registry, and pushes it onto the stack. Pushes nil if the + * registry hasn't been created (see luax_insistregistry.) * @param L The Lua state. * @param r The Registry to get. **/ int luax_getregistry(lua_State *L, Registry r); -Type luax_type(lua_State *L, int idx); - -/** - * Convert the value at the specified index to an Lua number, and then - * convert to a float. - * - * @param L The Lua state. - * @param idx The index on the stack. - */ -inline float luax_tofloat(lua_State *L, int idx) -{ - return static_cast(lua_tonumber(L, idx)); -} - -/** - * Like luax_tofloat, but checks that the value is a number. - * - * @see luax_tofloat - */ -inline float luax_checkfloat(lua_State *L, int idx) -{ - return static_cast(luaL_checknumber(L, idx)); -} - -/** - * Converts the value at idx to the specified type without checking that - * this conversion is valid. If the type has been previously verified with - * luax_istype, then this can be safely used. Otherwise, use luax_checktype. - * @param L The Lua state. - * @param idx The index on the stack. - * @param name The name of the type. - * @param type The type bit. - **/ -template -T *luax_totype(lua_State *L, int idx, const char *, love::bits) -{ - return (T *)(((Proxy *)lua_touserdata(L, idx))->data); +extern "C" { // Also called from luasocket + int luax_typerror(lua_State *L, int narg, const char *tname); } /** @@ -363,12 +402,12 @@ template T *luax_checktype(lua_State *L, int idx, const char *name, love::bits type) { if (lua_isuserdata(L, idx) == 0) - luaL_error(L, "Incorrect parameter type: expected userdata."); + luax_typerror(L, idx, name); Proxy *u = (Proxy *)lua_touserdata(L, idx); if ((u->flags & type) != type) - luaL_error(L, "Incorrect parameter type: expected %s", name); + luax_typerror(L, idx, name); return (T *)u->data; } @@ -376,11 +415,11 @@ T *luax_checktype(lua_State *L, int idx, const char *name, love::bits type) template T *luax_getmodule(lua_State *L, const char *k, love::bits type) { - luax_getregistry(L, REGISTRY_MODULES); + luax_insistregistry(L, REGISTRY_MODULES); lua_getfield(L, -1, k); if (!lua_isuserdata(L, -1)) - luaL_error(L, "Tried to get nonexisting module %s.", k); + luaL_error(L, "Tried to get nonexistant module %s.", k); Proxy *u = (Proxy *)lua_touserdata(L, -1); @@ -392,6 +431,64 @@ T *luax_getmodule(lua_State *L, const char *k, love::bits type) return (T *)u->data; } +template +T *luax_optmodule(lua_State *L, const char *k, love::bits type) +{ + luax_insistregistry(L, REGISTRY_MODULES); + lua_getfield(L, -1, k); + + if (!lua_isuserdata(L, -1)) + { + lua_pop(L, 2); + return 0; + } + + Proxy *u = (Proxy *)lua_touserdata(L, -1); + + if ((u->flags & type) != type) + luaL_error(L, "Incorrect module %s", k); + + lua_pop(L, 2); + + return (T *) u->data; +} + +/** + * Converts the value at idx to the specified type without checking that + * this conversion is valid. If the type has been previously verified with + * luax_istype, then this can be safely used. Otherwise, use luax_checktype. + * @param L The Lua state. + * @param idx The index on the stack. + * @param name The name of the type. + * @param type The type bit. + **/ +template +T *luax_totype(lua_State *L, int idx, const char * /* name */, love::bits /* type */) +{ + return (T *)(((Proxy *)lua_touserdata(L, idx))->data); +} + +Type luax_type(lua_State *L, int idx); + +/** + * Macro for converting a LOVE exception into a Lua error. + * lua_error (and luaL_error) cannot be called from inside the exception handler + * because they use longjmp, which causes undefined behaviour when the + * destructor of the exception would have been called. + **/ +#define EXCEPT_GUARD(A) \ +{ \ + bool should_error = false; \ + try { A } \ + catch (love::Exception &e) \ + { \ + should_error = true; \ + lua_pushstring(L, e.what()); \ + } \ + if (should_error) \ + return luaL_error(L, "%s", lua_tostring(L, -1)); \ +} + } // love #endif // LOVE_RUNTIME_H diff --git a/src/common/types.h b/src/common/types.h index 89bde6f05..e9319ea58 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -45,7 +45,7 @@ enum Type // Graphics GRAPHICS_DRAWABLE_ID, - GRAPHICS_DRAWQABLE_ID, + GRAPHICS_TEXTURE_ID, GRAPHICS_IMAGE_ID, GRAPHICS_QUAD_ID, GRAPHICS_FONT_ID, @@ -53,10 +53,18 @@ enum Type GRAPHICS_SPRITE_BATCH_ID, GRAPHICS_CANVAS_ID, GRAPHICS_SHADER_ID, + GRAPHICS_MESH_ID, // Image IMAGE_IMAGE_DATA_ID, - IMAGE_ENCODED_IMAGE_DATA_ID, + IMAGE_COMPRESSED_DATA_ID, + + // Joystick + JOYSTICK_JOYSTICK_ID, + + // Math + MATH_RANDOM_GENERATOR_ID, + MATH_BEZIER_CURVE_ID, // Audio AUDIO_SOURCE_ID, @@ -65,6 +73,9 @@ enum Type SOUND_SOUND_DATA_ID, SOUND_DECODER_ID, + // Mouse + MOUSE_CURSOR_ID, + // Physics PHYSICS_WORLD_ID, PHYSICS_CONTACT_ID, @@ -86,6 +97,7 @@ enum Type PHYSICS_WELD_JOINT_ID, PHYSICS_ROPE_JOINT_ID, PHYSICS_WHEEL_JOINT_ID, + PHYSICS_MOTOR_JOINT_ID, // Thread THREAD_THREAD_ID, @@ -93,6 +105,7 @@ enum Type // The modules themselves. Only add abstracted modules here. MODULE_FILESYSTEM_ID, + MODULE_GRAPHICS_ID, MODULE_IMAGE_ID, MODULE_SOUND_ID, @@ -117,18 +130,26 @@ const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T; // Graphics. const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T; -const bits GRAPHICS_DRAWQABLE_T = (bits(1) << GRAPHICS_DRAWQABLE_ID) | GRAPHICS_DRAWABLE_T; -const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWQABLE_T; +const bits GRAPHICS_TEXTURE_T = (bits(1) << GRAPHICS_TEXTURE_ID) | GRAPHICS_DRAWABLE_T; +const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_TEXTURE_T; const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T; const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T; const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T; const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T; -const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWQABLE_T; +const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_TEXTURE_T; const bits GRAPHICS_SHADER_T = (bits(1) << GRAPHICS_SHADER_ID) | OBJECT_T; +const bits GRAPHICS_MESH_T = (bits(1) << GRAPHICS_MESH_ID) | GRAPHICS_DRAWABLE_T; // Image. const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T; -const bits IMAGE_ENCODED_IMAGE_DATA_T = (bits(1) << IMAGE_ENCODED_IMAGE_DATA_ID) | DATA_T; +const bits IMAGE_COMPRESSED_DATA_T = (bits(1) << IMAGE_COMPRESSED_DATA_ID) | DATA_T; + +// Joystick. +const bits JOYSTICK_JOYSTICK_T = (bits(1) << JOYSTICK_JOYSTICK_ID) | OBJECT_T; + +// Math. +const bits MATH_RANDOM_GENERATOR_T = (bits(1) << MATH_RANDOM_GENERATOR_ID) | OBJECT_T; +const bits MATH_BEZIER_CURVE_T = (bits(1) << MATH_BEZIER_CURVE_ID) | OBJECT_T; // Audio. const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T; @@ -137,6 +158,9 @@ const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T; const bits SOUND_SOUND_DATA_T = (bits(1) << SOUND_SOUND_DATA_ID) | DATA_T; const bits SOUND_DECODER_T = bits(1) << SOUND_DECODER_ID; +// Mouse. +const bits MOUSE_CURSOR_T = (bits(1) << MOUSE_CURSOR_ID) | OBJECT_T; + // Physics. const bits PHYSICS_WORLD_T = (bits(1) << PHYSICS_WORLD_ID) | OBJECT_T; const bits PHYSICS_CONTACT_T = (bits(1) << PHYSICS_CONTACT_ID) | OBJECT_T; @@ -158,6 +182,7 @@ const bits PHYSICS_FRICTION_JOINT_T = (bits(1) << PHYSICS_FRICTION_JOINT_ID) | P const bits PHYSICS_WELD_JOINT_T = (bits(1) << PHYSICS_WELD_JOINT_ID) | PHYSICS_JOINT_T; const bits PHYSICS_ROPE_JOINT_T = (bits(1) << PHYSICS_ROPE_JOINT_ID) | PHYSICS_JOINT_T; const bits PHYSICS_WHEEL_JOINT_T = (bits(1) << PHYSICS_WHEEL_JOINT_ID) | PHYSICS_JOINT_T; +const bits PHYSICS_MOTOR_JOINT_T = (bits(1) << PHYSICS_MOTOR_JOINT_ID) | PHYSICS_JOINT_T; // Thread. const bits THREAD_THREAD_T = (bits(1) << THREAD_THREAD_ID) | OBJECT_T; @@ -165,6 +190,7 @@ const bits THREAD_CHANNEL_T = (bits(1) << THREAD_CHANNEL_ID) | OBJECT_T; // Modules. const bits MODULE_FILESYSTEM_T = (bits(1) << MODULE_FILESYSTEM_ID) | MODULE_T; +const bits MODULE_GRAPHICS_T = (bits(1) << MODULE_GRAPHICS_ID) | MODULE_T; const bits MODULE_IMAGE_T = (bits(1) << MODULE_IMAGE_ID) | MODULE_T; const bits MODULE_SOUND_T = (bits(1) << MODULE_SOUND_ID) | MODULE_T; diff --git a/src/common/utf8.cpp b/src/common/utf8.cpp index 7f2943498..fb12997aa 100644 --- a/src/common/utf8.cpp +++ b/src/common/utf8.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/utf8.h b/src/common/utf8.h index f16306a81..6f0d78ef1 100644 --- a/src/common/utf8.h +++ b/src/common/utf8.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/common/version.h b/src/common/version.h index 87e62c6da..d8798f9dc 100644 --- a/src/common/version.h +++ b/src/common/version.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,11 +26,11 @@ namespace love // Version stuff. const int VERSION_MAJOR = 0; -const int VERSION_MINOR = 8; +const int VERSION_MINOR = 9; const int VERSION_REV = 0; -const char *VERSION = "0.8.0"; +const char *VERSION = "0.9.0"; const char *VERSION_COMPATIBILITY[] = { VERSION, 0 }; -const char *VERSION_CODENAME = "Rubber Piggy"; +const char *VERSION_CODENAME = "Baby Inspector"; } // love diff --git a/src/common/wrap_Data.cpp b/src/common/wrap_Data.cpp index 76996a261..c093a78ff 100644 --- a/src/common/wrap_Data.cpp +++ b/src/common/wrap_Data.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -28,6 +28,13 @@ Data *luax_checkdata(lua_State *L, int idx) return luax_checktype(L, idx, "Data", DATA_T); } +int w_Data_getString(lua_State *L) +{ + Data *t = luax_checkdata(L, 1); + lua_pushlstring(L, (const char *) t->getData(), (size_t) t->getSize()); + return 1; +} + int w_Data_getPointer(lua_State *L) { Data *t = luax_checkdata(L, 1); @@ -44,7 +51,8 @@ int w_Data_getSize(lua_State *L) const luaL_Reg w_Data_functions[] = { -// { "getPointer", w_Data_getPointer }, + { "getString", w_Data_getString }, + { "getPointer", w_Data_getPointer }, { "getSize", w_Data_getSize }, { 0, 0 } }; diff --git a/src/common/wrap_Data.h b/src/common/wrap_Data.h index bdcc7cecf..94cc31cde 100644 --- a/src/common/wrap_Data.h +++ b/src/common/wrap_Data.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,6 +29,7 @@ namespace love { Data *luax_checkdata(lua_State *L, int idx); +int w_Data_getString(lua_State *L); int w_Data_getPointer(lua_State *L); int w_Data_getSize(lua_State *L); int w_Data_open(lua_State *L); diff --git a/src/libraries/Box2D/Box2D.h b/src/libraries/Box2D/Box2D.h index f674d8226..187046131 100755 --- a/src/libraries/Box2D/Box2D.h +++ b/src/libraries/Box2D/Box2D.h @@ -56,12 +56,13 @@ For discussion please visit http://box2d.org/forum #include #include #include -#include +#include #include #include #include #include #include #include +#include #endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp b/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp index bd23346a5..069b4cae8 100755 --- a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp +++ b/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp @@ -19,8 +19,7 @@ #include #include #include -#include -using namespace std; +#include b2ChainShape::~b2ChainShape() { @@ -33,6 +32,14 @@ void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count) { b2Assert(m_vertices == NULL && m_count == 0); b2Assert(count >= 3); + for (int32 i = 1; i < count; ++i) + { + b2Vec2 v1 = vertices[i-1]; + b2Vec2 v2 = vertices[i]; + // If the code crashes here, it means your vertices are too close together. + b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop); + } + m_count = count + 1; m_vertices = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2)); memcpy(m_vertices, vertices, count * sizeof(b2Vec2)); @@ -47,11 +54,23 @@ void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 count) { b2Assert(m_vertices == NULL && m_count == 0); b2Assert(count >= 2); + for (int32 i = 1; i < count; ++i) + { + b2Vec2 v1 = vertices[i-1]; + b2Vec2 v2 = vertices[i]; + // If the code crashes here, it means your vertices are too close together. + b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop); + } + m_count = count; m_vertices = (b2Vec2*)b2Alloc(count * sizeof(b2Vec2)); memcpy(m_vertices, vertices, m_count * sizeof(b2Vec2)); + m_hasPrevVertex = false; m_hasNextVertex = false; + + m_prevVertex.SetZero(); + m_nextVertex.SetZero(); } void b2ChainShape::SetPrevVertex(const b2Vec2& prevVertex) diff --git a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h b/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h index d7c5b2924..e836dfef9 100755 --- a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h +++ b/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h @@ -95,8 +95,8 @@ inline b2ChainShape::b2ChainShape() m_radius = b2_polygonRadius; m_vertices = NULL; m_count = 0; - m_hasPrevVertex = NULL; - m_hasNextVertex = NULL; + m_hasPrevVertex = false; + m_hasNextVertex = false; } #endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp b/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp index d494b134a..39d4ae999 100755 --- a/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp +++ b/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp @@ -18,7 +18,6 @@ #include #include -using namespace std; b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const { diff --git a/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp b/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp index cbac41cfa..8bcd12f7a 100755 --- a/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp +++ b/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp @@ -18,7 +18,6 @@ #include #include -using namespace std; void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2) { @@ -105,11 +104,11 @@ bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, output->fraction = t; if (numerator > 0.0f) { - output->normal = -normal; + output->normal = -b2Mul(xf.q, normal); } else { - output->normal = normal; + output->normal = b2Mul(xf.q, normal); } return true; } diff --git a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp b/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp index 499e168f8..2f32e9fe2 100755 --- a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp +++ b/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp @@ -29,7 +29,7 @@ b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const void b2PolygonShape::SetAsBox(float32 hx, float32 hy) { - m_vertexCount = 4; + m_count = 4; m_vertices[0].Set(-hx, -hy); m_vertices[1].Set( hx, -hy); m_vertices[2].Set( hx, hy); @@ -43,7 +43,7 @@ void b2PolygonShape::SetAsBox(float32 hx, float32 hy) void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle) { - m_vertexCount = 4; + m_count = 4; m_vertices[0].Set(-hx, -hy); m_vertices[1].Set( hx, -hy); m_vertices[2].Set( hx, hy); @@ -59,7 +59,7 @@ void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, floa xf.q.Set(angle); // Transform vertices and normals. - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m_count; ++i) { m_vertices[i] = b2Mul(xf, m_vertices[i]); m_normals[i] = b2Mul(xf.q, m_normals[i]); @@ -120,61 +120,131 @@ static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count) void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) { b2Assert(3 <= count && count <= b2_maxPolygonVertices); - m_vertexCount = count; + if (count < 3) + { + SetAsBox(1.0f, 1.0f); + return; + } + + int32 n = b2Min(count, b2_maxPolygonVertices); + + // Perform welding and copy vertices into local buffer. + b2Vec2 ps[b2_maxPolygonVertices]; + int32 tempCount = 0; + for (int32 i = 0; i < n; ++i) + { + b2Vec2 v = vertices[i]; + + bool unique = true; + for (int32 j = 0; j < tempCount; ++j) + { + if (b2DistanceSquared(v, ps[j]) < 0.5f * b2_linearSlop) + { + unique = false; + break; + } + } + + if (unique) + { + ps[tempCount++] = v; + } + } + + n = tempCount; + if (n < 3) + { + // Polygon is degenerate. + b2Assert(false); + SetAsBox(1.0f, 1.0f); + return; + } + + // Create the convex hull using the Gift wrapping algorithm + // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm + + // Find the right most point on the hull + int32 i0 = 0; + float32 x0 = ps[0].x; + for (int32 i = 1; i < n; ++i) + { + float32 x = ps[i].x; + if (x > x0 || (x == x0 && ps[i].y < ps[i0].y)) + { + i0 = i; + x0 = x; + } + } + + int32 hull[b2_maxPolygonVertices]; + int32 m = 0; + int32 ih = i0; + + for (;;) + { + hull[m] = ih; + + int32 ie = 0; + for (int32 j = 1; j < n; ++j) + { + if (ie == ih) + { + ie = j; + continue; + } + + b2Vec2 r = ps[ie] - ps[hull[m]]; + b2Vec2 v = ps[j] - ps[hull[m]]; + float32 c = b2Cross(r, v); + if (c < 0.0f) + { + ie = j; + } + + // Collinearity check + if (c == 0.0f && v.LengthSquared() > r.LengthSquared()) + { + ie = j; + } + } + + ++m; + ih = ie; + + if (ie == i0) + { + break; + } + } + + m_count = m; // Copy vertices. - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m; ++i) { - m_vertices[i] = vertices[i]; + m_vertices[i] = ps[hull[i]]; } // Compute normals. Ensure the edges have non-zero length. - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m; ++i) { int32 i1 = i; - int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0; + int32 i2 = i + 1 < m ? i + 1 : 0; b2Vec2 edge = m_vertices[i2] - m_vertices[i1]; b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon); m_normals[i] = b2Cross(edge, 1.0f); m_normals[i].Normalize(); } -#ifdef _DEBUG - // Ensure the polygon is convex and the interior - // is to the left of each edge. - for (int32 i = 0; i < m_vertexCount; ++i) - { - int32 i1 = i; - int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0; - b2Vec2 edge = m_vertices[i2] - m_vertices[i1]; - - for (int32 j = 0; j < m_vertexCount; ++j) - { - // Don't check vertices on the current edge. - if (j == i1 || j == i2) - { - continue; - } - - b2Vec2 r = m_vertices[j] - m_vertices[i1]; - - // If this crashes, your polygon is non-convex, has colinear edges, - // or the winding order is wrong. - float32 s = b2Cross(edge, r); - b2Assert(s > 0.0f && "ERROR: Please ensure your polygon is convex and has a CCW winding order"); - } - } -#endif - // Compute the polygon centroid. - m_centroid = ComputeCentroid(m_vertices, m_vertexCount); + m_centroid = ComputeCentroid(m_vertices, m); } bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const { b2Vec2 pLocal = b2MulT(xf.q, p - xf.p); - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m_count; ++i) { float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]); if (dot > 0.0f) @@ -200,7 +270,7 @@ bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& inpu int32 index = -1; - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m_count; ++i) { // p = p1 + a * d // dot(normal, p - v) = 0 @@ -265,7 +335,7 @@ void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 chil b2Vec2 lower = b2Mul(xf, m_vertices[0]); b2Vec2 upper = lower; - for (int32 i = 1; i < m_vertexCount; ++i) + for (int32 i = 1; i < m_count; ++i) { b2Vec2 v = b2Mul(xf, m_vertices[i]); lower = b2Min(lower, v); @@ -303,7 +373,7 @@ void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const // // The rest of the derivation is handled by computer algebra. - b2Assert(m_vertexCount >= 3); + b2Assert(m_count >= 3); b2Vec2 center; center.Set(0.0f, 0.0f); float32 area = 0.0f; @@ -314,19 +384,19 @@ void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const b2Vec2 s(0.0f, 0.0f); // This code would put the reference point inside the polygon. - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m_count; ++i) { s += m_vertices[i]; } - s *= 1.0f / m_vertexCount; + s *= 1.0f / m_count; const float32 k_inv3 = 1.0f / 3.0f; - for (int32 i = 0; i < m_vertexCount; ++i) + for (int32 i = 0; i < m_count; ++i) { // Triangle vertices. b2Vec2 e1 = m_vertices[i] - s; - b2Vec2 e2 = i + 1 < m_vertexCount ? m_vertices[i+1] - s : m_vertices[0] - s; + b2Vec2 e2 = i + 1 < m_count ? m_vertices[i+1] - s : m_vertices[0] - s; float32 D = b2Cross(e1, e2); @@ -359,3 +429,31 @@ void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const // Shift to center of mass then to original body origin. massData->I += massData->mass * (b2Dot(massData->center, massData->center) - b2Dot(center, center)); } + +bool b2PolygonShape::Validate() const +{ + for (int32 i = 0; i < m_count; ++i) + { + int32 i1 = i; + int32 i2 = i < m_count - 1 ? i1 + 1 : 0; + b2Vec2 p = m_vertices[i1]; + b2Vec2 e = m_vertices[i2] - p; + + for (int32 j = 0; j < m_count; ++j) + { + if (j == i1 || j == i2) + { + continue; + } + + b2Vec2 v = m_vertices[j] - p; + float32 c = b2Cross(e, v); + if (c < 0.0f) + { + return false; + } + } + } + + return true; +} diff --git a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h b/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h index 5c5321221..b19298038 100755 --- a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h +++ b/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h @@ -36,12 +36,14 @@ public: /// @see b2Shape::GetChildCount int32 GetChildCount() const; - /// Copy vertices. This assumes the vertices define a convex polygon. - /// It is assumed that the exterior is the the right of each edge. + /// Create a convex hull from the given array of local points. /// The count must be in the range [3, b2_maxPolygonVertices]. - void Set(const b2Vec2* vertices, int32 vertexCount); + /// @warning the points may be re-ordered, even if they form a convex polygon + /// @warning collinear points are handled but not removed. Collinear points + /// may lead to poor stacking behavior. + void Set(const b2Vec2* points, int32 count); - /// Build vertices to represent an axis-aligned box. + /// Build vertices to represent an axis-aligned box centered on the local origin. /// @param hx the half-width. /// @param hy the half-height. void SetAsBox(float32 hx, float32 hy); @@ -67,28 +69,32 @@ public: void ComputeMass(b2MassData* massData, float32 density) const; /// Get the vertex count. - int32 GetVertexCount() const { return m_vertexCount; } + int32 GetVertexCount() const { return m_count; } /// Get a vertex by index. const b2Vec2& GetVertex(int32 index) const; + /// Validate convexity. This is a very time consuming operation. + /// @returns true if valid + bool Validate() const; + b2Vec2 m_centroid; b2Vec2 m_vertices[b2_maxPolygonVertices]; b2Vec2 m_normals[b2_maxPolygonVertices]; - int32 m_vertexCount; + int32 m_count; }; inline b2PolygonShape::b2PolygonShape() { m_type = e_polygon; m_radius = b2_polygonRadius; - m_vertexCount = 0; + m_count = 0; m_centroid.SetZero(); } inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const { - b2Assert(0 <= index && index < m_vertexCount); + b2Assert(0 <= index && index < m_count); return m_vertices[index]; } diff --git a/src/libraries/Box2D/Collision/b2BroadPhase.cpp b/src/libraries/Box2D/Collision/b2BroadPhase.cpp index b34df8707..5cd6f0e8a 100755 --- a/src/libraries/Box2D/Collision/b2BroadPhase.cpp +++ b/src/libraries/Box2D/Collision/b2BroadPhase.cpp @@ -17,8 +17,7 @@ */ #include -#include -using namespace std; +#include b2BroadPhase::b2BroadPhase() { @@ -90,7 +89,6 @@ void b2BroadPhase::UnBufferMove(int32 proxyId) if (m_moveBuffer[i] == proxyId) { m_moveBuffer[i] = e_nullProxy; - return; } } } diff --git a/src/libraries/Box2D/Collision/b2BroadPhase.h b/src/libraries/Box2D/Collision/b2BroadPhase.h index a289bbf6c..0c460cabb 100755 --- a/src/libraries/Box2D/Collision/b2BroadPhase.h +++ b/src/libraries/Box2D/Collision/b2BroadPhase.h @@ -28,7 +28,6 @@ struct b2Pair { int32 proxyIdA; int32 proxyIdB; - int32 next; }; /// The broad-phase is used for computing pairs and performing volume queries and ray casts. @@ -100,6 +99,11 @@ public: /// Get the quality metric of the embedded tree. float32 GetTreeQuality() const; + /// Shift the world origin. Useful for large worlds. + /// The shift formula is: position -= newOrigin + /// @param newOrigin the new origin with respect to the old origin + void ShiftOrigin(const b2Vec2& newOrigin); + private: friend class b2DynamicTree; @@ -245,4 +249,9 @@ inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) cons m_tree.RayCast(callback, input); } +inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin) +{ + m_tree.ShiftOrigin(newOrigin); +} + #endif diff --git a/src/libraries/Box2D/Collision/b2CollideCircle.cpp b/src/libraries/Box2D/Collision/b2CollideCircle.cpp index ae91c733c..4181fd47c 100755 --- a/src/libraries/Box2D/Collision/b2CollideCircle.cpp +++ b/src/libraries/Box2D/Collision/b2CollideCircle.cpp @@ -63,7 +63,7 @@ void b2CollidePolygonAndCircle( int32 normalIndex = 0; float32 separation = -b2_maxFloat; float32 radius = polygonA->m_radius + circleB->m_radius; - int32 vertexCount = polygonA->m_vertexCount; + int32 vertexCount = polygonA->m_count; const b2Vec2* vertices = polygonA->m_vertices; const b2Vec2* normals = polygonA->m_normals; diff --git a/src/libraries/Box2D/Collision/b2CollideEdge.cpp b/src/libraries/Box2D/Collision/b2CollideEdge.cpp index 92a8e1157..88e311c66 100755 --- a/src/libraries/Box2D/Collision/b2CollideEdge.cpp +++ b/src/libraries/Box2D/Collision/b2CollideEdge.cpp @@ -425,8 +425,8 @@ void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const } // Get polygonB in frameA - m_polygonB.count = polygonB->m_vertexCount; - for (int32 i = 0; i < polygonB->m_vertexCount; ++i) + m_polygonB.count = polygonB->m_count; + for (int32 i = 0; i < polygonB->m_count; ++i) { m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]); m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]); @@ -497,13 +497,13 @@ void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const ie[0].v = m_polygonB.vertices[i1]; ie[0].id.cf.indexA = 0; - ie[0].id.cf.indexB = i1; + ie[0].id.cf.indexB = static_cast(i1); ie[0].id.cf.typeA = b2ContactFeature::e_face; ie[0].id.cf.typeB = b2ContactFeature::e_vertex; ie[1].v = m_polygonB.vertices[i2]; ie[1].id.cf.indexA = 0; - ie[1].id.cf.indexB = i2; + ie[1].id.cf.indexB = static_cast(i2); ie[1].id.cf.typeA = b2ContactFeature::e_face; ie[1].id.cf.typeB = b2ContactFeature::e_vertex; @@ -530,13 +530,13 @@ void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const ie[0].v = m_v1; ie[0].id.cf.indexA = 0; - ie[0].id.cf.indexB = primaryAxis.index; + ie[0].id.cf.indexB = static_cast(primaryAxis.index); ie[0].id.cf.typeA = b2ContactFeature::e_vertex; ie[0].id.cf.typeB = b2ContactFeature::e_face; ie[1].v = m_v2; ie[1].id.cf.indexA = 0; - ie[1].id.cf.indexB = primaryAxis.index; + ie[1].id.cf.indexB = static_cast(primaryAxis.index); ie[1].id.cf.typeA = b2ContactFeature::e_vertex; ie[1].id.cf.typeB = b2ContactFeature::e_face; diff --git a/src/libraries/Box2D/Collision/b2CollidePolygon.cpp b/src/libraries/Box2D/Collision/b2CollidePolygon.cpp index 68695285c..0aac38b2a 100755 --- a/src/libraries/Box2D/Collision/b2CollidePolygon.cpp +++ b/src/libraries/Box2D/Collision/b2CollidePolygon.cpp @@ -19,123 +19,46 @@ #include #include -// Find the separation between poly1 and poly2 for a give edge normal on poly1. -static float32 b2EdgeSeparation(const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1, - const b2PolygonShape* poly2, const b2Transform& xf2) -{ - const b2Vec2* vertices1 = poly1->m_vertices; - const b2Vec2* normals1 = poly1->m_normals; - - int32 count2 = poly2->m_vertexCount; - const b2Vec2* vertices2 = poly2->m_vertices; - - b2Assert(0 <= edge1 && edge1 < poly1->m_vertexCount); - - // Convert normal from poly1's frame into poly2's frame. - b2Vec2 normal1World = b2Mul(xf1.q, normals1[edge1]); - b2Vec2 normal1 = b2MulT(xf2.q, normal1World); - - // Find support vertex on poly2 for -normal. - int32 index = 0; - float32 minDot = b2_maxFloat; - - for (int32 i = 0; i < count2; ++i) - { - float32 dot = b2Dot(vertices2[i], normal1); - if (dot < minDot) - { - minDot = dot; - index = i; - } - } - - b2Vec2 v1 = b2Mul(xf1, vertices1[edge1]); - b2Vec2 v2 = b2Mul(xf2, vertices2[index]); - float32 separation = b2Dot(v2 - v1, normal1World); - return separation; -} - // Find the max separation between poly1 and poly2 using edge normals from poly1. static float32 b2FindMaxSeparation(int32* edgeIndex, const b2PolygonShape* poly1, const b2Transform& xf1, const b2PolygonShape* poly2, const b2Transform& xf2) { - int32 count1 = poly1->m_vertexCount; - const b2Vec2* normals1 = poly1->m_normals; + int32 count1 = poly1->m_count; + int32 count2 = poly2->m_count; + const b2Vec2* n1s = poly1->m_normals; + const b2Vec2* v1s = poly1->m_vertices; + const b2Vec2* v2s = poly2->m_vertices; + b2Transform xf = b2MulT(xf2, xf1); - // Vector pointing from the centroid of poly1 to the centroid of poly2. - b2Vec2 d = b2Mul(xf2, poly2->m_centroid) - b2Mul(xf1, poly1->m_centroid); - b2Vec2 dLocal1 = b2MulT(xf1.q, d); - - // Find edge normal on poly1 that has the largest projection onto d. - int32 edge = 0; - float32 maxDot = -b2_maxFloat; + int32 bestIndex = 0; + float32 maxSeparation = -b2_maxFloat; for (int32 i = 0; i < count1; ++i) { - float32 dot = b2Dot(normals1[i], dLocal1); - if (dot > maxDot) + // Get poly1 normal in frame2. + b2Vec2 n = b2Mul(xf.q, n1s[i]); + b2Vec2 v1 = b2Mul(xf, v1s[i]); + + // Find deepest point for normal i. + float32 si = b2_maxFloat; + for (int32 j = 0; j < count2; ++j) { - maxDot = dot; - edge = i; + float32 sij = b2Dot(n, v2s[j] - v1); + if (sij < si) + { + si = sij; + } + } + + if (si > maxSeparation) + { + maxSeparation = si; + bestIndex = i; } } - // Get the separation for the edge normal. - float32 s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2); - - // Check the separation for the previous edge normal. - int32 prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1; - float32 sPrev = b2EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); - - // Check the separation for the next edge normal. - int32 nextEdge = edge + 1 < count1 ? edge + 1 : 0; - float32 sNext = b2EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); - - // Find the best edge and the search direction. - int32 bestEdge; - float32 bestSeparation; - int32 increment; - if (sPrev > s && sPrev > sNext) - { - increment = -1; - bestEdge = prevEdge; - bestSeparation = sPrev; - } - else if (sNext > s) - { - increment = 1; - bestEdge = nextEdge; - bestSeparation = sNext; - } - else - { - *edgeIndex = edge; - return s; - } - - // Perform a local search for the best edge normal. - for ( ; ; ) - { - if (increment == -1) - edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; - else - edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0; - - s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2); - - if (s > bestSeparation) - { - bestEdge = edge; - bestSeparation = s; - } - else - { - break; - } - } - - *edgeIndex = bestEdge; - return bestSeparation; + *edgeIndex = bestIndex; + return maxSeparation; } static void b2FindIncidentEdge(b2ClipVertex c[2], @@ -144,11 +67,11 @@ static void b2FindIncidentEdge(b2ClipVertex c[2], { const b2Vec2* normals1 = poly1->m_normals; - int32 count2 = poly2->m_vertexCount; + int32 count2 = poly2->m_count; const b2Vec2* vertices2 = poly2->m_vertices; const b2Vec2* normals2 = poly2->m_normals; - b2Assert(0 <= edge1 && edge1 < poly1->m_vertexCount); + b2Assert(0 <= edge1 && edge1 < poly1->m_count); // Get the normal of the reference edge in poly2's frame. b2Vec2 normal1 = b2MulT(xf2.q, b2Mul(xf1.q, normals1[edge1])); @@ -210,12 +133,11 @@ void b2CollidePolygons(b2Manifold* manifold, const b2PolygonShape* poly1; // reference polygon const b2PolygonShape* poly2; // incident polygon b2Transform xf1, xf2; - int32 edge1; // reference edge + int32 edge1; // reference edge uint8 flip; - const float32 k_relativeTol = 0.98f; - const float32 k_absoluteTol = 0.001f; + const float32 k_tol = 0.1f * b2_linearSlop; - if (separationB > k_relativeTol * separationA + k_absoluteTol) + if (separationB > separationA + k_tol) { poly1 = polyB; poly2 = polyA; @@ -239,7 +161,7 @@ void b2CollidePolygons(b2Manifold* manifold, b2ClipVertex incidentEdge[2]; b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); - int32 count1 = poly1->m_vertexCount; + int32 count1 = poly1->m_count; const b2Vec2* vertices1 = poly1->m_vertices; int32 iv1 = edge1; diff --git a/src/libraries/Box2D/Collision/b2Collision.cpp b/src/libraries/Box2D/Collision/b2Collision.cpp index 8ecb33775..4ebf35565 100755 --- a/src/libraries/Box2D/Collision/b2Collision.cpp +++ b/src/libraries/Box2D/Collision/b2Collision.cpp @@ -44,6 +44,7 @@ void b2WorldManifold::Initialize(const b2Manifold* manifold, b2Vec2 cA = pointA + radiusA * normal; b2Vec2 cB = pointB - radiusB * normal; points[0] = 0.5f * (cA + cB); + separations[0] = b2Dot(cB - cA, normal); } break; @@ -58,6 +59,7 @@ void b2WorldManifold::Initialize(const b2Manifold* manifold, b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal; b2Vec2 cB = clipPoint - radiusB * normal; points[i] = 0.5f * (cA + cB); + separations[i] = b2Dot(cB - cA, normal); } } break; @@ -73,6 +75,7 @@ void b2WorldManifold::Initialize(const b2Manifold* manifold, b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal; b2Vec2 cA = clipPoint - radiusA * normal; points[i] = 0.5f * (cA + cB); + separations[i] = b2Dot(cA - cB, normal); } // Ensure normal points from A to B. @@ -217,7 +220,7 @@ int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v); // VertexA is hitting edgeB. - vOut[numOut].id.cf.indexA = vertexIndexA; + vOut[numOut].id.cf.indexA = static_cast(vertexIndexA); vOut[numOut].id.cf.indexB = vIn[0].id.cf.indexB; vOut[numOut].id.cf.typeA = b2ContactFeature::e_vertex; vOut[numOut].id.cf.typeB = b2ContactFeature::e_face; diff --git a/src/libraries/Box2D/Collision/b2Collision.h b/src/libraries/Box2D/Collision/b2Collision.h index 8bb316caa..ad023b3ca 100755 --- a/src/libraries/Box2D/Collision/b2Collision.h +++ b/src/libraries/Box2D/Collision/b2Collision.h @@ -20,7 +20,7 @@ #define B2_COLLISION_H #include -#include +#include /// @file /// Structures and functions used for computing contact points, distance @@ -117,8 +117,9 @@ struct b2WorldManifold const b2Transform& xfA, float32 radiusA, const b2Transform& xfB, float32 radiusB); - b2Vec2 normal; ///< world vector pointing from A to B - b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection) + b2Vec2 normal; ///< world vector pointing from A to B + b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection) + float32 separations[b2_maxManifoldPoints]; ///< a negative value indicates overlap, in meters }; /// This is used for determining the state of contact points. diff --git a/src/libraries/Box2D/Collision/b2Distance.cpp b/src/libraries/Box2D/Collision/b2Distance.cpp index 8309ea4fe..78daab3e2 100755 --- a/src/libraries/Box2D/Collision/b2Distance.cpp +++ b/src/libraries/Box2D/Collision/b2Distance.cpp @@ -31,7 +31,7 @@ void b2DistanceProxy::Set(const b2Shape* shape, int32 index) { case b2Shape::e_circle: { - const b2CircleShape* circle = (b2CircleShape*)shape; + const b2CircleShape* circle = static_cast(shape); m_vertices = &circle->m_p; m_count = 1; m_radius = circle->m_radius; @@ -40,16 +40,16 @@ void b2DistanceProxy::Set(const b2Shape* shape, int32 index) case b2Shape::e_polygon: { - const b2PolygonShape* polygon = (b2PolygonShape*)shape; + const b2PolygonShape* polygon = static_cast(shape); m_vertices = polygon->m_vertices; - m_count = polygon->m_vertexCount; + m_count = polygon->m_count; m_radius = polygon->m_radius; } break; case b2Shape::e_chain: { - const b2ChainShape* chain = (b2ChainShape*)shape; + const b2ChainShape* chain = static_cast(shape); b2Assert(0 <= index && index < chain->m_count); m_buffer[0] = chain->m_vertices[index]; @@ -70,7 +70,7 @@ void b2DistanceProxy::Set(const b2Shape* shape, int32 index) case b2Shape::e_edge: { - const b2EdgeShape* edge = (b2EdgeShape*)shape; + const b2EdgeShape* edge = static_cast(shape); m_vertices = &edge->m_vertex1; m_count = 2; m_radius = edge->m_radius; @@ -141,6 +141,7 @@ struct b2Simplex v->wA = b2Mul(transformA, wALocal); v->wB = b2Mul(transformB, wBLocal); v->w = v->wB - v->wA; + v->a = 1.0f; m_count = 1; } } @@ -244,7 +245,7 @@ struct b2Simplex { case 0: b2Assert(false); - return 0.0; + return 0.0f; case 1: return 0.0f; @@ -465,8 +466,7 @@ void b2Distance(b2DistanceOutput* output, int32 saveA[3], saveB[3]; int32 saveCount = 0; - b2Vec2 closestPoint = simplex.GetClosestPoint(); - float32 distanceSqr1 = closestPoint.LengthSquared(); + float32 distanceSqr1 = b2_maxFloat; float32 distanceSqr2 = distanceSqr1; // Main iteration loop. diff --git a/src/libraries/Box2D/Collision/b2DynamicTree.cpp b/src/libraries/Box2D/Collision/b2DynamicTree.cpp index 2f81958e3..7035ab8b8 100755 --- a/src/libraries/Box2D/Collision/b2DynamicTree.cpp +++ b/src/libraries/Box2D/Collision/b2DynamicTree.cpp @@ -17,10 +17,7 @@ */ #include -#include -#include -using namespace std; - +#include b2DynamicTree::b2DynamicTree() { @@ -769,3 +766,13 @@ void b2DynamicTree::RebuildBottomUp() Validate(); } + +void b2DynamicTree::ShiftOrigin(const b2Vec2& newOrigin) +{ + // Build array of leaves. Free the rest. + for (int32 i = 0; i < m_nodeCapacity; ++i) + { + m_nodes[i].aabb.lowerBound -= newOrigin; + m_nodes[i].aabb.upperBound -= newOrigin; + } +} diff --git a/src/libraries/Box2D/Collision/b2DynamicTree.h b/src/libraries/Box2D/Collision/b2DynamicTree.h index 0787785b7..bf80f73a1 100755 --- a/src/libraries/Box2D/Collision/b2DynamicTree.h +++ b/src/libraries/Box2D/Collision/b2DynamicTree.h @@ -118,6 +118,11 @@ public: /// Build an optimal tree. Very expensive. For testing. void RebuildBottomUp(); + /// Shift the world origin. Useful for large worlds. + /// The shift formula is: position -= newOrigin + /// @param newOrigin the new origin with respect to the old origin + void ShiftOrigin(const b2Vec2& newOrigin); + private: int32 AllocateNode(); diff --git a/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp b/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp index 9b456a999..60da95c38 100755 --- a/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp +++ b/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp @@ -21,13 +21,15 @@ #include #include #include +#include -#include -using namespace std; +#include +float32 b2_toiTime, b2_toiMaxTime; int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; int32 b2_toiRootIters, b2_toiMaxRootIters; +// struct b2SeparationFunction { enum Type @@ -119,6 +121,7 @@ struct b2SeparationFunction } } + // float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const { b2Transform xfA, xfB; @@ -187,6 +190,7 @@ struct b2SeparationFunction } } + // float32 Evaluate(int32 indexA, int32 indexB, float32 t) const { b2Transform xfA, xfB; @@ -197,9 +201,6 @@ struct b2SeparationFunction { case e_points: { - b2Vec2 axisA = b2MulT(xfA.q, m_axis); - b2Vec2 axisB = b2MulT(xfB.q, -m_axis); - b2Vec2 localPointA = m_proxyA->GetVertex(indexA); b2Vec2 localPointB = m_proxyB->GetVertex(indexB); @@ -215,8 +216,6 @@ struct b2SeparationFunction b2Vec2 normal = b2Mul(xfA.q, m_axis); b2Vec2 pointA = b2Mul(xfA, m_localPoint); - b2Vec2 axisB = b2MulT(xfB.q, -normal); - b2Vec2 localPointB = m_proxyB->GetVertex(indexB); b2Vec2 pointB = b2Mul(xfB, localPointB); @@ -229,8 +228,6 @@ struct b2SeparationFunction b2Vec2 normal = b2Mul(xfB.q, m_axis); b2Vec2 pointB = b2Mul(xfB, m_localPoint); - b2Vec2 axisA = b2MulT(xfA.q, -normal); - b2Vec2 localPointA = m_proxyA->GetVertex(indexA); b2Vec2 pointA = b2Mul(xfA, localPointA); @@ -256,6 +253,8 @@ struct b2SeparationFunction // by computing the largest time at which separation is maintained. void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) { + b2Timer timer; + ++b2_toiCalls; output->state = b2TOIOutput::e_unknown; @@ -422,6 +421,9 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) t = 0.5f * (a1 + a2); } + ++rootIterCount; + ++b2_toiRootIters; + float32 s = fcn.Evaluate(indexA, indexB, t); if (b2Abs(s - target) < tolerance) @@ -442,10 +444,7 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) a2 = t; s2 = s; } - - ++rootIterCount; - ++b2_toiRootIters; - + if (rootIterCount == 50) { break; @@ -480,4 +479,8 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) } b2_toiMaxIters = b2Max(b2_toiMaxIters, iter); + + float32 time = timer.GetMilliseconds(); + b2_toiMaxTime = b2Max(b2_toiMaxTime, time); + b2_toiTime += time; } diff --git a/src/libraries/Box2D/Common/b2BlockAllocator.cpp b/src/libraries/Box2D/Common/b2BlockAllocator.cpp index d5fa97db9..f7a4688ea 100755 --- a/src/libraries/Box2D/Common/b2BlockAllocator.cpp +++ b/src/libraries/Box2D/Common/b2BlockAllocator.cpp @@ -17,11 +17,9 @@ */ #include -#include -#include -#include -#include -using namespace std; +#include +#include +#include int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = { diff --git a/src/libraries/Box2D/Common/b2Draw.h b/src/libraries/Box2D/Common/b2Draw.h index 7c4676b50..20359c913 100755 --- a/src/libraries/Box2D/Common/b2Draw.h +++ b/src/libraries/Box2D/Common/b2Draw.h @@ -16,6 +16,9 @@ * 3. This notice may not be removed or altered from any source distribution. */ +#ifndef B2_DRAW_H +#define B2_DRAW_H + #include /// Color for debug drawing. Each value has the range [0,1]. @@ -79,3 +82,5 @@ public: protected: uint32 m_drawFlags; }; + +#endif diff --git a/src/libraries/Box2D/Common/b2GrowableStack.h b/src/libraries/Box2D/Common/b2GrowableStack.h index 27a8eb25d..4094644a2 100755 --- a/src/libraries/Box2D/Common/b2GrowableStack.h +++ b/src/libraries/Box2D/Common/b2GrowableStack.h @@ -19,7 +19,7 @@ #ifndef B2_GROWABLE_STACK_H #define B2_GROWABLE_STACK_H #include -#include +#include /// This is a growable LIFO stack with an initial capacity of N. /// If the stack size exceeds the initial capacity, the heap is used @@ -51,7 +51,7 @@ public: T* old = m_stack; m_capacity *= 2; m_stack = (T*)b2Alloc(m_capacity * sizeof(T)); - std::memcpy(m_stack, old, m_count * sizeof(T)); + memcpy(m_stack, old, m_count * sizeof(T)); if (old != m_array) { b2Free(old); diff --git a/src/libraries/Box2D/Common/b2Math.h b/src/libraries/Box2D/Common/b2Math.h index 11c70707a..713100dfa 100755 --- a/src/libraries/Box2D/Common/b2Math.h +++ b/src/libraries/Box2D/Common/b2Math.h @@ -20,24 +20,14 @@ #define B2_MATH_H #include +#include +#include -#include -#include -#include -#include - -/// This function is used to ensure that a floating point number is -/// not a NaN or infinity. +/// This function is used to ensure that a floating point number is not a NaN or infinity. inline bool b2IsValid(float32 x) { - if (x != x) - { - // NaN. - return false; - } - - float32 infinity = std::numeric_limits::infinity(); - return -infinity < x && x < infinity; + int32 ix = *reinterpret_cast(&x); + return (ix & 0x7f800000) != 0x7f800000; } /// This is a approximate yet fast inverse square-root. @@ -57,8 +47,8 @@ inline float32 b2InvSqrt(float32 x) return x; } -#define b2Sqrt(x) std::sqrt(x) -#define b2Atan2(y, x) std::atan2(y, x) +#define b2Sqrt(x) sqrtf(x) +#define b2Atan2(y, x) atan2f(y, x) /// A 2D column vector. struct b2Vec2 @@ -714,8 +704,8 @@ inline void b2Sweep::Advance(float32 alpha) { b2Assert(alpha0 < 1.0f); float32 beta = (alpha - alpha0) / (1.0f - alpha0); - c0 = (1.0f - beta) * c0 + beta * c; - a0 = (1.0f - beta) * a0 + beta * a; + c0 += beta * (c - c0); + a0 += beta * (a - a0); alpha0 = alpha; } diff --git a/src/libraries/Box2D/Common/b2Settings.cpp b/src/libraries/Box2D/Common/b2Settings.cpp index 416e72c16..e2ceefc1d 100755 --- a/src/libraries/Box2D/Common/b2Settings.cpp +++ b/src/libraries/Box2D/Common/b2Settings.cpp @@ -17,13 +17,13 @@ */ #include -#include -#include -#include +#include +#include +#include #include "common/Exception.h" -b2Version b2_version = {2, 2, 1}; +b2Version b2_version = {2, 3, 0}; // Memory allocators. Modify these to use your own allocator. void* b2Alloc(int32 size) @@ -48,5 +48,5 @@ void b2Log(const char* string, ...) void loveAssert(bool test, const char *teststr) { if (!test) - throw love::Exception("Box2D error: %s", teststr); + throw love::Exception("Box2D assertion failed: %s", teststr); } diff --git a/src/libraries/Box2D/Common/b2Settings.h b/src/libraries/Box2D/Common/b2Settings.h index 0eb7a0fa4..beaa1d47b 100755 --- a/src/libraries/Box2D/Common/b2Settings.h +++ b/src/libraries/Box2D/Common/b2Settings.h @@ -19,8 +19,9 @@ #ifndef B2_SETTINGS_H #define B2_SETTINGS_H -#include -#include +#include +#include +#include void loveAssert(bool test, const char *teststr); diff --git a/src/libraries/Box2D/Common/b2Timer.cpp b/src/libraries/Box2D/Common/b2Timer.cpp index 17cd247d4..cbea5309e 100755 --- a/src/libraries/Box2D/Common/b2Timer.cpp +++ b/src/libraries/Box2D/Common/b2Timer.cpp @@ -22,6 +22,7 @@ float64 b2Timer::s_invFrequency = 0.0f; +#define WIN32_LEAN_AND_MEAN #include b2Timer::b2Timer() @@ -72,14 +73,14 @@ void b2Timer::Reset() timeval t; gettimeofday(&t, 0); m_start_sec = t.tv_sec; - m_start_msec = t.tv_usec * 0.001f; + m_start_usec = t.tv_usec; } float32 b2Timer::GetMilliseconds() const { timeval t; gettimeofday(&t, 0); - return (t.tv_sec - m_start_sec) * 1000 + t.tv_usec * 0.001f - m_start_msec; + return 1000.0f * (t.tv_sec - m_start_sec) + 0.001f * (t.tv_usec - m_start_usec); } #else diff --git a/src/libraries/Box2D/Common/b2Timer.h b/src/libraries/Box2D/Common/b2Timer.h index b6db8884d..edf1ca459 100755 --- a/src/libraries/Box2D/Common/b2Timer.h +++ b/src/libraries/Box2D/Common/b2Timer.h @@ -16,6 +16,9 @@ * 3. This notice may not be removed or altered from any source distribution. */ +#ifndef B2_TIMER_H +#define B2_TIMER_H + #include /// Timer for profiling. This has platform specific code and may @@ -40,6 +43,8 @@ private: static float64 s_invFrequency; #elif defined(__linux__) || defined (__APPLE__) unsigned long m_start_sec; - unsigned long m_start_msec; + unsigned long m_start_usec; #endif }; + +#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp index 81bf68230..01c921f3d 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp @@ -23,7 +23,6 @@ #include #include -using namespace std; b2Contact* b2ChainAndCircleContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp index 0da218786..4642fa46a 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp @@ -23,7 +23,6 @@ #include #include -using namespace std; b2Contact* b2ChainAndPolygonContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp index ade092049..b47f35aed 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp @@ -24,7 +24,6 @@ #include #include -using namespace std; b2Contact* b2CircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp index e7e2a2e65..d9f1021e4 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp @@ -102,14 +102,19 @@ void b2Contact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) { b2Assert(s_initialized == true); - if (contact->m_manifold.pointCount > 0) + b2Fixture* fixtureA = contact->m_fixtureA; + b2Fixture* fixtureB = contact->m_fixtureB; + + if (contact->m_manifold.pointCount > 0 && + fixtureA->IsSensor() == false && + fixtureB->IsSensor() == false) { - contact->GetFixtureA()->GetBody()->SetAwake(true); - contact->GetFixtureB()->GetBody()->SetAwake(true); + fixtureA->GetBody()->SetAwake(true); + fixtureB->GetBody()->SetAwake(true); } - b2Shape::Type typeA = contact->GetFixtureA()->GetType(); - b2Shape::Type typeB = contact->GetFixtureB()->GetType(); + b2Shape::Type typeA = fixtureA->GetType(); + b2Shape::Type typeB = fixtureB->GetType(); b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount); b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount); @@ -147,6 +152,8 @@ b2Contact::b2Contact(b2Fixture* fA, int32 indexA, b2Fixture* fB, int32 indexB) m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction); m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); + + m_tangentSpeed = 0.0f; } // Update the contact manifold and touching status. diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h b/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h index f8e74e923..36e31e256 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h +++ b/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h @@ -36,7 +36,7 @@ class b2ContactListener; /// For example, anything slides on ice. inline float32 b2MixFriction(float32 friction1, float32 friction2) { - return std::sqrt(friction1 * friction2); + return b2Sqrt(friction1 * friction2); } /// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface. @@ -135,6 +135,12 @@ public: /// Reset the restitution to the default value. void ResetRestitution(); + /// Set the desired tangent speed for a conveyor belt behavior. In meters per second. + void SetTangentSpeed(float32 speed); + + /// Get the desired tangent speed. In meters per second. + float32 GetTangentSpeed() const; + /// Evaluate this contact with your own manifold and transforms. virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0; @@ -209,6 +215,8 @@ protected: float32 m_friction; float32 m_restitution; + + float32 m_tangentSpeed; }; inline b2Manifold* b2Contact::GetManifold() @@ -328,4 +336,14 @@ inline void b2Contact::ResetRestitution() m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); } +inline void b2Contact::SetTangentSpeed(float32 speed) +{ + m_tangentSpeed = speed; +} + +inline float32 b2Contact::GetTangentSpeed() const +{ + return m_tangentSpeed; +} + #endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp index 4e510a620..8224fdc2d 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp @@ -73,6 +73,7 @@ b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def) b2ContactVelocityConstraint* vc = m_velocityConstraints + i; vc->friction = contact->m_friction; vc->restitution = contact->m_restitution; + vc->tangentSpeed = contact->m_tangentSpeed; vc->indexA = bodyA->m_islandIndex; vc->indexB = bodyB->m_islandIndex; vc->invMassA = bodyA->m_invMass; @@ -320,7 +321,7 @@ void b2ContactSolver::SolveVelocityConstraints() b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA); // Compute tangent force - float32 vt = b2Dot(dv, tangent); + float32 vt = b2Dot(dv, tangent) - vc->tangentSpeed; float32 lambda = vcp->tangentMass * (-vt); // b2Clamp the accumulated force @@ -763,8 +764,8 @@ bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiInde iA = pc->invIA; } - float32 mB = pc->invMassB; - float32 iB = pc->invIB; + float32 mB = 0.0f; + float32 iB = 0.; if (indexB == toiIndexA || indexB == toiIndexB) { mB = pc->invMassB; diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h b/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h index ff3a49c4b..a622e30d8 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h +++ b/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h @@ -51,6 +51,7 @@ struct b2ContactVelocityConstraint float32 invIA, invIB; float32 friction; float32 restitution; + float32 tangentSpeed; int32 pointCount; int32 contactIndex; }; diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp index 742a10167..d1fd3295c 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp @@ -21,7 +21,6 @@ #include #include -using namespace std; b2Contact* b2EdgeAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp index 0eb09cffa..ba536bc39 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp @@ -21,7 +21,6 @@ #include #include -using namespace std; b2Contact* b2EdgeAndPolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp index b5712af8a..7c9cbcc92 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp @@ -21,7 +21,6 @@ #include #include -using namespace std; b2Contact* b2PolygonAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp index 47dce21fe..b5706ca10 100755 --- a/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +++ b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp @@ -24,7 +24,6 @@ #include #include -using namespace std; b2Contact* b2PolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) { diff --git a/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp index 023d107b4..155eb0c1d 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp @@ -147,22 +147,18 @@ void b2GearJoint::InitVelocityConstraints(const b2SolverData& data) m_iC = m_bodyC->m_invI; m_iD = m_bodyD->m_invI; - b2Vec2 cA = data.positions[m_indexA].c; float32 aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; float32 wA = data.velocities[m_indexA].w; - b2Vec2 cB = data.positions[m_indexB].c; float32 aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; float32 wB = data.velocities[m_indexB].w; - b2Vec2 cC = data.positions[m_indexC].c; float32 aC = data.positions[m_indexC].a; b2Vec2 vC = data.velocities[m_indexC].v; float32 wC = data.velocities[m_indexC].w; - b2Vec2 cD = data.positions[m_indexD].c; float32 aD = data.positions[m_indexD].a; b2Vec2 vD = data.velocities[m_indexD].v; float32 wD = data.velocities[m_indexD].w; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp index 84802bff9..dd55be94f 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -42,70 +43,77 @@ b2Joint* b2Joint::Create(const b2JointDef* def, b2BlockAllocator* allocator) case e_distanceJoint: { void* mem = allocator->Allocate(sizeof(b2DistanceJoint)); - joint = new (mem) b2DistanceJoint((b2DistanceJointDef*)def); + joint = new (mem) b2DistanceJoint(static_cast(def)); } break; case e_mouseJoint: { void* mem = allocator->Allocate(sizeof(b2MouseJoint)); - joint = new (mem) b2MouseJoint((b2MouseJointDef*)def); + joint = new (mem) b2MouseJoint(static_cast(def)); } break; case e_prismaticJoint: { void* mem = allocator->Allocate(sizeof(b2PrismaticJoint)); - joint = new (mem) b2PrismaticJoint((b2PrismaticJointDef*)def); + joint = new (mem) b2PrismaticJoint(static_cast(def)); } break; case e_revoluteJoint: { void* mem = allocator->Allocate(sizeof(b2RevoluteJoint)); - joint = new (mem) b2RevoluteJoint((b2RevoluteJointDef*)def); + joint = new (mem) b2RevoluteJoint(static_cast(def)); } break; case e_pulleyJoint: { void* mem = allocator->Allocate(sizeof(b2PulleyJoint)); - joint = new (mem) b2PulleyJoint((b2PulleyJointDef*)def); + joint = new (mem) b2PulleyJoint(static_cast(def)); } break; case e_gearJoint: { void* mem = allocator->Allocate(sizeof(b2GearJoint)); - joint = new (mem) b2GearJoint((b2GearJointDef*)def); + joint = new (mem) b2GearJoint(static_cast(def)); } break; case e_wheelJoint: { void* mem = allocator->Allocate(sizeof(b2WheelJoint)); - joint = new (mem) b2WheelJoint((b2WheelJointDef*)def); + joint = new (mem) b2WheelJoint(static_cast(def)); } break; case e_weldJoint: { void* mem = allocator->Allocate(sizeof(b2WeldJoint)); - joint = new (mem) b2WeldJoint((b2WeldJointDef*)def); + joint = new (mem) b2WeldJoint(static_cast(def)); } break; case e_frictionJoint: { void* mem = allocator->Allocate(sizeof(b2FrictionJoint)); - joint = new (mem) b2FrictionJoint((b2FrictionJointDef*)def); + joint = new (mem) b2FrictionJoint(static_cast(def)); } break; case e_ropeJoint: { void* mem = allocator->Allocate(sizeof(b2RopeJoint)); - joint = new (mem) b2RopeJoint((b2RopeJointDef*)def); + joint = new (mem) b2RopeJoint(static_cast(def)); + } + break; + + case e_motorJoint: + { + void* mem = allocator->Allocate(sizeof(b2MotorJoint)); + joint = new (mem) b2MotorJoint(static_cast(def)); } break; @@ -162,6 +170,10 @@ void b2Joint::Destroy(b2Joint* joint, b2BlockAllocator* allocator) allocator->Free(joint, sizeof(b2RopeJoint)); break; + case e_motorJoint: + allocator->Free(joint, sizeof(b2MotorJoint)); + break; + default: b2Assert(false); break; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2Joint.h b/src/libraries/Box2D/Dynamics/Joints/b2Joint.h index c0f9db832..dd076b6b2 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2Joint.h +++ b/src/libraries/Box2D/Dynamics/Joints/b2Joint.h @@ -38,7 +38,8 @@ enum b2JointType e_wheelJoint, e_weldJoint, e_frictionJoint, - e_ropeJoint + e_ropeJoint, + e_motorJoint }; enum b2LimitState @@ -145,6 +146,9 @@ public: /// Dump this joint to the log file. virtual void Dump() { b2Log("// Dump is not supported for this joint type.\n"); } + /// Shift the origin for any points stored in world coordinates. + virtual void ShiftOrigin(const b2Vec2& newOrigin) { B2_NOT_USED(newOrigin); } + protected: friend class b2World; friend class b2Body; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp new file mode 100755 index 000000000..e5bbcb165 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp @@ -0,0 +1,304 @@ +/* +* Copyright (c) 2006-2012 Erin Catto http://www.box2d.org +* +* 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. +*/ + +#include +#include +#include + +// Point-to-point constraint +// Cdot = v2 - v1 +// = v2 + cross(w2, r2) - v1 - cross(w1, r1) +// J = [-I -r1_skew I r2_skew ] +// Identity used: +// w k % (rx i + ry j) = w * (-ry i + rx j) + +// Angle constraint +// Cdot = w2 - w1 +// J = [0 0 -1 0 0 1] +// K = invI1 + invI2 + +void b2MotorJointDef::Initialize(b2Body* bA, b2Body* bB) +{ + bodyA = bA; + bodyB = bB; + b2Vec2 xB = bodyB->GetPosition(); + linearOffset = bodyA->GetLocalPoint(xB); + + float32 angleA = bodyA->GetAngle(); + float32 angleB = bodyB->GetAngle(); + angularOffset = angleB - angleA; +} + +b2MotorJoint::b2MotorJoint(const b2MotorJointDef* def) +: b2Joint(def) +{ + m_linearOffset = def->linearOffset; + m_angularOffset = def->angularOffset; + + m_linearImpulse.SetZero(); + m_angularImpulse = 0.0f; + + m_maxForce = def->maxForce; + m_maxTorque = def->maxTorque; + m_correctionFactor = def->correctionFactor; +} + +void b2MotorJoint::InitVelocityConstraints(const b2SolverData& data) +{ + m_indexA = m_bodyA->m_islandIndex; + m_indexB = m_bodyB->m_islandIndex; + m_localCenterA = m_bodyA->m_sweep.localCenter; + m_localCenterB = m_bodyB->m_sweep.localCenter; + m_invMassA = m_bodyA->m_invMass; + m_invMassB = m_bodyB->m_invMass; + m_invIA = m_bodyA->m_invI; + m_invIB = m_bodyB->m_invI; + + b2Vec2 cA = data.positions[m_indexA].c; + float32 aA = data.positions[m_indexA].a; + b2Vec2 vA = data.velocities[m_indexA].v; + float32 wA = data.velocities[m_indexA].w; + + b2Vec2 cB = data.positions[m_indexB].c; + float32 aB = data.positions[m_indexB].a; + b2Vec2 vB = data.velocities[m_indexB].v; + float32 wB = data.velocities[m_indexB].w; + + b2Rot qA(aA), qB(aB); + + // Compute the effective mass matrix. + m_rA = b2Mul(qA, -m_localCenterA); + m_rB = b2Mul(qB, -m_localCenterB); + + // J = [-I -r1_skew I r2_skew] + // [ 0 -1 0 1] + // r_skew = [-ry; rx] + + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] + // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] + + float32 mA = m_invMassA, mB = m_invMassB; + float32 iA = m_invIA, iB = m_invIB; + + b2Mat22 K; + K.ex.x = mA + mB + iA * m_rA.y * m_rA.y + iB * m_rB.y * m_rB.y; + K.ex.y = -iA * m_rA.x * m_rA.y - iB * m_rB.x * m_rB.y; + K.ey.x = K.ex.y; + K.ey.y = mA + mB + iA * m_rA.x * m_rA.x + iB * m_rB.x * m_rB.x; + + m_linearMass = K.GetInverse(); + + m_angularMass = iA + iB; + if (m_angularMass > 0.0f) + { + m_angularMass = 1.0f / m_angularMass; + } + + m_linearError = cB + m_rB - cA - m_rA - b2Mul(qA, m_linearOffset); + m_angularError = aB - aA - m_angularOffset; + + if (data.step.warmStarting) + { + // Scale impulses to support a variable time step. + m_linearImpulse *= data.step.dtRatio; + m_angularImpulse *= data.step.dtRatio; + + b2Vec2 P(m_linearImpulse.x, m_linearImpulse.y); + vA -= mA * P; + wA -= iA * (b2Cross(m_rA, P) + m_angularImpulse); + vB += mB * P; + wB += iB * (b2Cross(m_rB, P) + m_angularImpulse); + } + else + { + m_linearImpulse.SetZero(); + m_angularImpulse = 0.0f; + } + + data.velocities[m_indexA].v = vA; + data.velocities[m_indexA].w = wA; + data.velocities[m_indexB].v = vB; + data.velocities[m_indexB].w = wB; +} + +void b2MotorJoint::SolveVelocityConstraints(const b2SolverData& data) +{ + b2Vec2 vA = data.velocities[m_indexA].v; + float32 wA = data.velocities[m_indexA].w; + b2Vec2 vB = data.velocities[m_indexB].v; + float32 wB = data.velocities[m_indexB].w; + + float32 mA = m_invMassA, mB = m_invMassB; + float32 iA = m_invIA, iB = m_invIB; + + float32 h = data.step.dt; + float32 inv_h = data.step.inv_dt; + + // Solve angular friction + { + float32 Cdot = wB - wA + inv_h * m_correctionFactor * m_angularError; + float32 impulse = -m_angularMass * Cdot; + + float32 oldImpulse = m_angularImpulse; + float32 maxImpulse = h * m_maxTorque; + m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_angularImpulse - oldImpulse; + + wA -= iA * impulse; + wB += iB * impulse; + } + + // Solve linear friction + { + b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA) + inv_h * m_correctionFactor * m_linearError; + + b2Vec2 impulse = -b2Mul(m_linearMass, Cdot); + b2Vec2 oldImpulse = m_linearImpulse; + m_linearImpulse += impulse; + + float32 maxImpulse = h * m_maxForce; + + if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) + { + m_linearImpulse.Normalize(); + m_linearImpulse *= maxImpulse; + } + + impulse = m_linearImpulse - oldImpulse; + + vA -= mA * impulse; + wA -= iA * b2Cross(m_rA, impulse); + + vB += mB * impulse; + wB += iB * b2Cross(m_rB, impulse); + } + + data.velocities[m_indexA].v = vA; + data.velocities[m_indexA].w = wA; + data.velocities[m_indexB].v = vB; + data.velocities[m_indexB].w = wB; +} + +bool b2MotorJoint::SolvePositionConstraints(const b2SolverData& data) +{ + B2_NOT_USED(data); + + return true; +} + +b2Vec2 b2MotorJoint::GetAnchorA() const +{ + return m_bodyA->GetPosition(); +} + +b2Vec2 b2MotorJoint::GetAnchorB() const +{ + return m_bodyB->GetPosition(); +} + +b2Vec2 b2MotorJoint::GetReactionForce(float32 inv_dt) const +{ + return inv_dt * m_linearImpulse; +} + +float32 b2MotorJoint::GetReactionTorque(float32 inv_dt) const +{ + return inv_dt * m_angularImpulse; +} + +void b2MotorJoint::SetMaxForce(float32 force) +{ + b2Assert(b2IsValid(force) && force >= 0.0f); + m_maxForce = force; +} + +float32 b2MotorJoint::GetMaxForce() const +{ + return m_maxForce; +} + +void b2MotorJoint::SetMaxTorque(float32 torque) +{ + b2Assert(b2IsValid(torque) && torque >= 0.0f); + m_maxTorque = torque; +} + +float32 b2MotorJoint::GetMaxTorque() const +{ + return m_maxTorque; +} + +void b2MotorJoint::SetCorrectionFactor(float32 factor) +{ + b2Assert(b2IsValid(factor) && 0.0f <= factor && factor <= 1.0f); + m_correctionFactor = factor; +} + +float32 b2MotorJoint::GetCorrectionFactor() const +{ + return m_correctionFactor; +} + +void b2MotorJoint::SetLinearOffset(const b2Vec2& linearOffset) +{ + if (linearOffset.x != m_linearOffset.x || linearOffset.y != m_linearOffset.y) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_linearOffset = linearOffset; + } +} + +const b2Vec2& b2MotorJoint::GetLinearOffset() const +{ + return m_linearOffset; +} + +void b2MotorJoint::SetAngularOffset(float32 angularOffset) +{ + if (angularOffset != m_angularOffset) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_angularOffset = angularOffset; + } +} + +float32 b2MotorJoint::GetAngularOffset() const +{ + return m_angularOffset; +} + +void b2MotorJoint::Dump() +{ + int32 indexA = m_bodyA->m_islandIndex; + int32 indexB = m_bodyB->m_islandIndex; + + b2Log(" b2MotorJointDef jd;\n"); + b2Log(" jd.bodyA = bodies[%d];\n", indexA); + b2Log(" jd.bodyB = bodies[%d];\n", indexB); + b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Log(" jd.linearOffset.Set(%.15lef, %.15lef);\n", m_linearOffset.x, m_linearOffset.y); + b2Log(" jd.angularOffset = %.15lef;\n", m_angularOffset); + b2Log(" jd.maxForce = %.15lef;\n", m_maxForce); + b2Log(" jd.maxTorque = %.15lef;\n", m_maxTorque); + b2Log(" jd.correctionFactor = %.15lef;\n", m_correctionFactor); + b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); +} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h new file mode 100755 index 000000000..0b76d6fe7 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2006-2012 Erin Catto http://www.box2d.org +* +* 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. +*/ + +#ifndef B2_MOTOR_JOINT_H +#define B2_MOTOR_JOINT_H + +#include + +/// Motor joint definition. +struct b2MotorJointDef : public b2JointDef +{ + b2MotorJointDef() + { + type = e_motorJoint; + linearOffset.SetZero(); + angularOffset = 0.0f; + maxForce = 1.0f; + maxTorque = 1.0f; + correctionFactor = 0.3f; + } + + /// Initialize the bodies and offsets using the current transforms. + void Initialize(b2Body* bodyA, b2Body* bodyB); + + /// Position of bodyB minus the position of bodyA, in bodyA's frame, in meters. + b2Vec2 linearOffset; + + /// The bodyB angle minus bodyA angle in radians. + float32 angularOffset; + + /// The maximum motor force in N. + float32 maxForce; + + /// The maximum motor torque in N-m. + float32 maxTorque; + + /// Position correction factor in the range [0,1]. + float32 correctionFactor; +}; + +/// A motor joint is used to control the relative motion +/// between two bodies. A typical usage is to control the movement +/// of a dynamic body with respect to the ground. +class b2MotorJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Set/get the target linear offset, in frame A, in meters. + void SetLinearOffset(const b2Vec2& linearOffset); + const b2Vec2& GetLinearOffset() const; + + /// Set/get the target angular offset, in radians. + void SetAngularOffset(float32 angularOffset); + float32 GetAngularOffset() const; + + /// Set the maximum friction force in N. + void SetMaxForce(float32 force); + + /// Get the maximum friction force in N. + float32 GetMaxForce() const; + + /// Set the maximum friction torque in N*m. + void SetMaxTorque(float32 torque); + + /// Get the maximum friction torque in N*m. + float32 GetMaxTorque() const; + + /// Set the position correction factor in the range [0,1]. + void SetCorrectionFactor(float32 factor); + + /// Get the position correction factor in the range [0,1]. + float32 GetCorrectionFactor() const; + + /// Dump to b2Log + void Dump(); + +protected: + + friend class b2Joint; + + b2MotorJoint(const b2MotorJointDef* def); + + void InitVelocityConstraints(const b2SolverData& data); + void SolveVelocityConstraints(const b2SolverData& data); + bool SolvePositionConstraints(const b2SolverData& data); + + // Solver shared + b2Vec2 m_linearOffset; + float32 m_angularOffset; + b2Vec2 m_linearImpulse; + float32 m_angularImpulse; + float32 m_maxForce; + float32 m_maxTorque; + float32 m_correctionFactor; + + // Solver temp + int32 m_indexA; + int32 m_indexB; + b2Vec2 m_rA; + b2Vec2 m_rB; + b2Vec2 m_localCenterA; + b2Vec2 m_localCenterB; + b2Vec2 m_linearError; + float32 m_angularError; + float32 m_invMassA; + float32 m_invMassB; + float32 m_invIA; + float32 m_invIB; + b2Mat22 m_linearMass; + float32 m_angularMass; +}; + +#endif diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp index 4d19bd407..ea96edde9 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp @@ -215,3 +215,8 @@ float32 b2MouseJoint::GetReactionTorque(float32 inv_dt) const { return inv_dt * 0.0f; } + +void b2MouseJoint::ShiftOrigin(const b2Vec2& newOrigin) +{ + m_targetA -= newOrigin; +} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h index 682e78340..8b50a0e14 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h +++ b/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h @@ -92,6 +92,9 @@ public: /// The mouse joint does not support dumping. void Dump() { b2Log("Mouse joint dumping is not supported.\n"); } + /// Implement b2Joint::ShiftOrigin + void ShiftOrigin(const b2Vec2& newOrigin); + protected: friend class b2Joint; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp index 1df28b9db..26f539681 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp @@ -108,7 +108,7 @@ b2PrismaticJoint::b2PrismaticJoint(const b2PrismaticJointDef* def) m_referenceAngle = def->referenceAngle; m_impulse.SetZero(); - m_motorMass = 0.0; + m_motorMass = 0.0f; m_motorImpulse = 0.0f; m_lowerTranslation = def->lowerTranslation; @@ -349,17 +349,6 @@ void b2PrismaticJoint::SolveVelocityConstraints(const b2SolverData& data) vB += mB * P; wB += iB * LB; - - b2Vec2 Cdot10 = Cdot1; - - Cdot1.x = b2Dot(m_perp, vB - vA) + m_s2 * wB - m_s1 * wA; - Cdot1.y = wB - wA; - - if (b2Abs(Cdot1.x) > 0.01f || b2Abs(Cdot1.y) > 0.01f) - { - b2Vec2 test = b2Mul22(m_K, df); - Cdot1.x += 0.0f; - } } data.velocities[m_indexA].v = vA; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp index b7bab69fc..9cd340f1b 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp @@ -292,6 +292,21 @@ b2Vec2 b2PulleyJoint::GetGroundAnchorB() const } float32 b2PulleyJoint::GetLengthA() const +{ + return m_lengthA; +} + +float32 b2PulleyJoint::GetLengthB() const +{ + return m_lengthB; +} + +float32 b2PulleyJoint::GetRatio() const +{ + return m_ratio; +} + +float32 b2PulleyJoint::GetCurrentLengthA() const { b2Vec2 p = m_bodyA->GetWorldPoint(m_localAnchorA); b2Vec2 s = m_groundAnchorA; @@ -299,7 +314,7 @@ float32 b2PulleyJoint::GetLengthA() const return d.Length(); } -float32 b2PulleyJoint::GetLengthB() const +float32 b2PulleyJoint::GetCurrentLengthB() const { b2Vec2 p = m_bodyB->GetWorldPoint(m_localAnchorB); b2Vec2 s = m_groundAnchorB; @@ -307,11 +322,6 @@ float32 b2PulleyJoint::GetLengthB() const return d.Length(); } -float32 b2PulleyJoint::GetRatio() const -{ - return m_ratio; -} - void b2PulleyJoint::Dump() { int32 indexA = m_bodyA->m_islandIndex; @@ -330,3 +340,9 @@ void b2PulleyJoint::Dump() b2Log(" jd.ratio = %.15lef;\n", m_ratio); b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } + +void b2PulleyJoint::ShiftOrigin(const b2Vec2& newOrigin) +{ + m_groundAnchorA -= newOrigin; + m_groundAnchorB -= newOrigin; +} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h index 24480ba05..44843e7b4 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h +++ b/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h @@ -100,9 +100,18 @@ public: /// Get the pulley ratio. float32 GetRatio() const; + /// Get the current length of the segment attached to bodyA. + float32 GetCurrentLengthA() const; + + /// Get the current length of the segment attached to bodyB. + float32 GetCurrentLengthB() const; + /// Dump joint to dmLog void Dump(); + /// Implement b2Joint::ShiftOrigin + void ShiftOrigin(const b2Vec2& newOrigin); + protected: friend class b2Joint; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp index e658f38b0..64bd19070 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp @@ -72,12 +72,10 @@ void b2RevoluteJoint::InitVelocityConstraints(const b2SolverData& data) m_invIA = m_bodyA->m_invI; m_invIB = m_bodyB->m_invI; - b2Vec2 cA = data.positions[m_indexA].c; float32 aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; float32 wA = data.velocities[m_indexA].w; - b2Vec2 cB = data.positions[m_indexB].c; float32 aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; float32 wB = data.velocities[m_indexB].w; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp index 8e49aca17..253f7216e 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp @@ -66,12 +66,10 @@ void b2WeldJoint::InitVelocityConstraints(const b2SolverData& data) m_invIA = m_bodyA->m_invI; m_invIB = m_bodyB->m_invI; - b2Vec2 cA = data.positions[m_indexA].c; float32 aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; float32 wA = data.velocities[m_indexA].w; - b2Vec2 cB = data.positions[m_indexB].c; float32 aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; float32 wB = data.velocities[m_indexB].w; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp index 5ecc8928c..c9f6de600 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp +++ b/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp @@ -55,7 +55,7 @@ b2WheelJoint::b2WheelJoint(const b2WheelJointDef* def) m_mass = 0.0f; m_impulse = 0.0f; - m_motorMass = 0.0; + m_motorMass = 0.0f; m_motorImpulse = 0.0f; m_springMass = 0.0f; m_springImpulse = 0.0f; diff --git a/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h index 968eeafe5..ca59d7a64 100755 --- a/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h +++ b/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h @@ -79,8 +79,6 @@ struct b2WheelJointDef : public b2JointDef class b2WheelJoint : public b2Joint { public: - void GetDefinition(b2WheelJointDef* def) const; - b2Vec2 GetAnchorA() const; b2Vec2 GetAnchorB() const; diff --git a/src/libraries/Box2D/Dynamics/b2Body.cpp b/src/libraries/Box2D/Dynamics/b2Body.cpp index b19c7ffd5..b6550531f 100755 --- a/src/libraries/Box2D/Dynamics/b2Body.cpp +++ b/src/libraries/Box2D/Dynamics/b2Body.cpp @@ -141,10 +141,25 @@ void b2Body::SetType(b2BodyType type) m_force.SetZero(); m_torque = 0.0f; - // Since the body type changed, we need to flag contacts for filtering. + // Delete the attached contacts. + b2ContactEdge* ce = m_contactList; + while (ce) + { + b2ContactEdge* ce0 = ce; + ce = ce->next; + m_world->m_contactManager.Destroy(ce0->contact); + } + m_contactList = NULL; + + // Touch the proxies so that new contacts will be created (when appropriate) + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; for (b2Fixture* f = m_fixtureList; f; f = f->m_next) { - f->Refilter(); + int32 proxyCount = f->m_proxyCount; + for (int32 i = 0; i < proxyCount; ++i) + { + broadPhase->TouchProxy(f->m_proxies[i].proxyId); + } } } @@ -421,8 +436,6 @@ void b2Body::SetTransform(const b2Vec2& position, float32 angle) { f->Synchronize(broadPhase, m_xf, m_xf); } - - m_world->m_contactManager.FindNewContacts(); } void b2Body::SynchronizeFixtures() @@ -483,6 +496,28 @@ void b2Body::SetActive(bool flag) } } +void b2Body::SetFixedRotation(bool flag) +{ + bool status = (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; + if (status == flag) + { + return; + } + + if (flag) + { + m_flags |= e_fixedRotationFlag; + } + else + { + m_flags &= ~e_fixedRotationFlag; + } + + m_angularVelocity = 0.0f; + + ResetMassData(); +} + void b2Body::Dump() { int32 bodyIndex = m_islandIndex; @@ -511,4 +546,4 @@ void b2Body::Dump() b2Log(" }\n"); } b2Log("}\n"); -} \ No newline at end of file +} diff --git a/src/libraries/Box2D/Dynamics/b2Body.h b/src/libraries/Box2D/Dynamics/b2Body.h index c6009513a..24bae6403 100755 --- a/src/libraries/Box2D/Dynamics/b2Body.h +++ b/src/libraries/Box2D/Dynamics/b2Body.h @@ -154,8 +154,8 @@ public: void DestroyFixture(b2Fixture* fixture); /// Set the position of the body's origin and rotation. - /// This breaks any contacts and wakes the other bodies. /// Manipulating a body's transform may cause non-physical behavior. + /// Note: contacts are updated on the next call to b2World::Step. /// @param position the world position of the body's local origin. /// @param angle the world rotation in radians. void SetTransform(const b2Vec2& position, float32 angle); @@ -184,7 +184,7 @@ public: /// Get the linear velocity of the center of mass. /// @return the linear velocity of the center of mass. - b2Vec2 GetLinearVelocity() const; + const b2Vec2& GetLinearVelocity() const; /// Set the angular velocity. /// @param omega the new angular velocity in radians/second. @@ -199,28 +199,33 @@ public: /// affect the angular velocity. This wakes up the body. /// @param force the world force vector, usually in Newtons (N). /// @param point the world position of the point of application. - void ApplyForce(const b2Vec2& force, const b2Vec2& point); + /// @param wake also wake up the body + void ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake); /// Apply a force to the center of mass. This wakes up the body. /// @param force the world force vector, usually in Newtons (N). - void ApplyForceToCenter(const b2Vec2& force); + /// @param wake also wake up the body + void ApplyForceToCenter(const b2Vec2& force, bool wake); /// Apply a torque. This affects the angular velocity /// without affecting the linear velocity of the center of mass. /// This wakes up the body. /// @param torque about the z-axis (out of the screen), usually in N-m. - void ApplyTorque(float32 torque); + /// @param wake also wake up the body + void ApplyTorque(float32 torque, bool wake); /// Apply an impulse at a point. This immediately modifies the velocity. /// It also modifies the angular velocity if the point of application /// is not at the center of mass. This wakes up the body. /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. /// @param point the world position of the point of application. - void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point); + /// @param wake also wake up the body + void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point, bool wake); /// Apply an angular impulse. /// @param impulse the angular impulse in units of kg*m*m/s - void ApplyAngularImpulse(float32 impulse); + /// @param wake also wake up the body + void ApplyAngularImpulse(float32 impulse, bool wake); /// Get the total mass of the body. /// @return the mass, usually in kilograms (kg). @@ -315,11 +320,11 @@ public: /// Set the sleep state of the body. A sleeping body has very /// low CPU cost. - /// @param flag set to true to put body to sleep, false to wake it. + /// @param flag set to true to wake the body, false to put it to sleep. void SetAwake(bool flag); /// Get the sleeping state of this body. - /// @return true if the body is sleeping. + /// @return true if the body is awake. bool IsAwake() const; /// Set the active state of the body. An inactive body is not @@ -387,15 +392,16 @@ private: friend class b2Contact; friend class b2DistanceJoint; + friend class b2FrictionJoint; friend class b2GearJoint; - friend class b2WheelJoint; + friend class b2MotorJoint; friend class b2MouseJoint; friend class b2PrismaticJoint; friend class b2PulleyJoint; friend class b2RevoluteJoint; - friend class b2WeldJoint; - friend class b2FrictionJoint; friend class b2RopeJoint; + friend class b2WeldJoint; + friend class b2WheelJoint; // m_flags enum @@ -505,7 +511,7 @@ inline void b2Body::SetLinearVelocity(const b2Vec2& v) m_linearVelocity = v; } -inline b2Vec2 b2Body::GetLinearVelocity() const +inline const b2Vec2& b2Body::GetLinearVelocity() const { return m_linearVelocity; } @@ -655,20 +661,6 @@ inline bool b2Body::IsActive() const return (m_flags & e_activeFlag) == e_activeFlag; } -inline void b2Body::SetFixedRotation(bool flag) -{ - if (flag) - { - m_flags |= e_fixedRotationFlag; - } - else - { - m_flags &= ~e_fixedRotationFlag; - } - - ResetMassData(); -} - inline bool b2Body::IsFixedRotation() const { return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; @@ -742,79 +734,101 @@ inline void* b2Body::GetUserData() const return m_userData; } -inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point) +inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake) { if (m_type != b2_dynamicBody) { return; } - if (IsAwake() == false) + if (wake && (m_flags & e_awakeFlag) == 0) { SetAwake(true); } - m_force += force; - m_torque += b2Cross(point - m_sweep.c, force); + // Don't accumulate a force if the body is sleeping. + if (m_flags & e_awakeFlag) + { + m_force += force; + m_torque += b2Cross(point - m_sweep.c, force); + } } -inline void b2Body::ApplyForceToCenter(const b2Vec2& force) +inline void b2Body::ApplyForceToCenter(const b2Vec2& force, bool wake) { if (m_type != b2_dynamicBody) { return; } - if (IsAwake() == false) + if (wake && (m_flags & e_awakeFlag) == 0) { SetAwake(true); } - m_force += force; + // Don't accumulate a force if the body is sleeping + if (m_flags & e_awakeFlag) + { + m_force += force; + } } -inline void b2Body::ApplyTorque(float32 torque) +inline void b2Body::ApplyTorque(float32 torque, bool wake) { if (m_type != b2_dynamicBody) { return; } - if (IsAwake() == false) + if (wake && (m_flags & e_awakeFlag) == 0) { SetAwake(true); } - m_torque += torque; + // Don't accumulate a force if the body is sleeping + if (m_flags & e_awakeFlag) + { + m_torque += torque; + } } -inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point) +inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point, bool wake) { if (m_type != b2_dynamicBody) { return; } - if (IsAwake() == false) + if (wake && (m_flags & e_awakeFlag) == 0) { SetAwake(true); } - m_linearVelocity += m_invMass * impulse; - m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse); + + // Don't accumulate velocity if the body is sleeping + if (m_flags & e_awakeFlag) + { + m_linearVelocity += m_invMass * impulse; + m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse); + } } -inline void b2Body::ApplyAngularImpulse(float32 impulse) +inline void b2Body::ApplyAngularImpulse(float32 impulse, bool wake) { if (m_type != b2_dynamicBody) { return; } - if (IsAwake() == false) + if (wake && (m_flags & e_awakeFlag) == 0) { SetAwake(true); } - m_angularVelocity += m_invI * impulse; + + // Don't accumulate velocity if the body is sleeping + if (m_flags & e_awakeFlag) + { + m_angularVelocity += m_invI * impulse; + } } inline void b2Body::SynchronizeTransform() diff --git a/src/libraries/Box2D/Dynamics/b2ContactManager.cpp b/src/libraries/Box2D/Dynamics/b2ContactManager.cpp index 47331bd9e..d8a189b74 100755 --- a/src/libraries/Box2D/Dynamics/b2ContactManager.cpp +++ b/src/libraries/Box2D/Dynamics/b2ContactManager.cpp @@ -286,8 +286,11 @@ void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) bodyB->m_contactList = &c->m_nodeB; // Wake up the bodies - bodyA->SetAwake(true); - bodyB->SetAwake(true); + if (fixtureA->IsSensor() == false && fixtureB->IsSensor() == false) + { + bodyA->SetAwake(true); + bodyB->SetAwake(true); + } ++m_contactCount; } diff --git a/src/libraries/Box2D/Dynamics/b2Fixture.cpp b/src/libraries/Box2D/Dynamics/b2Fixture.cpp index 1d09c6d57..fb17f0a3e 100755 --- a/src/libraries/Box2D/Dynamics/b2Fixture.cpp +++ b/src/libraries/Box2D/Dynamics/b2Fixture.cpp @@ -267,11 +267,11 @@ void b2Fixture::Dump(int32 bodyIndex) b2PolygonShape* s = (b2PolygonShape*)m_shape; b2Log(" b2PolygonShape shape;\n"); b2Log(" b2Vec2 vs[%d];\n", b2_maxPolygonVertices); - for (int32 i = 0; i < s->m_vertexCount; ++i) + for (int32 i = 0; i < s->m_count; ++i) { b2Log(" vs[%d].Set(%.15lef, %.15lef);\n", i, s->m_vertices[i].x, s->m_vertices[i].y); } - b2Log(" shape.Set(vs, %d);\n", s->m_vertexCount); + b2Log(" shape.Set(vs, %d);\n", s->m_count); } break; diff --git a/src/libraries/Box2D/Dynamics/b2Island.cpp b/src/libraries/Box2D/Dynamics/b2Island.cpp index 0ecb273a5..d46589dee 100755 --- a/src/libraries/Box2D/Dynamics/b2Island.cpp +++ b/src/libraries/Box2D/Dynamics/b2Island.cpp @@ -211,10 +211,10 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g // Solution: v(t) = v0 * exp(-c * t) // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt) // v2 = exp(-c * dt) * v1 - // Taylor expansion: - // v2 = (1.0f - c * dt) * v1 - v *= b2Clamp(1.0f - h * b->m_linearDamping, 0.0f, 1.0f); - w *= b2Clamp(1.0f - h * b->m_angularDamping, 0.0f, 1.0f); + // Pade approximation: + // v2 = v1 * 1 / (1 + c * dt) + v *= 1.0f / (1.0f + h * b->m_linearDamping); + w *= 1.0f / (1.0f + h * b->m_angularDamping); } m_positions[i].c = c; diff --git a/src/libraries/Box2D/Dynamics/b2World.cpp b/src/libraries/Box2D/Dynamics/b2World.cpp index fae03ecb5..a3a6a1e41 100755 --- a/src/libraries/Box2D/Dynamics/b2World.cpp +++ b/src/libraries/Box2D/Dynamics/b2World.cpp @@ -1073,7 +1073,7 @@ void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color case b2Shape::e_polygon: { b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape(); - int32 vertexCount = poly->m_vertexCount; + int32 vertexCount = poly->m_count; b2Assert(vertexCount <= b2_maxPolygonVertices); b2Vec2 vertices[b2_maxPolygonVertices]; @@ -1256,6 +1256,29 @@ float32 b2World::GetTreeQuality() const return m_contactManager.m_broadPhase.GetTreeQuality(); } +void b2World::ShiftOrigin(const b2Vec2& newOrigin) +{ + b2Assert((m_flags & e_locked) == 0); + if ((m_flags & e_locked) == e_locked) + { + return; + } + + for (b2Body* b = m_bodyList; b; b = b->m_next) + { + b->m_xf.p -= newOrigin; + b->m_sweep.c0 -= newOrigin; + b->m_sweep.c -= newOrigin; + } + + for (b2Joint* j = m_jointList; j; j = j->m_next) + { + j->ShiftOrigin(newOrigin); + } + + m_contactManager.m_broadPhase.ShiftOrigin(newOrigin); +} + void b2World::Dump() { if ((m_flags & e_locked) == e_locked) diff --git a/src/libraries/Box2D/Dynamics/b2World.h b/src/libraries/Box2D/Dynamics/b2World.h index eba757276..4f94f6efe 100755 --- a/src/libraries/Box2D/Dynamics/b2World.h +++ b/src/libraries/Box2D/Dynamics/b2World.h @@ -104,7 +104,7 @@ public: /// @see SetAutoClearForces void ClearForces(); - /// Call this to draw shapes and other debug draw data. + /// Call this to draw shapes and other debug draw data. This is intentionally non-const. void DrawDebugData(); /// Query the world for all fixtures that potentially overlap the @@ -194,6 +194,11 @@ public: /// Get the flag that controls automatic clearing of forces after each time step. bool GetAutoClearForces() const; + /// Shift the world origin. Useful for large worlds. + /// The body shift formula is: position -= newOrigin + /// @param newOrigin the new origin with respect to the old origin + void ShiftOrigin(const b2Vec2& newOrigin); + /// Get the contact manager for testing. const b2ContactManager& GetContactManager() const; diff --git a/src/libraries/Box2D/README.MODIFIED b/src/libraries/Box2D/README.MODIFIED new file mode 100644 index 000000000..71388bce0 --- /dev/null +++ b/src/libraries/Box2D/README.MODIFIED @@ -0,0 +1 @@ +PLEASE NOTE, this version of Box2D is NOT original, it has been MODIFIED by the LÖVE Development Team. diff --git a/src/libraries/Wuff/wuff.c b/src/libraries/Wuff/wuff.c new file mode 100644 index 000000000..f35973330 --- /dev/null +++ b/src/libraries/Wuff/wuff.c @@ -0,0 +1,203 @@ +#include + +#include "wuff_config.h" +#include "wuff.h" +#include "wuff_internal.h" + + +wuff_sint32 wuff_open(struct wuff_handle ** handle_pointer, struct wuff_callback * callback, void * userdata) +{ + struct wuff_handle * handle; + wuff_sint32 wuff_status; + + if (handle_pointer == NULL || callback == NULL) + return WUFF_INVALID_PARAM; + + handle = wuff_alloc(sizeof(struct wuff_handle)); + if (handle == NULL) + return WUFF_MEMALLOC_ERROR; + + memset(handle, 0, sizeof(struct wuff_handle)); + handle->buffer.data = NULL; + handle->callback = callback; + handle->userdata = userdata; + + wuff_status = wuff_setup(handle); + if (wuff_status < 0) + { + wuff_cleanup(handle); + return wuff_status; + } + + *handle_pointer = handle; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_close(struct wuff_handle * handle) +{ + wuff_sint32 wuff_status; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + wuff_status = wuff_cleanup(handle); + WUFF_STATUS_BAIL() + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_seek(struct wuff_handle * handle, wuff_uint64 offset) +{ + wuff_sint32 wuff_status; + wuff_uint64 seek_offset; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + /* Clamp offset to stream length. */ + offset = offset <= handle->stream.length ? offset : handle->stream.length; + seek_offset = offset * handle->stream.header.block_size; + wuff_status = handle->callback->seek(handle->userdata, handle->stream.data.offset + seek_offset); + WUFF_STATUS_BAIL() + + handle->stream.position = offset; + handle->output.block_offset = 0; + + /* A new position requires an empty buffer. */ + wuff_status = wuff_buffer_clear(handle); + WUFF_STATUS_BAIL() + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_tell(struct wuff_handle * handle, wuff_uint64 * offset) +{ + if (handle == NULL) + return WUFF_INVALID_PARAM; + + *offset = handle->stream.position; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_stream_info(struct wuff_handle * handle, struct wuff_info * info) +{ + if (handle == NULL || info == NULL) + return WUFF_INVALID_PARAM; + + info->format = handle->stream.format; + info->channels = handle->stream.header.channels; + info->sample_rate = handle->stream.header.sample_rate; + info->bits_per_sample = handle->stream.header.bits_per_sample; + info->length = handle->stream.length; + /* Think about adding channel mapping and perhaps other things. */ + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_format(struct wuff_handle * handle, wuff_uint16 format) +{ + wuff_sint32 wuff_status; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + else if (format >= WUFF_FORMAT_MAX) + return WUFF_FORMAT_UNSUPPORTED; + + /* A format change resets the position to the start of the block. */ + wuff_status = wuff_seek(handle, handle->stream.position); + WUFF_STATUS_BAIL() + + wuff_status = wuff_set_output_format(handle, format); + WUFF_STATUS_BAIL() + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_read(struct wuff_handle * handle, wuff_uint8 * out_buffer, size_t * out_size) +{ + size_t current_offset; + size_t r_samples, num_samples; + wuff_uint8 head_offset, head, tail, sample_size; + wuff_uint8 * in_buffer; + wuff_sint32 wuff_status; + + if (handle == NULL || out_buffer == NULL || out_size == NULL) + return WUFF_INVALID_PARAM; + + if (*out_size == 0) + return WUFF_SUCCESS; + + sample_size = (wuff_uint8)handle->output.bytes_per_sample; + + /* Calculating the number of samples that fit into the application buffer. */ + /* The first and last sample may be truncated. */ + current_offset = handle->output.block_offset; + head_offset = current_offset % sample_size; + head = head_offset == 0 ? 0 : sample_size - head_offset; + num_samples = wuff_calculate_samples(*out_size, sample_size, &head, &tail); + + /* Requesting the number of samples from the buffer. */ + /* Calculate the new sample count if necessary and write the output. */ + r_samples = num_samples; + wuff_status = wuff_buffer_request(handle, &in_buffer, &r_samples); + WUFF_STATUS_BAIL() + else if (r_samples == 0) + { + /* Possible EOF. */ + *out_size = 0; + } + else + { + if (r_samples == 1 && head != 0) + { + /* Only the first truncated sample fits. */ + /* I really hope nobody will use small buffers like this. */ + num_samples = 0; + tail = 0; + } + else + { + /* At this point the first (possibly truncated) sample will be fully written. */ + /* Subtract the first and last sample from the count if they're truncated. */ + if (r_samples < num_samples) + tail = 0; + num_samples = r_samples - !!head - !!tail; + } + + handle->output.function(out_buffer, in_buffer, num_samples, head_offset, head, tail); + + /* Report the number of bytes written. */ + *out_size = num_samples * sample_size + head + tail; + + /* Adjust the block offset and sample position. */ + current_offset += *out_size; + if (current_offset >= handle->output.block_size) + { + handle->stream.position += current_offset / handle->output.block_size; + handle->output.block_offset = current_offset % handle->output.block_size; + } + else + { + handle->output.block_offset = current_offset; + } + + /* Release the fully processed samples from the buffer. */ + wuff_status = wuff_buffer_release(handle, head_offset + head == sample_size ? num_samples + 1 : num_samples); + WUFF_STATUS_BAIL() + } + + return WUFF_SUCCESS; +} + +void wuff_version(struct wuff_version * version) +{ + if (version == NULL) + return; + + version->major = WUFF_VERSION_MAJOR; + version->minor = WUFF_VERSION_MINOR; + version->build = WUFF_VERSION_BUILD; + version->revision = WUFF_VERSION_REVISION; +} diff --git a/src/libraries/Wuff/wuff.h b/src/libraries/Wuff/wuff.h new file mode 100644 index 000000000..c7cc10927 --- /dev/null +++ b/src/libraries/Wuff/wuff.h @@ -0,0 +1,274 @@ +/* + * Wuff - A very basic WAVE reader + */ + +#ifndef WUFF_H +#define WUFF_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#define WUFF_VERSION_MAJOR 0 +#define WUFF_VERSION_MINOR 0 +#define WUFF_VERSION_BUILD 0 +#define WUFF_VERSION_REVISION 2 + + +#ifndef WUFF_API_OVERRIDE + #if defined(_WIN32) && defined(WUFF_DYNAMIC_LIB) + #define WUFF_EXPORT __declspec(dllexport) + #define WUFF_IMPORT __declspec(dllimport) + #else + #define WUFF_EXPORT + #define WUFF_IMPORT + #endif +#endif + +#ifdef WUFF_BUILDING_CORE + #define WUFF_API WUFF_EXPORT +#else + #define WUFF_API WUFF_IMPORT +#endif + + +#ifdef WUFF_FORCE_STDINT_H + #include +typedef uint8_t wuff_uint8; +typedef int8_t wuff_sint8; +typedef uint16_t wuff_uint16; +typedef int16_t wuff_sint16; +typedef uint32_t wuff_uint32; +typedef int32_t wuff_sint32; + #ifdef WUFF_NO_64BIT_TYPE +typedef uint32_t wuff_uint64; +typedef int32_t wuff_sint64; + #else +typedef uint64_t wuff_uint64; +typedef int64_t wuff_sint64; + #endif +#elif _MSC_VER +typedef unsigned __int8 wuff_uint8; +typedef signed __int8 wuff_sint8; +typedef unsigned __int16 wuff_uint16; +typedef signed __int16 wuff_sint16; +typedef unsigned __int32 wuff_uint32; +typedef signed __int32 wuff_sint32; +typedef unsigned __int64 wuff_uint64; +typedef signed __int64 wuff_sint64; +#else +typedef unsigned char wuff_uint8; +typedef signed char wuff_sint8; +typedef unsigned short wuff_uint16; +typedef signed short wuff_sint16; +typedef unsigned int wuff_uint32; +typedef signed int wuff_sint32; + #ifdef WUFF_NO_64BIT_TYPE +typedef unsigned long wuff_uint64; +typedef signed long wuff_sint64; + #else +typedef unsigned long long wuff_uint64; +typedef signed long long wuff_sint64; + #endif +#endif + +/** @file */ +/** + * Opaque structure used to identify the open Wuff streams. + */ +struct wuff_handle; + +/** + * Callbacks that control the delivery of the data of the WAVE file. + * + * The return values of the functions indicate their status. A zero or positive + * value means success and a negative value failure. The macros WUFF_SUCCESS and + * WUFF_ERROR, or a value equal or below WUFF_USER_ERROR can be used. The error + * value will be returned by the function called by the application. + */ +struct wuff_callback +{ + /** + * The read callback requests the linking application to write at least + * 'size' bytes into the memory where 'buffer' is pointing to. The value + * pointed to by 'size' must be update to the actual number of bytes + * written. Zero will be interepreted as the end-of-file. + * + * @param userdata The userdata set with wuff_open. + * @param buffer A pointer to the memory where the data can be written to. + * @param size A pointer to the size of the buffer and the bytes written. + */ + wuff_sint32 (* read)(void * userdata, wuff_uint8 * buffer, size_t * size); + + /** + * The seek callback requests the linking application to seek to a new byte + * offset in the WAVE data. The next call to the read callback must then + * write data starting from this position. The offset is always relative + * to the beginning of the WAVE data. + * + * @param userdata The userdata set with wuff_open. + * @param offset The new offset. + */ + wuff_sint32 (* seek)(void * userdata, wuff_uint64 offset); + + /** + * The tell callback requests the linking application to write the current + * byte position to the integer pointed to by 'offset'. + * + * @param userdata The userdata set with wuff_open. + * @param offset A pointer to an integer where the current position can be written to. + */ + wuff_sint32 (* tell)(void * userdata, wuff_uint64 * offset); +}; + + +/** + * Stream information structure. + */ +struct wuff_info +{ + wuff_uint16 format; /**< The format of the stream. + * See "Wuff raw sample formats" below. */ + wuff_uint16 channels; /**< The number of channels in the stream. */ + wuff_uint32 sample_rate; /**< The sample rate in hertz. */ + wuff_uint16 bits_per_sample; /**< The number of bits per sample. */ + wuff_uint64 length; /**< The length of the stream in samples. */ +}; + + +/** + * Version information structure. + */ +struct wuff_version +{ + wuff_uint16 major; + wuff_uint16 minor; + wuff_uint16 build; + wuff_uint16 revision; +}; + + +/** + * Opens a new Wuff stream. This will read from the callbacks immediately, make + * sure they're ready. It will check if the WAVE file is supported. + * + * @param handle A pointer to pointer of a wuff_handle that will be + * initialized if the function succeeds. + * @param callback The callbacks for the data of the WAVE file. + * @param userdata A void pointer that will be passed to the callbacks. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_open(struct wuff_handle ** handle, struct wuff_callback * callback, void * userdata); + +/** + * Closes a Wuff stream. + * + * @param handle The Wuff stream handle. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_close(struct wuff_handle * handle); + +/** + * Fills the wuff_info struct with information about the stream. + * + * @param handle The Wuff stream handle. + * @param info A pointer to a wuff_info struct. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_stream_info(struct wuff_handle * handle, struct wuff_info * info); + +/** + * Sets the output format of the decoder. A new format resets the decoder output + * to the beginning of the current block (the sample of the first channel). + * + * @param handle The Wuff stream handle. + * @param format The new output format. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_format(struct wuff_handle * handle, wuff_uint16 format); + +/** + * Decodes samples to the passed memory location. The size_t pointer points to + * the maximum number of bytes that can be written to the buffer. This count + * will be adjusted to the number of bytes written to the buffer. + * + * @param handle The Wuff stream handle. + * @param buffer The buffer to write to. + * @param size The maximum number of bytes to write to the buffer. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_read(struct wuff_handle * handle, wuff_uint8 * buffer, size_t * size); + +/** + * Seeks to a sample location. + * The next call to wuff_read will return samples starting from this position. + * + * @param handle The Wuff stream handle. + * @param offset The sample offset to seek to. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_seek(struct wuff_handle * handle, wuff_uint64 offset); + +/** + * Sets the current position. + * + * @param handle The Wuff stream handle. + * @param offset A pointer to a integer that will receive the sample offset. + * @return Returns a negative value if an error occured. + */ +WUFF_API wuff_sint32 wuff_tell(struct wuff_handle * handle, wuff_uint64 * offset); + +/** + * Copies the Wuff version of the binary into the struct. + * For compile-time version information use the WUFF_VERSION_MAJOR, + * WUFF_VERSION_MINOR, WUFF_VERSION_BUILD, and WUFF_VERSION_REVISION macros. + * + * @param version A pointer to a wuff_version struct that will receive the + * version information. + */ +WUFF_API void wuff_version(struct wuff_version * version); + + +/* Wuff raw sample formats. */ +#define WUFF_FORMAT_PCM_U8 0 +#define WUFF_FORMAT_PCM_S16 1 +#define WUFF_FORMAT_PCM_S24 2 +#define WUFF_FORMAT_PCM_S32 3 +#define WUFF_FORMAT_IEEE_FLOAT_32 4 +#define WUFF_FORMAT_IEEE_FLOAT_64 5 +#define WUFF_FORMAT_MAX 6 + + +/* Success and error return values for all functions. */ +#define WUFF_STREAM_EOF 100 + +#define WUFF_SUCCESS 0 + +#define WUFF_ERROR -1 +#define WUFF_INVALID_PARAM -2 +#define WUFF_MEMALLOC_ERROR -3 + +#define WUFF_STREAM_NOT_RIFF -100 +#define WUFF_STREAM_NOT_WAVE -101 +#define WUFF_STREAM_INVALID -102 +#define WUFF_STREAM_ZERO_CHANNELS -103 +#define WUFF_STREAM_ZERO_SAMPLE_RATE -104 +#define WUFF_STREAM_ZERO_BITS_PER_SAMPLE -105 +#define WUFF_STREAM_FORMAT_CHUNK_MISSING -106 +#define WUFF_STREAM_DATA_CHUNK_MISSING -107 +#define WUFF_STREAM_CHUNK_NOT_FOUND -108 + +#define WUFF_FORMAT_UNSUPPORTED -200 + +#define WUFF_BUFFER_INVALID_SIZE -300 +#define WUFF_BUFFER_INVALID_STREAM_POSITION -301 + +#define WUFF_USER_ERROR -10000 + + +#ifdef __cplusplus +} +#endif + +#endif /* WUFF_H */ diff --git a/src/libraries/Wuff/wuff_config.h b/src/libraries/Wuff/wuff_config.h new file mode 100644 index 000000000..ed17005f4 --- /dev/null +++ b/src/libraries/Wuff/wuff_config.h @@ -0,0 +1,50 @@ +#ifndef WUFF_CONFIG_H +#define WUFF_CONFIG_H + +/* Defines that the internal code is being built. */ +/* The wuff.h header uses this to change export and import macros. */ +#define WUFF_BUILDING_CORE + +#ifndef WUFF_INLINE_OVERRIDE + #ifdef __cplusplus + #define WUFF_INLINE inline + #else + #ifdef _MSC_VER + #define WUFF_INLINE __inline + #elif __GNUC__ + #define WUFF_INLINE __inline__ + #else + #define WUFF_INLINE + #endif + #endif +#endif + + +#ifndef WUFF_GCC_VISIBILITY_OVERRIDE + #if __GNUC__ >= 4 + #define WUFF_INTERN_API __attribute__((visibility("hidden"))) + #else + #define WUFF_INTERN_API + #endif +#endif + + +#ifdef WUFF_MEMALLOC_OVERRIDE + #ifdef __cplusplus +extern "C" { + #endif + + /* Define your own memory allocator. */ + void * wuff_alloc(size_t size); + void wuff_free(void * mem); + + #ifdef __cplusplus +} + #endif +#else +WUFF_INTERN_API void * wuff_alloc(size_t size); +WUFF_INTERN_API void wuff_free(void * mem); +#endif + + +#endif /* WUFF_CONFIG_H */ diff --git a/src/libraries/Wuff/wuff_convert.c b/src/libraries/Wuff/wuff_convert.c new file mode 100644 index 000000000..9e60ff5d3 --- /dev/null +++ b/src/libraries/Wuff/wuff_convert.c @@ -0,0 +1,827 @@ +#include + +#include "wuff_config.h" +#include "wuff.h" +#include "wuff_convert.h" + +/* + * int8 functions. + */ + +WUFF_CONV_FUNC(wuff_int8_to_int8) +{ + (void)offset; + memcpy(dst, src, samples + head + tail); +} + +WUFF_CONV_FUNC(wuff_int8_to_int16) +{ + wuff_sint16 i16; + size_t i; + + if (head != 0) + { + i16 = (src[0] - 128) << 8; + memcpy(dst, (wuff_uint8 *)&i16 + offset, head); + src += 1; + dst += head; + } + + for (i = 0; i < samples; i++) + { + i16 = (src[i] - 128) << 8; + memcpy(dst + i * 2, &i16, 2); + } + + if (tail != 0) + { + i16 = (src[samples] - 128) << 8; + memcpy(dst + samples * 2, &i16, tail); + } +} + +WUFF_CONV_FUNC(wuff_int8_to_int24) +{ + wuff_sint32 i24; + size_t i; + + if (head != 0) + { + i24 = (src[0] - 128) << 24; + memcpy(dst, (wuff_uint8 *)&i24 + 1 + offset, head); + src += 1; + dst += head; + } + + for (i = 0; i < samples; i++) + { + i24 = (src[i] - 128) << 24; + memcpy(dst + i * 3, (wuff_uint8 *)&i24 + 1, 3); + } + + if (tail != 0) + { + i24 = (src[samples] - 128) << 24; + memcpy(dst + samples * 3, (wuff_uint8 *)&i24 + 1, tail); + } +} + +WUFF_CONV_FUNC(wuff_int8_to_int32) +{ + wuff_sint32 i32; + size_t i; + + if (head != 0) + { + i32 = (src[0] - 128) << 24; + memcpy(dst, (wuff_uint8 *)&i32 + offset, head); + src += 1; + dst += head; + } + + for (i = 0; i < samples; i++) + { + i32 = (src[i] - 128) << 24; + memcpy(dst + i * 4, &i32, 4); + } + + if (tail != 0) + { + i32 = (src[samples] - 128) << 24; + memcpy(dst + samples * 4, &i32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int8_to_float32) +{ + float f32; + size_t i; + + if (head != 0) + { + f32 = (float)(src[0] - 128) / 128.0f; + memcpy(dst, (wuff_uint8 *)&f32 + offset, head); + src += 1; + dst += head; + } + + for (i = 0; i < samples; i++) + { + f32 = (float)(src[i] - 128) / 128.0f; + memcpy(dst + i * 4, &f32, 4); + } + + if (tail != 0) + { + f32 = (float)(src[samples] - 128) / 128.0f; + memcpy(dst + samples * 4, &f32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int8_to_float64) +{ + double f64; + size_t i; + + if (head != 0) + { + f64 = (double)(src[0] - 128) / 128.0; + memcpy(dst, (wuff_uint8 *)&f64 + offset, head); + src += 1; + dst += head; + } + + for (i = 0; i < samples; i++) + { + f64 = (double)(src[i] - 128) / 128.0; + memcpy(dst + i * 8, &f64, 8); + } + + if (tail != 0) + { + f64 = (double)(src[samples] - 128) / 128.0; + memcpy(dst + samples * 8, &f64, tail); + } +} + +/* + * int16 functions. + */ + +WUFF_CONV_FUNC(wuff_int16_to_int8) +{ + wuff_sint16 i16; + size_t i; + (void)offset; (void)head; (void)tail; + + for (i = 0; i < samples; i++) + { + memcpy(&i16, src + i * 2, 2); + dst[i] = (i16 >> 8) + 128; + } +} + +WUFF_CONV_FUNC(wuff_int16_to_int16) +{ + memcpy(dst, src + offset, samples * 2 + head + tail); +} + +WUFF_CONV_FUNC(wuff_int16_to_int24) +{ + wuff_sint16 i16; + wuff_sint32 i24; + size_t i; + + if (head != 0) + { + memcpy(&i16, src, 2); + i24 = i16 << 16; + memcpy(dst, (wuff_uint8 *)&i24 + 1 + offset, head); + src += 2; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&i16, src + i * 2, 2); + i24 = i16 << 16; + memcpy(dst + i * 3, (wuff_uint8 *)&i24 + 1, 3); + } + + if (tail != 0) + { + memcpy(&i16, src + samples * 2, 2); + i24 = i16 << 16; + memcpy(dst + samples * 3, (wuff_uint8 *)&i24 + 1, tail); + } +} + +WUFF_CONV_FUNC(wuff_int16_to_int32) +{ + wuff_sint16 i16; + wuff_sint32 i32; + size_t i; + + if (head != 0) + { + memcpy(&i16, src, 2); + i32 = i16 << 16; + memcpy(dst, (wuff_uint8 *)&i32 + offset, head); + src += 2; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&i16, src + i * 2, 2); + i32 = i16 << 16; + memcpy(dst + i * 4, &i32, 4); + } + + if (tail != 0) + { + memcpy(&i16, src + samples * 2, 2); + i32 = i16 << 16; + memcpy(dst + samples * 4, &i32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int16_to_float32) +{ + wuff_sint16 i16; + float f32; + size_t i; + + if (head != 0) + { + memcpy(&i16, src, 2); + f32 = (float)i16 / 32768.0f; + memcpy(dst, (wuff_uint8 *)&f32 + offset, head); + src += 2; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&i16, src + i * 2, 2); + f32 = (float)i16 / 32768.0f; + memcpy(dst + i * 4, &f32, 4); + } + + if (tail != 0) + { + memcpy(&i16, src + samples * 2, 2); + f32 = (float)i16 / 32768.0f; + memcpy(dst + samples * 4, &f32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int16_to_float64) +{ + wuff_sint16 i16; + double f64; + size_t i; + + if (head != 0) + { + memcpy(&i16, src, 2); + f64 = (double)i16 / 32768.0; + memcpy(dst, (wuff_uint8 *)&f64 + offset, head); + src += 2; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&i16, src + i * 2, 2); + f64 = (double)i16 / 32768.0; + memcpy(dst + i * 8, &f64, 8); + } + + if (tail != 0) + { + memcpy(&i16, src + samples * 2, 2); + f64 = (double)i16 / 32768.0; + memcpy(dst + samples * 8, &f64, tail); + } +} + +/* + * int24 functions. + */ + +WUFF_CONV_FUNC(wuff_int24_to_int8) +{ + wuff_sint32 i24 = 0; + size_t i; + (void)offset; (void)head; (void)tail; + + for (i = 0; i < samples; i++) + { + memcpy((wuff_uint8 *)&i24 + 1, src + i * 3, 3); + dst[i] = (wuff_uint8)((i24 >> 16) + 128); + } +} + +WUFF_CONV_FUNC(wuff_int24_to_int16) +{ + size_t i; + + if (head != 0) + { + memcpy(dst, src + 1 + offset, head); + src += 3; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(dst + i * 2, src + 1 + i * 3, 2); + } + + if (tail != 0) + { + memcpy(dst + samples * 2, src + 1 + samples * 3, tail); + } +} + +WUFF_CONV_FUNC(wuff_int24_to_int24) +{ + memcpy(dst, src + offset, samples * 3 + head + tail); +} + +WUFF_CONV_FUNC(wuff_int24_to_int32) +{ + wuff_sint32 i32 = 0; + size_t i; + + if (head != 0) + { + memcpy((wuff_uint8 *)&i32 + 1, src, 3); + memcpy(dst, (wuff_uint8 *)&i32 + offset, head); + src += 3; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy((wuff_uint8 *)&i32 + 1, src + i * 3, 3); + memcpy(dst + i * 4, &i32, 4); + } + + if (tail != 0) + { + memcpy((wuff_uint8 *)&i32 + 1, src + samples * 3, 3); + memcpy(dst + samples * 4, &i32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int24_to_float32) +{ + wuff_sint32 i24 = 0; + float f32; + size_t i; + + if (head != 0) + { + memcpy((wuff_uint8 *)&i24 + 1, src, 3); + f32 = (float)((double)i24 / 2147483648.0); + memcpy(dst, (wuff_uint8 *)&f32 + offset, head); + src += 3; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy((wuff_uint8 *)&i24 + 1, src + i * 3, 3); + f32 = (float)((double)i24 / 2147483648.0); + memcpy(dst + i * 4, &f32, 4); + } + + if (tail != 0) + { + memcpy((wuff_uint8 *)&i24 + 1, src + samples * 3, 3); + f32 = (float)((double)i24 / 2147483648.0); + memcpy(dst + samples * 4, &f32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int24_to_float64) +{ + wuff_sint32 i24 = 0; + double f64; + size_t i; + + if (head != 0) + { + memcpy((wuff_uint8 *)&i24 + 1, src, 3); + f64 = (double)i24 / 2147483648.0; + memcpy(dst, (wuff_uint8 *)&f64 + offset, head); + src += 3; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy((wuff_uint8 *)&i24 + 1, src + i * 3, 3); + f64 = (double)i24 / 2147483648.0; + memcpy(dst + i * 8, &f64, 8); + } + + if (tail != 0) + { + memcpy((wuff_uint8 *)&i24 + 1, src + samples * 3, 3); + f64 = (double)i24 / 2147483648.0; + memcpy(dst + samples * 8, &f64, tail); + } +} + +/* + * int32 functions. + */ + +WUFF_CONV_FUNC(wuff_int32_to_int8) +{ + wuff_sint32 i32 = 0; + size_t i; + (void)offset; (void)head; (void)tail; + + for (i = 0; i < samples; i++) + { + memcpy(&i32, src + i * 4, 4); + dst[i] = (i32 >> 24) + 128; + } +} + +WUFF_CONV_FUNC(wuff_int32_to_int16) +{ + size_t i; + + if (head != 0) + { + memcpy(dst, src + 2 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(dst + i * 2, src + 2 + i * 4, 2); + } + + if (tail != 0) + { + memcpy(dst + samples * 2, src + 2 + samples * 4, tail); + } +} + +WUFF_CONV_FUNC(wuff_int32_to_int24) +{ + size_t i; + + if (head != 0) + { + memcpy(dst, src + 1 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(dst + i * 3, src + 1 + i * 4, 3); + } + + if (tail != 0) + { + memcpy(dst + samples * 3, src + 1 + samples * 4, tail); + } +} + +WUFF_CONV_FUNC(wuff_int32_to_int32) +{ + memcpy(dst, src + offset, samples * 4 + head + tail); +} + +WUFF_CONV_FUNC(wuff_int32_to_float32) +{ + wuff_sint32 i32; + float f32; + size_t i; + + if (head != 0) + { + memcpy(&i32, src, 4); + f32 = (float)((double)i32 / 2147483648.0); + memcpy(dst, (wuff_uint8 *)&f32 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&i32, src + i * 4, 4); + f32 = (float)((double)i32 / 2147483648.0); + memcpy(dst + i * 4, &f32, 4); + } + + if (tail != 0) + { + memcpy(&i32, src + samples * 4, 4); + f32 = (float)((double)i32 / 2147483648.0); + memcpy(dst + samples * 4, &f32, tail); + } +} + +WUFF_CONV_FUNC(wuff_int32_to_float64) +{ + wuff_sint32 i32; + double f64; + size_t i; + + if (head != 0) + { + memcpy(&i32, src, 4); + f64 = (double)i32 / 2147483648.0; + memcpy(dst, (wuff_uint8 *)&f64 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&i32, src + i * 4, 4); + f64 = (double)i32 / 2147483648.0; + memcpy(dst + i * 8, &f64, 8); + } + + if (tail != 0) + { + memcpy(&i32, src + samples * 4, 4); + f64 = (double)i32 / 2147483648.0; + memcpy(dst + samples * 8, &f64, tail); + } +} + +/* + * float32 functions. + */ + +WUFF_CONV_FUNC(wuff_float32_to_int8) +{ + float f32; + size_t i; + (void)offset; (void)head; (void)tail; + + for (i = 0; i < samples; i++) + { + memcpy(&f32, src + i * 4, 4); + dst[i] = (wuff_uint8)((f32 * 127.5f) + 128.0f); + } +} + +WUFF_CONV_FUNC(wuff_float32_to_int16) +{ + float f32; + wuff_sint16 i16; + size_t i; + + if (head != 0) + { + memcpy(&f32, src, 4); + i16 = (wuff_sint16)(f32 * 32767.5f); + memcpy(dst, (wuff_uint8 *)&i16 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f32, src + i * 4, 4); + i16 = (wuff_sint16)(f32 * 32767.5f); + memcpy(dst + i * 2, &i16, 2); + } + + if (tail != 0) + { + memcpy(&f32, src + i * 4, 4); + i16 = (wuff_sint16)(f32 * 32767.5f); + memcpy(dst + i * 2, &i16, tail); + } +} + +WUFF_CONV_FUNC(wuff_float32_to_int24) +{ + float f32; + wuff_sint32 i24; + size_t i; + + if (head != 0) + { + memcpy(&f32, src, 4); + i24 = (wuff_sint32)((double)f32 * 2147483647.5); + memcpy(dst, (wuff_uint8 *)&i24 + 1 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f32, src + i * 4, 4); + i24 = (wuff_sint32)((double)f32 * 2147483647.5); + memcpy(dst + i * 3, (wuff_uint8 *)&i24 + 1, 3); + } + + if (tail != 0) + { + memcpy(&f32, src + samples * 4, 4); + i24 = (wuff_sint32)((double)f32 * 2147483647.5); + memcpy(dst + samples * 3, (wuff_uint8 *)&i24 + 1, tail); + } +} + +WUFF_CONV_FUNC(wuff_float32_to_int32) +{ + float f32; + wuff_sint32 i32; + size_t i; + + if (head != 0) + { + memcpy(&f32, src, 4); + i32 = (wuff_sint32)((double)f32 * 2147483647.5); + memcpy(dst, (wuff_uint8 *)&i32 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f32, src + i * 4, 4); + i32 = (wuff_sint32)((double)f32 * 2147483647.5); + memcpy(dst + i * 4, &i32, 4); + } + + if (tail != 0) + { + memcpy(&f32, src + samples * 4, 4); + i32 = (wuff_sint32)((double)f32 * 2147483647.5); + memcpy(dst + samples * 4, &i32, tail); + } +} + +WUFF_CONV_FUNC(wuff_float32_to_float32) +{ + memcpy(dst, src + offset, samples * 4 + head + tail); +} + +WUFF_CONV_FUNC(wuff_float32_to_float64) +{ + float f32; + double f64; + size_t i; + + if (head != 0) + { + memcpy(&f32, src, 4); + f64 = f32; + memcpy(dst, (wuff_uint8 *)&f64 + offset, head); + src += 4; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f32, src + i * 4, 4); + f64 = f32; + memcpy(dst + i * 8, &f64, 8); + } + + if (tail != 0) + { + memcpy(&f32, src + samples * 4, 4); + f64 = f32; + memcpy(dst + samples * 8, &f64, tail); + } +} + +/* + * float64 functions. + */ + +WUFF_CONV_FUNC(wuff_float64_to_int8) +{ + double f64; + size_t i; + (void)offset; (void)head; (void)tail; + + for (i = 0; i < samples; i++) + { + memcpy(&f64, src + i * 8, 8); + dst[i] = (wuff_uint8)((f64 * 127.5) + 128.0); + } +} + +WUFF_CONV_FUNC(wuff_float64_to_int16) +{ + double f64; + wuff_sint16 i16; + size_t i; + + if (head != 0) + { + memcpy(&f64, src, 8); + i16 = (wuff_sint16)(f64 * 32767.5); + memcpy(dst, (wuff_uint8 *)&i16 + offset, head); + src += 8; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f64, src + i * 8, 8); + i16 = (wuff_sint16)(f64 * 32767.5); + memcpy(dst + i * 2, &i16, 2); + } + + if (tail != 0) + { + memcpy(&f64, src + i * 8, 8); + i16 = (wuff_sint16)(f64 * 32767.5); + memcpy(dst + i * 2, &i16, tail); + } +} + +WUFF_CONV_FUNC(wuff_float64_to_int24) +{ + double f64; + wuff_sint32 i24; + size_t i; + + if (head != 0) + { + memcpy(&f64, src, 8); + i24 = (wuff_sint32)(f64 * 2147483647.5); + memcpy(dst, (wuff_uint8 *)&i24 + 1 + offset, head); + src += 8; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f64, src + i * 8, 8); + i24 = (wuff_sint32)(f64 * 2147483647.5); + memcpy(dst + i * 3, (wuff_uint8 *)&i24 + 1, 3); + } + + if (tail != 0) + { + memcpy(&f64, src + samples * 8, 8); + i24 = (wuff_sint32)(f64 * 2147483647.5); + memcpy(dst + samples * 3, (wuff_uint8 *)&i24 + 1, tail); + } +} + +WUFF_CONV_FUNC(wuff_float64_to_int32) +{ + double f64; + wuff_sint32 i32; + size_t i; + + if (head != 0) + { + memcpy(&f64, src, 8); + i32 = (wuff_sint32)(f64 * 2147483647.5); + memcpy(dst, (wuff_uint8 *)&i32 + offset, head); + src += 8; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f64, src + i * 8, 8); + i32 = (wuff_sint32)(f64 * 2147483647.5); + memcpy(dst + i * 4, &i32, 4); + } + + if (tail != 0) + { + memcpy(&f64, src + samples * 8, 8); + i32 = (wuff_sint32)(f64 * 2147483647.5); + memcpy(dst + samples * 4, &i32, tail); + } +} + +WUFF_CONV_FUNC(wuff_float64_to_float32) +{ + double f64; + float f32; + size_t i; + + if (head != 0) + { + memcpy(&f64, src, 8); + f32 = (float)f64; + memcpy(dst, (wuff_uint8 *)&f32 + offset, head); + src += 8; + dst += head; + } + + for (i = 0; i < samples; i++) + { + memcpy(&f64, src + i * 8, 8); + f32 = (float)f64; + memcpy(dst + i * 4, &f32, 4); + } + + if (tail != 0) + { + memcpy(&f64, src + samples * 8, 8); + f32 = (float)f64; + memcpy(dst + samples * 4, &f32, tail); + } +} + +WUFF_CONV_FUNC(wuff_float64_to_float64) +{ + memcpy(dst, src + offset, samples * 8 + head + tail); +} diff --git a/src/libraries/Wuff/wuff_convert.h b/src/libraries/Wuff/wuff_convert.h new file mode 100644 index 000000000..280973d25 --- /dev/null +++ b/src/libraries/Wuff/wuff_convert.h @@ -0,0 +1,48 @@ +#ifndef WUFF_CONVERT_H +#define WUFF_CONVERT_H + +#define WUFF_CONV_FUNC(name) WUFF_INTERN_API void name(wuff_uint8 * dst, wuff_uint8 * src, size_t samples, wuff_uint8 offset, wuff_uint8 head, wuff_uint8 tail) + +WUFF_CONV_FUNC(wuff_int8_to_int8); +WUFF_CONV_FUNC(wuff_int8_to_int16); +WUFF_CONV_FUNC(wuff_int8_to_int24); +WUFF_CONV_FUNC(wuff_int8_to_int32); +WUFF_CONV_FUNC(wuff_int8_to_float32); +WUFF_CONV_FUNC(wuff_int8_to_float64); + +WUFF_CONV_FUNC(wuff_int16_to_int8); +WUFF_CONV_FUNC(wuff_int16_to_int16); +WUFF_CONV_FUNC(wuff_int16_to_int24); +WUFF_CONV_FUNC(wuff_int16_to_int32); +WUFF_CONV_FUNC(wuff_int16_to_float32); +WUFF_CONV_FUNC(wuff_int16_to_float64); + +WUFF_CONV_FUNC(wuff_int24_to_int8); +WUFF_CONV_FUNC(wuff_int24_to_int16); +WUFF_CONV_FUNC(wuff_int24_to_int24); +WUFF_CONV_FUNC(wuff_int24_to_int32); +WUFF_CONV_FUNC(wuff_int24_to_float32); +WUFF_CONV_FUNC(wuff_int24_to_float64); + +WUFF_CONV_FUNC(wuff_int32_to_int8); +WUFF_CONV_FUNC(wuff_int32_to_int16); +WUFF_CONV_FUNC(wuff_int32_to_int24); +WUFF_CONV_FUNC(wuff_int32_to_int32); +WUFF_CONV_FUNC(wuff_int32_to_float32); +WUFF_CONV_FUNC(wuff_int32_to_float64); + +WUFF_CONV_FUNC(wuff_float32_to_int8); +WUFF_CONV_FUNC(wuff_float32_to_int16); +WUFF_CONV_FUNC(wuff_float32_to_int24); +WUFF_CONV_FUNC(wuff_float32_to_int32); +WUFF_CONV_FUNC(wuff_float32_to_float32); +WUFF_CONV_FUNC(wuff_float32_to_float64); + +WUFF_CONV_FUNC(wuff_float64_to_int8); +WUFF_CONV_FUNC(wuff_float64_to_int16); +WUFF_CONV_FUNC(wuff_float64_to_int24); +WUFF_CONV_FUNC(wuff_float64_to_int32); +WUFF_CONV_FUNC(wuff_float64_to_float32); +WUFF_CONV_FUNC(wuff_float64_to_float64); + +#endif /* WUFF_CONVERT_H */ diff --git a/src/libraries/Wuff/wuff_internal.c b/src/libraries/Wuff/wuff_internal.c new file mode 100644 index 000000000..e4813329d --- /dev/null +++ b/src/libraries/Wuff/wuff_internal.c @@ -0,0 +1,540 @@ +#include +#include + +#include "wuff_config.h" +#include "wuff.h" +#include "wuff_internal.h" +#include "wuff_convert.h" + + +wuff_sint32 wuff_setup(struct wuff_handle * handle) +{ + wuff_sint32 wuff_status; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + wuff_status = wuff_init_stream(handle); + WUFF_STATUS_BAIL() + + /* Allocating the buffer for the handle requires information from the stream. */ + wuff_status = wuff_buffer_alloc(handle); + WUFF_STATUS_BAIL() + + /* The output format defaults to the stream format. */ + wuff_status = wuff_format(handle, handle->stream.format); + WUFF_STATUS_BAIL() + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_cleanup(struct wuff_handle * handle) +{ + if (handle == NULL) + return WUFF_INVALID_PARAM; + + if (handle->buffer.data != NULL) + wuff_free(handle->buffer.data); + wuff_free(handle); + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_set_output_format(struct wuff_handle * handle, wuff_uint16 format) +{ + wuff_uint16 bits; + wuff_uint16 stream_format; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + else if (format >= WUFF_FORMAT_MAX) + return WUFF_FORMAT_UNSUPPORTED; + + stream_format = handle->stream.format; + + switch (format) + { + case WUFF_FORMAT_PCM_U8: + bits = 8; + switch (stream_format) + { + case WUFF_FORMAT_PCM_U8: + handle->output.function = wuff_int8_to_int8; + break; + case WUFF_FORMAT_PCM_S16: + handle->output.function = wuff_int16_to_int8; + break; + case WUFF_FORMAT_PCM_S24: + handle->output.function = wuff_int24_to_int8; + break; + case WUFF_FORMAT_PCM_S32: + handle->output.function = wuff_int32_to_int8; + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + handle->output.function = wuff_float32_to_int8; + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + handle->output.function = wuff_float64_to_int8; + break; + } + break; + case WUFF_FORMAT_PCM_S16: + bits = 16; + switch (stream_format) + { + case WUFF_FORMAT_PCM_U8: + handle->output.function = wuff_int8_to_int16; + break; + case WUFF_FORMAT_PCM_S16: + handle->output.function = wuff_int16_to_int16; + break; + case WUFF_FORMAT_PCM_S24: + handle->output.function = wuff_int24_to_int16; + break; + case WUFF_FORMAT_PCM_S32: + handle->output.function = wuff_int32_to_int16; + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + handle->output.function = wuff_float32_to_int16; + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + handle->output.function = wuff_float64_to_int16; + break; + } + break; + case WUFF_FORMAT_PCM_S24: + bits = 24; + switch (stream_format) + { + case WUFF_FORMAT_PCM_U8: + handle->output.function = wuff_int8_to_int24; + break; + case WUFF_FORMAT_PCM_S16: + handle->output.function = wuff_int16_to_int24; + break; + case WUFF_FORMAT_PCM_S24: + handle->output.function = wuff_int24_to_int24; + break; + case WUFF_FORMAT_PCM_S32: + handle->output.function = wuff_int32_to_int24; + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + handle->output.function = wuff_float32_to_int24; + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + handle->output.function = wuff_float64_to_int24; + break; + } + break; + case WUFF_FORMAT_PCM_S32: + bits = 32; + switch (stream_format) + { + case WUFF_FORMAT_PCM_U8: + handle->output.function = wuff_int8_to_int32; + break; + case WUFF_FORMAT_PCM_S16: + handle->output.function = wuff_int16_to_int32; + break; + case WUFF_FORMAT_PCM_S24: + handle->output.function = wuff_int24_to_int32; + break; + case WUFF_FORMAT_PCM_S32: + handle->output.function = wuff_int32_to_int32; + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + handle->output.function = wuff_float32_to_int32; + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + handle->output.function = wuff_float64_to_int32; + break; + } + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + bits = 32; + switch (stream_format) + { + case WUFF_FORMAT_PCM_U8: + handle->output.function = wuff_int8_to_float32; + break; + case WUFF_FORMAT_PCM_S16: + handle->output.function = wuff_int16_to_float32; + break; + case WUFF_FORMAT_PCM_S24: + handle->output.function = wuff_int24_to_float32; + break; + case WUFF_FORMAT_PCM_S32: + handle->output.function = wuff_int32_to_float32; + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + handle->output.function = wuff_float32_to_float32; + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + handle->output.function = wuff_float64_to_float32; + break; + } + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + bits = 64; + switch (stream_format) + { + case WUFF_FORMAT_PCM_U8: + handle->output.function = wuff_int8_to_float64; + break; + case WUFF_FORMAT_PCM_S16: + handle->output.function = wuff_int16_to_float64; + break; + case WUFF_FORMAT_PCM_S24: + handle->output.function = wuff_int24_to_float64; + break; + case WUFF_FORMAT_PCM_S32: + handle->output.function = wuff_int32_to_float64; + break; + case WUFF_FORMAT_IEEE_FLOAT_32: + handle->output.function = wuff_float32_to_float64; + break; + case WUFF_FORMAT_IEEE_FLOAT_64: + handle->output.function = wuff_float64_to_float64; + break; + } + break; + default: + return WUFF_FORMAT_UNSUPPORTED; + } + + handle->output.format = format; + handle->output.bytes_per_sample = bits / 8; + handle->output.block_size = handle->stream.header.channels * (bits / 8); + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_check_bits(wuff_uint16 bits, wuff_uint16 * format) +{ + if (*format == WUFF_FORMAT_PCM) + { + switch (bits) + { + case 8: + *format = WUFF_FORMAT_PCM_U8; + break; + case 16: + *format = WUFF_FORMAT_PCM_S16; + break; + case 24: + *format = WUFF_FORMAT_PCM_S24; + break; + case 32: + *format = WUFF_FORMAT_PCM_S32; + break; + default: + return WUFF_FORMAT_UNSUPPORTED; + } + } + else if (*format == WUFF_FORMAT_IEEE_FLOAT) + { + switch (bits) + { + case 32: + *format = WUFF_FORMAT_IEEE_FLOAT_32; + break; + case 64: + *format = WUFF_FORMAT_IEEE_FLOAT_64; + break; + default: + return WUFF_FORMAT_UNSUPPORTED; + } + } + else + { + return WUFF_FORMAT_UNSUPPORTED; + } + + return WUFF_SUCCESS; +} + +size_t wuff_calculate_samples(size_t target_size, wuff_uint8 sample_size, wuff_uint8 * head, wuff_uint8 * tail) +{ + size_t samples = 0; + + if (*head != 0) + { + if (target_size <= *head) + { + *head = (wuff_uint8)target_size; + *tail = 0; + return 1; + } + target_size -= *head; + ++samples; + } + + samples = target_size / sample_size; + *tail = target_size % sample_size; + if (*tail != 0) + ++samples; + return samples; +} + +wuff_sint32 wuff_init_stream(struct wuff_handle * handle) +{ + /* Allocate some space on the stack. */ + /* No need to do dynamic allocation for simple header probing. */ + wuff_uint8 buffer[WUFF_HEADER_FETCH_SIZE]; + size_t buffer_size = WUFF_HEADER_FETCH_SIZE; + wuff_uint64 search_offset; + struct wuff_chunk_header chunk; + wuff_sint32 wuff_status; + + wuff_status = handle->callback->read(handle->userdata, buffer, &buffer_size); + WUFF_STATUS_BAIL() + else if (buffer_size < WUFF_STREAM_MIN_SIZE) + return WUFF_STREAM_NOT_RIFF; + + /* Check for RIFF signature. */ + wuff_copy_chunk_header_data(&chunk, buffer); + if (chunk.id != WUFF_RIFF_CHUNK_ID) + return WUFF_STREAM_NOT_RIFF; + handle->stream.size = chunk.size; + + /* Check for WAVE format. */ + wuff_copy_chunk_header_data(&chunk, buffer + 8); + if (chunk.id != WUFF_WAVE_CHUNK_ID) + return WUFF_STREAM_NOT_WAVE; + + /* Search fmt chunk. */ + wuff_copy_chunk_header_data(&chunk, buffer + 12); + search_offset = 12; + if (chunk.id != WUFF_FORMAT_CHUNK_ID) + { + chunk.id = 0; + /* The fmt chunk must appear before the data chunk. */ + wuff_status = wuff_search_chunk(handle, &chunk, &search_offset, WUFF_FORMAT_CHUNK_ID, WUFF_DATA_CHUNK_ID); + if (wuff_status == WUFF_STREAM_CHUNK_NOT_FOUND) + return WUFF_STREAM_FORMAT_CHUNK_MISSING; + else WUFF_STATUS_BAIL() + + /* In case the fmt chunk is not the first chunk, align it on the stack buffer as if it were. */ + buffer_size = WUFF_HEADER_FETCH_SIZE - 20; + wuff_status = handle->callback->read(handle->userdata, buffer + 20, &buffer_size); + WUFF_STATUS_BAIL() + /* EOF bail. */ + else if (buffer_size < WUFF_HEADER_MIN_SIZE) + return WUFF_STREAM_INVALID; + } + + /* Extract header information. */ + handle->stream.header.size = chunk.size; + handle->stream.header.offset = search_offset + 8; + handle->stream.header.format = wuff_get_uint16(buffer + 20); + handle->stream.header.channels = wuff_get_uint16(buffer + 22); + handle->stream.header.sample_rate = wuff_get_uint32(buffer + 24); + handle->stream.header.bits_per_sample = wuff_get_uint16(buffer + 34); + handle->stream.header.bytes_per_sample = handle->stream.header.bits_per_sample / 8; + handle->stream.header.block_size = handle->stream.header.channels * handle->stream.header.bytes_per_sample; + + /* Bail on invalid streams. */ + if (handle->stream.header.channels == 0) + return WUFF_STREAM_ZERO_CHANNELS; + else if (handle->stream.header.sample_rate == 0) + return WUFF_STREAM_ZERO_SAMPLE_RATE; + else if (handle->stream.header.bits_per_sample == 0) + return WUFF_STREAM_ZERO_BITS_PER_SAMPLE; + + /* Grab the format from the extended header. */ + if (handle->stream.header.size > WUFF_HEADER_MIN_SIZE && wuff_get_uint16(buffer + 36) == 22) + { + if (handle->stream.header.format == WUFF_FORMAT_EXTENSIBLE) + handle->stream.header.format = wuff_get_uint16(buffer + 44); + } + + /* The check if this format is actually supported. */ + handle->stream.format = handle->stream.header.format; + wuff_status = wuff_check_bits(handle->stream.header.bits_per_sample, &handle->stream.format); + WUFF_STATUS_BAIL() + + /* The search for the data chunk begins. */ + wuff_copy_chunk_header_data(&chunk, buffer + 20 + handle->stream.header.size); + search_offset = handle->stream.header.offset + handle->stream.header.size; + wuff_status = wuff_search_chunk(handle, &chunk, &search_offset, WUFF_DATA_CHUNK_ID, 0); + if (wuff_status == WUFF_STREAM_CHUNK_NOT_FOUND) + return WUFF_STREAM_DATA_CHUNK_MISSING; + else WUFF_STATUS_BAIL() + + handle->stream.data.size = chunk.size; + handle->stream.data.offset = search_offset + 8; + handle->stream.length = handle->stream.data.size / handle->stream.header.channels / handle->stream.header.bytes_per_sample; + handle->stream.position = 0; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_search_chunk(struct wuff_handle * handle, struct wuff_chunk_header * chunk, wuff_uint64 * offset, wuff_uint32 id, wuff_uint32 stop_id) +{ + wuff_uint8 buffer[8]; + wuff_uint64 search_offset; + size_t buffer_size; + wuff_sint32 wuff_status = 0; + + if (chunk->id != 0 && chunk->id == id) + return WUFF_SUCCESS; + + /* Copy the current file position. */ + search_offset = *offset; + + while (wuff_status >= 0) + { + search_offset += 8 + chunk->size; + /* FIXME: Non-compliant RIFFs may not pad to WORD alignment. What now? */ + if (search_offset & 1) + search_offset++; + + wuff_status = handle->callback->seek(handle->userdata, search_offset); + WUFF_STATUS_BAIL() + /*else if (wuff_status == WUFF_CALLBACK_EOF) + return WUFF_STREAM_CHUNK_NOT_FOUND;*/ + + buffer_size = 8; + wuff_status = handle->callback->read(handle->userdata, buffer, &buffer_size); + WUFF_STATUS_BAIL() + + wuff_copy_chunk_header_data(chunk, buffer); + /* Bail if we're at the EOF or the stop id. */ + if (buffer_size < 8 || (stop_id != 0 && chunk->id == stop_id)) + return WUFF_STREAM_CHUNK_NOT_FOUND; + else if (chunk->id == id) + break; + } + + /* Report chunk offset. */ + *offset = search_offset; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_buffer_alloc(struct wuff_handle * handle) +{ + wuff_sint32 wuff_status; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + /* Try to allocate a buffer for 0.25 seconds, but clamp at some minimum and maximum value. */ + handle->buffer.size = handle->stream.header.sample_rate * handle->stream.header.block_size / 4; + if (handle->buffer.size < WUFF_BUFFER_MIN_SIZE) + handle->buffer.size = WUFF_BUFFER_MIN_SIZE; + else if (handle->buffer.size > WUFF_BUFFER_MAX_SIZE) + handle->buffer.size = WUFF_BUFFER_MAX_SIZE; + + handle->buffer.data = wuff_alloc(handle->buffer.size); + if (handle->buffer.data == NULL) + return WUFF_MEMALLOC_ERROR; + + /* Just in case, let's null the offsets. */ + wuff_status = wuff_buffer_clear(handle); + WUFF_STATUS_BAIL() + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_buffer_clear(struct wuff_handle * handle) +{ + wuff_uint64 position; + wuff_sint32 wuff_status; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + wuff_status = handle->callback->tell(handle->userdata, &position); + WUFF_STATUS_BAIL() + + if (position < handle->stream.data.offset || position > handle->stream.data.offset + handle->stream.data.size) + return WUFF_BUFFER_INVALID_STREAM_POSITION; + + handle->buffer.bytes_left = handle->stream.data.size - (position - handle->stream.data.offset); + handle->buffer.offset = 0; + handle->buffer.end = 0; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_buffer_fill(struct wuff_handle * handle) +{ + size_t bytes_in_buffer; + size_t bytes_to_read; + wuff_sint32 wuff_status; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + /* Check if there are bytes in the buffer and move them to the start of the buffer. */ + /* Probably not the most efficient way. Think on it some more! */ + bytes_in_buffer = handle->buffer.end - handle->buffer.offset; + + if (bytes_in_buffer == handle->buffer.size) + return WUFF_SUCCESS; + else if (bytes_in_buffer > 0) + memmove(handle->buffer.data, handle->buffer.data + handle->buffer.offset, bytes_in_buffer); + + bytes_to_read = handle->buffer.size - bytes_in_buffer; + if (bytes_to_read > handle->buffer.bytes_left) + bytes_to_read = (size_t)handle->buffer.bytes_left; + + wuff_status = handle->callback->read(handle->userdata, handle->buffer.data + bytes_in_buffer, &bytes_to_read); + WUFF_STATUS_BAIL() + + handle->buffer.offset = 0; + handle->buffer.end = bytes_in_buffer + bytes_to_read; + handle->buffer.bytes_left -= bytes_to_read; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_buffer_release(struct wuff_handle * handle, size_t samples) +{ + size_t size; + + if (handle == NULL) + return WUFF_INVALID_PARAM; + + size = samples * handle->stream.header.bytes_per_sample; + + /* Check for an attempt to release more samples than the buffer could hold. */ + /* "This should never happen." Let's throw an error anyway in case.*/ + if (size > handle->buffer.end - handle->buffer.offset) + return WUFF_BUFFER_INVALID_SIZE; + + handle->buffer.offset += size; + + return WUFF_SUCCESS; +} + +wuff_sint32 wuff_buffer_request(struct wuff_handle * handle, wuff_uint8 ** buffer, size_t * samples) +{ + size_t request_samples = *samples; + size_t buffer_samples, size; + size_t bps = handle->stream.header.bytes_per_sample; + wuff_sint32 wuff_status; + + if (handle == NULL || buffer == NULL || samples == NULL) + return WUFF_INVALID_PARAM; + + /* Fill the buffer some more if the requested size is bigger than the current data in the buffer. */ + size = request_samples * bps; + if (size > handle->buffer.end - handle->buffer.offset) + { + wuff_status = wuff_buffer_fill(handle); + WUFF_STATUS_BAIL() + } + + buffer_samples = (handle->buffer.end - handle->buffer.offset) / bps; + + /* Report sample count change. */ + if (buffer_samples < request_samples) + *samples = buffer_samples; + + /* Report sample buffer start. */ + *buffer = handle->buffer.data + handle->buffer.offset; + + return WUFF_SUCCESS; +} diff --git a/src/libraries/Wuff/wuff_internal.h b/src/libraries/Wuff/wuff_internal.h new file mode 100644 index 000000000..2679cdbcb --- /dev/null +++ b/src/libraries/Wuff/wuff_internal.h @@ -0,0 +1,171 @@ +#ifndef WUFF_INTERNAL_H +#define WUFF_INTERNAL_H + +#define WUFF_BUFFER_MIN_SIZE 4096 +#define WUFF_BUFFER_MAX_SIZE 2097152 +#define WUFF_STREAM_MIN_SIZE 36 +#define WUFF_HEADER_MIN_SIZE 16 +#define WUFF_HEADER_FETCH_SIZE 80 + +#define WUFF_FORMAT_PCM 1 +#define WUFF_FORMAT_IEEE_FLOAT 3 +#define WUFF_FORMAT_EXTENSIBLE 0xFFFE + + +#define WUFF_RIFF_CHUNK_ID wuff_get_chunk_id("RIFF") +#define WUFF_WAVE_CHUNK_ID wuff_get_chunk_id("WAVE") +#define WUFF_FORMAT_CHUNK_ID wuff_get_chunk_id("fmt ") +#define WUFF_DATA_CHUNK_ID wuff_get_chunk_id("data") + +#define WUFF_STATUS_BAIL() if (wuff_status < 0) return wuff_status; + + +static WUFF_INLINE wuff_uint32 wuff_get_uint32(wuff_uint8 * data) +{ + return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24); +} + +static WUFF_INLINE wuff_uint16 wuff_get_uint16(wuff_uint8 * data) +{ + return data[0] + (data[1] << 8); +} + +struct wuff_chunk_header +{ + wuff_uint32 id; + wuff_uint32 size; +}; + +static WUFF_INLINE wuff_uint32 wuff_get_chunk_id(const char txt[5]) +{ + const wuff_uint8 * id = (wuff_uint8*) txt; + wuff_uint32 int_id; + wuff_uint8 * id_bytes = (wuff_uint8 *)&int_id; + id_bytes[0] = id[0]; + id_bytes[1] = id[1]; + id_bytes[2] = id[2]; + id_bytes[3] = id[3]; + + return int_id; +} + +static WUFF_INLINE void wuff_copy_chunk_header_data(struct wuff_chunk_header * chunk, wuff_uint8 * data) +{ + wuff_uint8 * id = (wuff_uint8 *)&chunk->id; + id[0] = data[0]; + id[1] = data[1]; + id[2] = data[2]; + id[3] = data[3]; + + chunk->size = wuff_get_uint32(data + 4); +} + +struct wuff_stream_header +{ + wuff_uint64 size; + wuff_uint64 offset; + + wuff_uint16 format; + wuff_uint16 channels; + wuff_uint32 sample_rate; + wuff_uint16 bits_per_sample; + wuff_uint16 bytes_per_sample; + size_t block_size; +}; + +struct wuff_stream_data +{ + wuff_uint64 size; + wuff_uint64 offset; +}; + +struct wuff_buffer +{ + wuff_uint8 * data; + wuff_uint64 bytes_left; + size_t size; + size_t offset; + size_t end; +}; + +struct wuff_output +{ + wuff_uint16 format; + size_t bytes_per_sample; + size_t block_size; + size_t block_offset; + void (* function)(wuff_uint8 *, wuff_uint8 *, size_t, wuff_uint8, wuff_uint8, wuff_uint8); +}; + +struct wuff_stream +{ + wuff_uint64 size; + wuff_uint64 length; + wuff_uint16 format; + + wuff_uint64 position; + + struct wuff_stream_header header; + struct wuff_stream_data data; +}; + +struct wuff_handle +{ + struct wuff_stream stream; + struct wuff_buffer buffer; + struct wuff_output output; + struct wuff_callback * callback; + void * userdata; +}; + + +/* Initializes the stream, allocates the buffer, and sets the output format. */ +/* Expects a nulled wuff_handle and the callbacks set and ready. */ +WUFF_INTERN_API wuff_sint32 wuff_setup(struct wuff_handle * handle); + +/* Cleans the stream up, frees the buffer and the wuff_handle. */ +WUFF_INTERN_API wuff_sint32 wuff_cleanup(struct wuff_handle * handle); + +/* Called by wuff_setup. Initializes the stream by reading the data from the */ +/* callbacks, searching for headers and stream information. */ +WUFF_INTERN_API wuff_sint32 wuff_init_stream(struct wuff_handle * handle); + +/* Searches for a specific chunk id and stops before another if it's not 0. */ +/* If the id in wuff_chunk_header is not 0, it will be checked too and if */ +/* they match, then the function will return immediately. */ +/* Expects offset to point to the file position of a chunk and */ +/* wuff_chunk_header to have the size of this chunk. */ +WUFF_INTERN_API wuff_sint32 wuff_search_chunk(struct wuff_handle * handle, struct wuff_chunk_header * chunk, wuff_uint64 * offset, wuff_uint32 id, wuff_uint32 stop_id); + +/* Sets the output struct of the stream to the new format. */ +WUFF_INTERN_API wuff_sint32 wuff_set_output_format(struct wuff_handle * handle, wuff_uint16); + +/* Checks if the number of bits per samples is supported and writes the */ +/* output identifier to the 16-bit integer. */ +WUFF_INTERN_API wuff_sint32 wuff_check_bits(wuff_uint16 bits, wuff_uint16 * format); + +/* Calculates the number of samples that have to be requested from the buffer */ +/* by also taking the truncated samples at the start and end into account. */ +/* The return value is the number of samples needed. */ +WUFF_INTERN_API size_t wuff_calculate_samples(size_t target_size, wuff_uint8 sample_size, wuff_uint8 * head, wuff_uint8 * tail); + + +/* Allocates the buffer for the input stream. */ +/* Expects the stream to be initialized, as format information is needed. */ +WUFF_INTERN_API wuff_sint32 wuff_buffer_alloc(struct wuff_handle * handle); + +/* Fills the buffer with new data. */ +WUFF_INTERN_API wuff_sint32 wuff_buffer_fill(struct wuff_handle * handle); + +/* Marks all bytes in the buffer as free. */ +WUFF_INTERN_API wuff_sint32 wuff_buffer_clear(struct wuff_handle * handle); + +/* Requests samples and a pointer to them. */ +/* The number of samples may be lower than requested. */ +WUFF_INTERN_API wuff_sint32 wuff_buffer_request(struct wuff_handle * handle, wuff_uint8 ** buffer, size_t * samples); + +/* Releases the number of samples from the buffer. */ +WUFF_INTERN_API wuff_sint32 wuff_buffer_release(struct wuff_handle * handle, size_t samples); + + +#endif /* WUFF_INTERNAL_H */ diff --git a/src/libraries/Wuff/wuff_memory.c b/src/libraries/Wuff/wuff_memory.c new file mode 100644 index 000000000..eaffa4e62 --- /dev/null +++ b/src/libraries/Wuff/wuff_memory.c @@ -0,0 +1,17 @@ +#include + +#include "wuff_config.h" + +/* Default memory allocators. */ +/* They can be overridden with custom functions at build time. */ +#ifndef WUFF_MEMALLOC_OVERRIDE +void * wuff_alloc(size_t size) +{ + return malloc(size); +} + +void wuff_free(void * mem) +{ + free(mem); +} +#endif diff --git a/src/libraries/ddsparse/ddsinfo.h b/src/libraries/ddsparse/ddsinfo.h new file mode 100644 index 000000000..59760d0fe --- /dev/null +++ b/src/libraries/ddsparse/ddsinfo.h @@ -0,0 +1,235 @@ +/** + * Simple DDS data parser for compressed 2D textures. + * + * Copyright (c) 2013 Alexander Szpakowski. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * Enums and structs copied from Microsoft. + * http://msdn.microsoft.com/en-us/library/bb943991.aspx + **/ + +#ifndef DDS_INFO_H +#define DDS_INFO_H + +#include + +namespace dds +{ +namespace dxinfo +{ + +enum DDPF +{ + DDPF_ALPHAPIXELS = 0x000001, + DDPF_ALPHA = 0x000002, + DDPF_FOURCC = 0x000004, + DDPF_RGB = 0x000040, + DDPF_YUV = 0x000200, + DDPF_LUMINANCE = 0x020000 +}; + +enum D3D10ResourceDimension +{ + D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D10_RESOURCE_DIMENSION_BUFFER = 1, + D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4 +}; + +enum DXGIFormat +{ + DXGI_FORMAT_UNKNOWN = 0, + + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + + DXGI_FORMAT_R11G11B10_FLOAT = 26, + + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + + DXGI_FORMAT_R1_UNORM = 66, + + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, + + DXGI_FORMAT_BC6H_TYPELESS = 94, + DXGI_FORMAT_BC6H_UF16 = 95, + DXGI_FORMAT_BC6H_SF16 = 96, + + DXGI_FORMAT_BC7_TYPELESS = 97, + DXGI_FORMAT_BC7_UNORM = 98, + DXGI_FORMAT_BC7_UNORM_SRGB = 99, + + DXGI_FORMAT_FORCE_UINT = 0xffffffffUL +}; + +struct DDSPixelFormat +{ + uint32_t size; + uint32_t flags; + uint32_t fourCC; + uint32_t rgbBitCount; + uint32_t rBitMask; + uint32_t gBitMask; + uint32_t bBitMask; + uint32_t aBitMask; +}; + +struct DDSHeader +{ + uint32_t size; + uint32_t flags; + uint32_t height; + uint32_t width; + uint32_t pitchOrLinearSize; + uint32_t depth; + uint32_t mipMapCount; + uint32_t reserved[11]; + + DDSPixelFormat format; + + uint32_t caps1; + uint32_t caps2; + uint32_t caps3; + uint32_t caps4; + uint32_t reserved2; +}; + +struct DDSHeader10 +{ + DXGIFormat dxgiFormat; + D3D10ResourceDimension resourceDimension; + + uint32_t miscFlag; + uint32_t arraySize; + uint32_t reserved; +}; + +} // dxinfo +} // dds + +#endif // DDS_INFO_H diff --git a/src/libraries/ddsparse/ddsparse.cpp b/src/libraries/ddsparse/ddsparse.cpp new file mode 100644 index 000000000..590d665ce --- /dev/null +++ b/src/libraries/ddsparse/ddsparse.cpp @@ -0,0 +1,356 @@ +/** + * Simple DDS data parser for compressed 2D textures. + * + * Copyright (c) 2013 Alexander Szpakowski. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **/ + +#include "ddsparse.h" +#include "ddsinfo.h" + +#include + +namespace dds +{ + +using namespace dds::dxinfo; + +// Creates a packed uint representation of a FourCC code. +#define MakeFourCC(a, b, c, d) ((uint32_t) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))) + +// Translate the old DDS format to our own. +static Format parseDDSFormat(const DDSPixelFormat &fmt) +{ + if ((fmt.flags & DDPF_FOURCC) == 0) + return FORMAT_UNKNOWN; + + Format f = FORMAT_UNKNOWN; + + switch (fmt.fourCC) + { + case MakeFourCC('D','X','T','1'): + f = FORMAT_DXT1; + break; + case MakeFourCC('D','X','T','3'): + f = FORMAT_DXT3; + break; + case MakeFourCC('D','X','T','5'): + f = FORMAT_DXT5; + break; + case MakeFourCC('A','T','I','1'): + case MakeFourCC('B','C','4','U'): + f = FORMAT_BC4; + break; + case MakeFourCC('B','C','4','S'): + f = FORMAT_BC4s; + break; + case MakeFourCC('A','T','I','2'): + case MakeFourCC('B','C','5','U'): + f = FORMAT_BC5; + break; + case MakeFourCC('B','C','5','S'): + f = FORMAT_BC5s; + break; + default: + break; + } + + return f; +} + +// Translate the new DX10 formats to our own. +static Format parseDX10Format(DXGIFormat fmt) +{ + Format f = FORMAT_UNKNOWN; + + switch (fmt) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + f = FORMAT_DXT1; + break; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + f = FORMAT_DXT3; + break; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + f = FORMAT_DXT5; + break; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + f = FORMAT_BC4; + break; + case DXGI_FORMAT_BC4_SNORM: + f = FORMAT_BC4s; + break; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + f = FORMAT_BC5; + break; + case DXGI_FORMAT_BC5_SNORM: + f = FORMAT_BC5s; + break; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + f = FORMAT_BC6H; + break; + case DXGI_FORMAT_BC6H_SF16: + f = FORAMT_BC6Hs; + break; + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + f = FORMAT_BC7; + break; + case DXGI_FORMAT_BC7_UNORM_SRGB: + f = FORMAT_BC7srgb; + break; + default: + break; + } + + return f; +} + +bool isDDS(const void *data, size_t dataSize) +{ + const uint8_t *readData = (const uint8_t *) data; + ptrdiff_t offset = 0; + + // Is the data large enough to hold the DDS header? + if(dataSize < sizeof(uint32_t) + sizeof(DDSHeader)) + return false; + + // All DDS files start with "DDS ". + if((*(uint32_t *) readData) != MakeFourCC('D','D','S',' ')) + return false; + + offset += sizeof(uint32_t); + + DDSHeader *header = (DDSHeader *) &readData[offset]; + + + // Verify header to validate DDS data. + if (header->size != sizeof(DDSHeader) || header->format.size != sizeof(DDSPixelFormat)) + return false; + + offset += sizeof(DDSHeader); + + // Check for DX10 extension. + if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0'))) + { + // Data must be big enough for both headers plus the magic value. + if (dataSize < (sizeof(uint32_t) + sizeof(DDSHeader) + sizeof(DDSHeader10))) + return false; + } + + return true; +} + +bool isCompressedDDS(const void *data, size_t dataSize) +{ + if (!isDDS(data, dataSize)) + return false; + + const uint8_t *readData = (const uint8_t *) data; + ptrdiff_t offset = sizeof(uint32_t); + + DDSHeader *header = (DDSHeader *) &readData[offset]; + offset += sizeof(DDSHeader); + + // Check for DX10 extension. + if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0'))) + { + DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset]; + return parseDX10Format(header10->dxgiFormat) != FORMAT_UNKNOWN; + } + + return parseDDSFormat(header->format) != FORMAT_UNKNOWN; +} + +Parser::Parser(const void *data, size_t dataSize) + : format(FORMAT_UNKNOWN) +{ + parseData(data, dataSize); +} + +Parser::Parser(const Parser &other) + : texData(other.texData) + , format(other.format) +{ +} + +Parser::Parser() + : format(FORMAT_UNKNOWN) +{ +} + +Parser &Parser::operator = (const Parser &other) +{ + texData = other.texData; + format = other.format; + + return *this; +} + +Parser::~Parser() +{ +} + +Format Parser::getFormat() const +{ + return format; +} + +const Image *Parser::getImageData(size_t miplevel) const +{ + if (miplevel >= texData.size()) + return 0; + + return &texData[miplevel]; +} + +size_t Parser::getMipmapCount() const +{ + return texData.size(); +} + +size_t Parser::parseImageSize(Format fmt, int width, int height) const +{ + size_t size = 0; + + switch (fmt) + { + case FORMAT_DXT1: + case FORMAT_DXT3: + case FORMAT_DXT5: + case FORMAT_BC5s: + case FORMAT_BC5: + case FORMAT_BC7: + case FORMAT_BC7srgb: + { + int numBlocksWide = 0; + if (width > 0) + numBlocksWide = std::max(1, (width + 3) / 4); + + int numBlocksHigh = 0; + if (height > 0) + numBlocksHigh = std::max(1, (height + 3) / 4); + + int numBytesPerBlock = (fmt == FORMAT_DXT1 ? 8 : 16); + + size = numBlocksWide * numBytesPerBlock * numBlocksHigh; + } + break; + default: + break; + } + + return size; +} + +bool Parser::parseTexData(const uint8_t *data, size_t dataSize, Format fmt, int w, int h, int mips) +{ + size_t offset = 0; + std::vector newTexData; + + for (int i = 0; i < mips; i++) + { + Image img; + img.width = w; + img.height = h; + + img.dataSize = parseImageSize(fmt, img.width, img.height); + + // Make sure the data size is valid. + if (img.dataSize == 0 || (offset + img.dataSize) > dataSize) + return false; + + // Store the memory address of the data representing this mip level. + img.data = &data[offset]; + + newTexData.push_back(img); + + // Move to the next mip level. + offset += img.dataSize; + + w = std::max(w / 2, 1); + h = std::max(h / 2, 1); + } + + texData = newTexData; + + return true; +} + +bool Parser::parseData(const void *data, size_t dataSize) +{ + if (!isDDS(data, dataSize)) + return false; + + const uint8_t *readData = (const uint8_t *) data; + ptrdiff_t offset = sizeof(uint32_t); + + DDSHeader *header = (DDSHeader *) &readData[offset]; + offset += sizeof(DDSHeader); + + + // Check for DX10 extension. + if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0'))) + { + DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset]; + offset += sizeof(DDSHeader10); + + // We can't deal with 1D/3D textures. + switch (header10->resourceDimension) + { + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + case D3D10_RESOURCE_DIMENSION_UNKNOWN: + break; + default: + return false; + } + + // We also can't deal with texture arrays and cubemaps. + if (header10->arraySize > 1) + return false; + + format = parseDX10Format(header10->dxgiFormat); + } + else + format = parseDDSFormat(header->format); + + + if (format == FORMAT_UNKNOWN) + return false; + + + int w = header->width; + int h = header->height; + + int mips = std::max((int) header->mipMapCount, 1); + + return parseTexData(&readData[offset], dataSize - offset, format, w, h, mips); +} + +} // dds diff --git a/src/libraries/ddsparse/ddsparse.h b/src/libraries/ddsparse/ddsparse.h new file mode 100644 index 000000000..82c2c41cc --- /dev/null +++ b/src/libraries/ddsparse/ddsparse.h @@ -0,0 +1,137 @@ +/** + * Simple DDS data parser for compressed 2D textures. + * + * Copyright (c) 2013 Alexander Szpakowski. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **/ + +#ifndef DDS_PARSE_H +#define DDS_PARSE_H + +#include +#include + +#include + +namespace dds +{ + +// Supported DDS formats. +// Formats with an 's' suffix have signed data. +enum Format +{ + FORMAT_DXT1, + FORMAT_DXT3, + FORMAT_DXT5, + FORMAT_BC4, + FORMAT_BC4s, + FORMAT_BC5, + FORMAT_BC5s, + FORMAT_BC6H, + FORAMT_BC6Hs, + FORMAT_BC7, + FORMAT_BC7srgb, // sRGB color space. + FORMAT_UNKNOWN +}; + +// Represents a single mipmap level of a texture. +struct Image +{ + int width; + int height; + size_t dataSize; + const uint8_t *data; + + Image() : width(0), height(0), dataSize(0), data(0) + {}; +}; + +/** + * Determines whether the input byte data represents a valid DDS file. + * Does not take into account whether the texture format is supported. + * + * @param data The byte data to parse. + * @param dataSize The size in bytes of the data. + **/ +bool isDDS(const void *data, size_t dataSize); + +/** + * Determines whether the input byte data represents a valid compressed DDS + * file. Takes into account texture format, but not type (3D textures, etc.) + * + * @param data The byte data to parse. + * @param dataSize The size in bytes of the data. + **/ +bool isCompressedDDS(const void *data, size_t dataSize); + +class Parser +{ +public: + + /** + * Constructor. + * Attempts to parse byte data as a compressed DDS file. + * + * @param data The byte data to parse. + * @param dataSize The size in bytes of the data. + **/ + Parser(const void *data, size_t dataSize); + Parser(const Parser &other); + Parser(); + + Parser &operator = (const Parser &other); + + ~Parser(); + + /** + * Gets the format of this texture. + **/ + Format getFormat() const; + + /** + * Gets the data of this texture at a mipmap level. Mipmap level 0 + * represents the base image. + * + * @param miplevel The mipmap level to get the data of. + * @return Pointer to the image data, or NULL if miplevel is not within the + * range of [0, numMipmaps). + **/ + const Image *getImageData(size_t miplevel = 0) const; + + /** + * Gets the number of mipmap levels in this texture. + * Includes the base mip level. + **/ + size_t getMipmapCount() const; + +private: + + size_t parseImageSize(Format fmt, int width, int height) const; + bool parseTexData(const uint8_t *data, size_t dataSize, Format fmt, int w, int h, int mips); + bool parseData(const void *data, size_t dataSize); + + std::vector texData; + Format format; + +}; // Parser + +} // dds + +#endif // DDS_PARSE_H diff --git a/src/libraries/enet/enet.cpp b/src/libraries/enet/enet.cpp new file mode 100644 index 000000000..836c166c6 --- /dev/null +++ b/src/libraries/enet/enet.cpp @@ -0,0 +1,756 @@ +/** + * + * Copyright (C) 2011 by Leaf Corcoran + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +extern "C" { +#define LUA_COMPAT_ALL +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +#include +} + +#define check_host(l, idx)\ + *(ENetHost**)luaL_checkudata(l, idx, "enet_host") + +#define check_peer(l, idx)\ + *(ENetPeer**)luaL_checkudata(l, idx, "enet_peer") + +/** + * Parse address string, eg: + * *:5959 + * 127.0.0.1:* + * website.com:8080 + */ +static void parse_address(lua_State *l, const char *addr_str, ENetAddress *address) { + int host_i = 0, port_i = 0; + char host_str[128] = {0}; + char port_str[32] = {0}; + int scanning_port = 0; + + char *c = (char *)addr_str; + + while (*c != 0) { + if (host_i >= 128 || port_i >= 32 ) luaL_error(l, "Hostname too long"); + if (scanning_port) { + port_str[port_i++] = *c; + } else { + if (*c == ':') { + scanning_port = 1; + } else { + host_str[host_i++] = *c; + } + } + c++; + } + host_str[host_i] = '\0'; + port_str[port_i] = '\0'; + + if (host_i == 0) luaL_error(l, "Failed to parse address"); + if (port_i == 0) luaL_error(l, "Missing port in address"); + + if (strcmp("*", host_str) == 0) { + address->host = ENET_HOST_ANY; + } else { + if (enet_address_set_host(address, host_str) != 0) { + luaL_error(l, "Failed to resolve host name"); + } + } + + if (strcmp("*", port_str) == 0) { + address->port = ENET_PORT_ANY; + } else { + address->port = atoi(port_str); + } +} + +/** + * Find the index of a given peer for which we only have the pointer. + */ +size_t find_peer_index (lua_State *l, ENetHost *enet_host, ENetPeer *peer) { + size_t peer_index; + for (peer_index = 0; peer_index < enet_host->peerCount; peer_index++) { + if (peer == &(enet_host->peers[peer_index])) + return peer_index; + } + + luaL_error (l, "enet: could not find peer id!"); + + return peer_index; +} + +static void push_peer(lua_State *l, ENetPeer *peer) { + // try to find in peer table + lua_getfield(l, LUA_REGISTRYINDEX, "enet_peers"); + lua_pushlightuserdata(l, peer); + lua_gettable(l, -2); + + if (lua_isnil(l, -1)) { + // printf("creating new peer\n"); + lua_pop(l, 1); + + *(ENetPeer**)lua_newuserdata(l, sizeof(void*)) = peer; + luaL_getmetatable(l, "enet_peer"); + lua_setmetatable(l, -2); + + lua_pushlightuserdata(l, peer); + lua_pushvalue(l, -2); + + lua_settable(l, -4); + } + lua_remove(l, -2); // remove enet_peers +} + +static void push_event(lua_State *l, ENetEvent *event) { + lua_newtable(l); // event table + + if (event->peer) { + push_peer(l, event->peer); + lua_setfield(l, -2, "peer"); + } + + switch (event->type) { + case ENET_EVENT_TYPE_CONNECT: + lua_pushinteger(l, event->data); + lua_setfield(l, -2, "data"); + + lua_pushstring(l, "connect"); + break; + case ENET_EVENT_TYPE_DISCONNECT: + lua_pushinteger(l, event->data); + lua_setfield(l, -2, "data"); + + lua_pushstring(l, "disconnect"); + break; + case ENET_EVENT_TYPE_RECEIVE: + lua_pushlstring(l, (const char *)event->packet->data, event->packet->dataLength); + lua_setfield(l, -2, "data"); + + lua_pushinteger(l, event->channelID); + lua_setfield(l, -2, "channel"); + + lua_pushstring(l, "receive"); + + enet_packet_destroy(event->packet); + break; + case ENET_EVENT_TYPE_NONE: + lua_pushstring(l, "none"); + break; + } + + lua_setfield(l, -2, "type"); +} + +/** + * Read a packet off the stack as a string + * idx is position of string + */ +static ENetPacket *read_packet(lua_State *l, int idx, enet_uint8 *channel_id) { + size_t size; + int argc = lua_gettop(l); + const void *data = luaL_checklstring(l, idx, &size); + ENetPacket *packet; + + enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE; + *channel_id = 0; + + if (argc >= idx+2 && !lua_isnil(l, idx+2)) { + const char *flag_str = luaL_checkstring(l, idx+2); + if (strcmp("unsequenced", flag_str) == 0) { + flags = ENET_PACKET_FLAG_UNSEQUENCED; + } else if (strcmp("reliable", flag_str) == 0) { + flags = ENET_PACKET_FLAG_RELIABLE; + } else if (strcmp("unreliable", flag_str) == 0) { + flags = 0; + } else { + luaL_error(l, "Unknown packet flag: %s", flag_str); + } + } + + if (argc >= idx+1 && !lua_isnil(l, idx+1)) { + *channel_id = luaL_checkint(l, idx+1); + } + + packet = enet_packet_create(data, size, flags); + if (packet == NULL) { + luaL_error(l, "Failed to create packet"); + } + + return packet; +} + +/** + * Create a new host + * Args: + * address (nil for client) + * [peer_count = 64] + * [channel_count = 1] + * [in_bandwidth = 0] + * [out_bandwidth = 0] + */ +static int host_create(lua_State *l) { + ENetHost *host; + size_t peer_count = 64, channel_count = 1; + enet_uint32 in_bandwidth = 0, out_bandwidth = 0; + + int have_address = 1; + ENetAddress address; + + if (lua_gettop(l) == 0 || lua_isnil(l, 1)) { + have_address = 0; + } else { + parse_address(l, luaL_checkstring(l, 1), &address); + } + + switch (lua_gettop(l)) { + case 5: + if (!lua_isnil(l, 5)) out_bandwidth = luaL_checkint(l, 5); + case 4: + if (!lua_isnil(l, 4)) in_bandwidth = luaL_checkint(l, 4); + case 3: + if (!lua_isnil(l, 3)) channel_count = luaL_checkint(l, 3); + case 2: + if (!lua_isnil(l, 2)) peer_count = luaL_checkint(l, 2); + } + + // printf("host create, peers=%d, channels=%d, in=%d, out=%d\n", + // peer_count, channel_count, in_bandwidth, out_bandwidth); + host = enet_host_create(have_address ? &address : NULL, peer_count, + channel_count, in_bandwidth, out_bandwidth); + + if (host == NULL) { + lua_pushnil (l); + lua_pushstring(l, "enet: failed to create host (already listening?)"); + return 2; + } + + *(ENetHost**)lua_newuserdata(l, sizeof(void*)) = host; + luaL_getmetatable(l, "enet_host"); + lua_setmetatable(l, -2); + + return 1; +} + +static int linked_version(lua_State *l) { + lua_pushfstring(l, "%d.%d.%d", + ENET_VERSION_GET_MAJOR(enet_linked_version()), + ENET_VERSION_GET_MINOR(enet_linked_version()), + ENET_VERSION_GET_PATCH(enet_linked_version())); + return 1; +} + +/** + * Serice a host + * Args: + * timeout + * + * Return + * nil on no event + * an event table on event + */ +static int host_service(lua_State *l) { + ENetHost *host = check_host(l, 1); + ENetEvent event; + int timeout = 0, out; + + if (lua_gettop(l) > 1) + timeout = luaL_checkint(l, 2); + + out = enet_host_service(host, &event, timeout); + if (out == 0) return 0; + if (out < 0) return luaL_error(l, "Error during service"); + + push_event(l, &event); + return 1; +} + +/** + * Dispatch a single event if available + */ +static int host_check_events(lua_State *l) { + ENetHost *host = check_host(l, 1); + ENetEvent event; + int out = enet_host_check_events(host, &event); + if (out == 0) return 0; + if (out < 0) return luaL_error(l, "Error checking event"); + + push_event(l, &event); + return 1; +} + +/** + * Enables an adaptive order-2 PPM range coder for the transmitted data of + * all peers. + */ +static int host_compress_with_range_coder(lua_State *l) { + ENetHost *host = check_host(l, 1); + + int result = enet_host_compress_with_range_coder (host); + if (result == 0) { + lua_pushboolean (l, 1); + } else { + lua_pushboolean (l, 0); + } + + return 1; +} + +/** + * Connect a host to an address + * Args: + * the address + * [channel_count = 1] + * [data = 0] + */ +static int host_connect(lua_State *l) { + ENetHost *host = check_host(l, 1); + ENetAddress address; + ENetPeer *peer; + + enet_uint32 data = 0; + size_t channel_count = 1; + + parse_address(l, luaL_checkstring(l, 2), &address); + + switch (lua_gettop(l)) { + case 4: + if (!lua_isnil(l, 4)) data = luaL_checkint(l, 4); + case 3: + if (!lua_isnil(l, 3)) channel_count = luaL_checkint(l, 3); + } + + // printf("host connect, channels=%d, data=%d\n", channel_count, data); + peer = enet_host_connect(host, &address, channel_count, data); + + if (peer == NULL) { + return luaL_error(l, "Failed to create peer"); + } + + push_peer(l, peer); + + return 1; +} + +static int host_flush(lua_State *l) { + ENetHost *host = check_host(l, 1); + enet_host_flush(host); + return 0; +} + +static int host_broadcast(lua_State *l) { + ENetHost *host = check_host(l, 1); + + enet_uint8 channel_id; + ENetPacket *packet = read_packet(l, 2, &channel_id); + enet_host_broadcast(host, channel_id, packet); + return 0; +} + +// Args: limit:number +static int host_channel_limit(lua_State *l) { + ENetHost *host = check_host(l, 1); + int limit = luaL_checkint(l, 2); + enet_host_channel_limit(host, limit); + return 0; +} + +static int host_bandwidth_limit(lua_State *l) { + ENetHost *host = check_host(l, 1); + enet_uint32 in_bandwidth = luaL_checkint(l, 2); + enet_uint32 out_bandwidth = luaL_checkint(l, 2); + enet_host_bandwidth_limit(host, in_bandwidth, out_bandwidth); + return 0; +} + +static int host_socket_get_address(lua_State *l) { + ENetHost *host = check_host(l, 1); + ENetAddress address; + enet_socket_get_address (host->socket, &address); + + lua_pushfstring(l, "%d.%d.%d.%d:%d", + ((address.host) & 0xFF), + ((address.host >> 8) & 0xFF), + ((address.host >> 16) & 0xFF), + (address.host >> 24& 0xFF), + address.port); + return 1; +} +static int host_total_sent_data(lua_State *l) { + ENetHost *host = check_host(l, 1); + + lua_pushinteger (l, host->totalSentData); + + return 1; +} + +static int host_total_received_data(lua_State *l) { + ENetHost *host = check_host(l, 1); + + lua_pushinteger (l, host->totalReceivedData); + + return 1; +} +static int host_service_time(lua_State *l) { + ENetHost *host = check_host(l, 1); + + lua_pushinteger (l, host->serviceTime); + + return 1; +} + +static int host_peer_count(lua_State *l) { + ENetHost *host = check_host(l, 1); + + lua_pushinteger (l, host->peerCount); + + return 1; +} + +static int host_get_peer(lua_State *l) { + ENetHost *host = check_host(l, 1); + + int peer_index = luaL_checkint(l, 2) - 1; + + if (peer_index < 0 || ((size_t) peer_index) >= host->peerCount) { + luaL_argerror (l, 2, "Invalid peer index"); + } + + ENetPeer *peer = &(host->peers[peer_index]); + + push_peer (l, peer); + return 1; +} + +static int host_gc(lua_State *l) { + ENetHost *host = check_host(l, 1); + enet_host_destroy(host); + return 0; +} + +static int peer_tostring(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + char host_str[128]; + enet_address_get_host_ip(&peer->address, host_str, 128); + + lua_pushstring(l, host_str); + lua_pushstring(l, ":"); + lua_pushinteger(l, peer->address.port); + lua_concat(l, 3); + return 1; +} + +static int peer_ping(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + enet_peer_ping(peer); + return 0; +} + +static int peer_throttle_configure(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + enet_uint32 interval = luaL_checkint(l, 2); + enet_uint32 acceleration = luaL_checkint(l, 3); + enet_uint32 deceleration = luaL_checkint(l, 4); + + enet_peer_throttle_configure(peer, interval, acceleration, deceleration); + return 0; +} + +static int peer_round_trip_time(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + if (lua_gettop(l) > 1) { + enet_uint32 round_trip_time = luaL_checkint(l, 2); + peer->roundTripTime = round_trip_time; + } + + lua_pushinteger (l, peer->roundTripTime); + + return 1; +} + +static int peer_last_round_trip_time(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + if (lua_gettop(l) > 1) { + enet_uint32 round_trip_time = luaL_checkint(l, 2); + peer->lastRoundTripTime = round_trip_time; + } + lua_pushinteger (l, peer->lastRoundTripTime); + + return 1; +} + +static int peer_ping_interval(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + if (lua_gettop(l) > 1) { + enet_uint32 interval = luaL_checkint(l, 2); + enet_peer_ping_interval (peer, interval); + } + + lua_pushinteger (l, peer->pingInterval); + + return 1; +} + +static int peer_timeout(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + enet_uint32 timeout_limit = 0; + enet_uint32 timeout_minimum = 0; + enet_uint32 timeout_maximum = 0; + + switch (lua_gettop(l)) { + case 4: + if (!lua_isnil(l, 4)) timeout_maximum = luaL_checkint(l, 4); + case 3: + if (!lua_isnil(l, 3)) timeout_minimum = luaL_checkint(l, 3); + case 2: + if (!lua_isnil(l, 2)) timeout_limit = luaL_checkint(l, 2); + } + + enet_peer_timeout (peer, timeout_limit, timeout_minimum, timeout_maximum); + + lua_pushinteger (l, peer->timeoutLimit); + lua_pushinteger (l, peer->timeoutMinimum); + lua_pushinteger (l, peer->timeoutMaximum); + + return 3; +} + +static int peer_disconnect(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0; + enet_peer_disconnect(peer, data); + return 0; +} + +static int peer_disconnect_now(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0; + enet_peer_disconnect_now(peer, data); + return 0; +} + +static int peer_disconnect_later(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0; + enet_peer_disconnect_later(peer, data); + return 0; +} + +static int peer_index(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + size_t peer_index = find_peer_index (l, peer->host, peer); + lua_pushinteger (l, peer_index + 1); + + return 1; +} + +static int peer_state(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + switch (peer->state) { + case (ENET_PEER_STATE_DISCONNECTED): + lua_pushstring (l, "disconnected"); + break; + case (ENET_PEER_STATE_CONNECTING): + lua_pushstring (l, "connecting"); + break; + case (ENET_PEER_STATE_ACKNOWLEDGING_CONNECT): + lua_pushstring (l, "acknowledging_connect"); + break; + case (ENET_PEER_STATE_CONNECTION_PENDING): + lua_pushstring (l, "connection_pending"); + break; + case (ENET_PEER_STATE_CONNECTION_SUCCEEDED): + lua_pushstring (l, "connection_succeeded"); + break; + case (ENET_PEER_STATE_CONNECTED): + lua_pushstring (l, "connected"); + break; + case (ENET_PEER_STATE_DISCONNECT_LATER): + lua_pushstring (l, "disconnect_later"); + break; + case (ENET_PEER_STATE_DISCONNECTING): + lua_pushstring (l, "disconnecting"); + break; + case (ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT): + lua_pushstring (l, "acknowledging_disconnect"); + break; + case (ENET_PEER_STATE_ZOMBIE): + lua_pushstring (l, "zombie"); + break; + default: + lua_pushstring (l, "unknown"); + } + + return 1; +} + +static int peer_connect_id(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + lua_pushinteger (l, peer->connectID); + + return 1; +} + + +static int peer_reset(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + enet_peer_reset(peer); + return 0; +} + +static int peer_receive(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + ENetPacket *packet; + enet_uint8 channel_id = 0; + + if (lua_gettop(l) > 1) { + channel_id = luaL_checkint(l, 2); + } + + packet = enet_peer_receive(peer, &channel_id); + if (packet == NULL) return 0; + + lua_pushlstring(l, (const char *)packet->data, packet->dataLength); + lua_pushinteger(l, channel_id); + + enet_packet_destroy(packet); + return 2; +} + + +/** + * Send a lua string to a peer + * Args: + * packet data, string + * channel id + * flags ["reliable", nil] + * + */ +static int peer_send(lua_State *l) { + ENetPeer *peer = check_peer(l, 1); + + enet_uint8 channel_id; + ENetPacket *packet = read_packet(l, 2, &channel_id); + + // printf("sending, channel_id=%d\n", channel_id); + enet_peer_send(peer, channel_id, packet); + return 0; +} + +static const struct luaL_Reg enet_funcs [] = { + {"host_create", host_create}, + {"linked_version", linked_version}, + {NULL, NULL} +}; + +static const struct luaL_Reg enet_host_funcs [] = { + {"service", host_service}, + {"check_events", host_check_events}, + {"compress_with_range_coder", host_compress_with_range_coder}, + {"connect", host_connect}, + {"flush", host_flush}, + {"broadcast", host_broadcast}, + {"channel_limit", host_channel_limit}, + {"bandwidth_limit", host_bandwidth_limit}, + {"socket_get_address", host_socket_get_address}, + + // additional convenience functions (mostly accessors) + {"total_sent_data", host_total_sent_data}, + {"total_received_data", host_total_received_data}, + {"service_time", host_service_time}, + {"peer_count", host_peer_count}, + {"get_peer", host_get_peer}, + {NULL, NULL} +}; + +static const struct luaL_Reg enet_peer_funcs [] = { + {"disconnect", peer_disconnect}, + {"disconnect_now", peer_disconnect_now}, + {"disconnect_later", peer_disconnect_later}, + {"reset", peer_reset}, + {"ping", peer_ping}, + {"receive", peer_receive}, + {"send", peer_send}, + {"throttle_configure", peer_throttle_configure}, + {"ping_interval", peer_ping_interval}, + {"timeout", peer_timeout}, + + // additional convenience functions to member variables + {"index", peer_index}, + {"state", peer_state}, + {"connect_id", peer_connect_id}, + {"round_trip_time", peer_round_trip_time}, + {"last_round_trip_time", peer_last_round_trip_time}, + {NULL, NULL} +}; + +static const struct luaL_Reg enet_event_funcs [] = { + {NULL, NULL} +}; + +int luaopen_enet(lua_State *l) { + enet_initialize(); + atexit(enet_deinitialize); + + // create metatables + luaL_newmetatable(l, "enet_host"); + lua_newtable(l); // index + luaL_register(l, NULL, enet_host_funcs); + lua_setfield(l, -2, "__index"); + lua_pushcfunction(l, host_gc); + lua_setfield(l, -2, "__gc"); + + luaL_newmetatable(l, "enet_peer"); + lua_newtable(l); + luaL_register(l, NULL, enet_peer_funcs); + lua_setfield(l, -2, "__index"); + lua_pushcfunction(l, peer_tostring); + lua_setfield(l, -2, "__tostring"); + + // set up peer table + lua_newtable(l); + + lua_newtable(l); // metatable + lua_pushstring(l, "v"); + lua_setfield(l, -2, "__mode"); + lua_setmetatable(l, -2); + + lua_setfield(l, LUA_REGISTRYINDEX, "enet_peers"); + + luaL_register(l, "enet", enet_funcs); + + // return the enet table created with luaL_register + return 1; +} diff --git a/src/libraries/enet/libenet/ChangeLog b/src/libraries/enet/libenet/ChangeLog new file mode 100644 index 000000000..c8f91a090 --- /dev/null +++ b/src/libraries/enet/libenet/ChangeLog @@ -0,0 +1,159 @@ +ENet 1.3.10 (October 23, 2013); + +* doubled maximum reliable window size +* fixed RCVTIMEO/SNDTIMEO socket options and also added NODELAY + +ENet 1.3.9 (August 19, 2013): + +* added duplicatePeers option to ENetHost which can limit the number of peers from duplicate IPs +* added enet_socket_get_option() and ENET_SOCKOPT_ERROR +* added enet_host_random_seed() platform stub + +ENet 1.3.8 (June 2, 2013): + +* added enet_linked_version() for checking the linked version +* added enet_socket_get_address() for querying the local address of a socket +* silenced some debugging prints unless ENET_DEBUG is defined during compilation +* handle EINTR in enet_socket_wait() so that enet_host_service() doesn't propagate errors from signals +* optimized enet_host_bandwidth_throttle() to be less expensive for large numbers of peers + +ENet 1.3.7 (March 6, 2013): + +* added ENET_PACKET_FLAG_SENT to indicate that a packet is being freed because it has been sent +* added userData field to ENetPacket +* changed how random seed is generated on Windows to avoid import warnings +* fixed case where disconnects could be generated with no preceding connect event + +ENet 1.3.6 (December 11, 2012): + +* added support for intercept callback in ENetHost that can be used to process raw packets before ENet +* added enet_socket_shutdown() for issuing shutdown on a socket +* fixed enet_socket_connect() to not error on non-blocking connects +* fixed bug in MTU negotiation during connections + +ENet 1.3.5 (July 31, 2012): + +* fixed bug in unreliable packet fragment queuing + +ENet 1.3.4 (May 29, 2012): + +* added enet_peer_ping_interval() for configuring per-peer ping intervals +* added enet_peer_timeout() for configuring per-peer timeouts +* added protocol packet size limits + +ENet 1.3.3 (June 28, 2011): + +* fixed bug with simultaneous disconnects not dispatching events + +ENet 1.3.2 (May 31, 2011): + +* added support for unreliable packet fragmenting via the packet flag +ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT +* fixed regression in unreliable packet queuing +* added check against received port to limit some forms of IP-spoofing + +ENet 1.3.1 (February 10, 2011): + +* fixed bug in tracking of reliable data in transit +* reliable data window size now scales with the throttle +* fixed bug in fragment length calculation when checksums are used + +ENet 1.3.0 (June 5, 2010): + +* enet_host_create() now requires the channel limit to be specified as +a parameter +* enet_host_connect() now accepts a data parameter which is supplied +to the receiving receiving host in the event data field for a connect event +* added an adaptive order-2 PPM range coder as a built-in compressor option +which can be set with enet_host_compress_with_range_coder() +* added support for packet compression configurable with a callback +* improved session number handling to not rely on the packet checksum +field, saving 4 bytes per packet unless the checksum option is used +* removed the dependence on the rand callback for session number handling + +Caveats: This version is not protocol compatible with the 1.2 series or +earlier. The enet_host_connect and enet_host_create API functions require +supplying additional parameters. + +ENet 1.2.5 (June 28, 2011): + +* fixed bug with simultaneous disconnects not dispatching events + +ENet 1.2.4 (May 31, 2011): + +* fixed regression in unreliable packet queuing +* added check against received port to limit some forms of IP-spoofing + +ENet 1.2.3 (February 10, 2011): + +* fixed bug in tracking reliable data in transit + +ENet 1.2.2 (June 5, 2010): + +* checksum functionality is now enabled by setting a checksum callback +inside ENetHost instead of being a configure script option +* added totalSentData, totalSentPackets, totalReceivedData, and +totalReceivedPackets counters inside ENetHost for getting usage +statistics +* added enet_host_channel_limit() for limiting the maximum number of +channels allowed by connected peers +* now uses dispatch queues for event dispatch rather than potentially +unscalable array walking +* added no_memory callback that is called when a malloc attempt fails, +such that if no_memory returns rather than aborts (the default behavior), +then the error is propagated to the return value of the API calls +* now uses packed attribute for protocol structures on platforms with +strange alignment rules +* improved autoconf build system contributed by Nathan Brink allowing +for easier building as a shared library + +Caveats: If you were using the compile-time option that enabled checksums, +make sure to set the checksum callback inside ENetHost to enet_crc32 to +regain the old behavior. The ENetCallbacks structure has added new fields, +so make sure to clear the structure to zero before use if +using enet_initialize_with_callbacks(). + +ENet 1.2.1 (November 12, 2009): + +* fixed bug that could cause disconnect events to be dropped +* added thin wrapper around select() for portable usage +* added ENET_SOCKOPT_REUSEADDR socket option +* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create() +* added contributed Code::Blocks build file + +ENet 1.2 (February 12, 2008): + +* fixed bug in VERIFY_CONNECT acknowledgement that could cause connect +attempts to occasionally timeout +* fixed acknowledgements to check both the outgoing and sent queues +when removing acknowledged packets +* fixed accidental bit rot in the MSVC project file +* revised sequence number overflow handling to address some possible +disconnect bugs +* added enet_host_check_events() for getting only local queued events +* factored out socket option setting into enet_socket_set_option() so +that socket options are now set separately from enet_socket_create() + +Caveats: While this release is superficially protocol compatible with 1.1, +differences in the sequence number overflow handling can potentially cause +random disconnects. + +ENet 1.1 (June 6, 2007): + +* optional CRC32 just in case someone needs a stronger checksum than UDP +provides (--enable-crc32 configure option) +* the size of packet headers are half the size they used to be (so less +overhead when sending small packets) +* enet_peer_disconnect_later() that waits till all queued outgoing +packets get sent before issuing an actual disconnect +* freeCallback field in individual packets for notification of when a +packet is about to be freed +* ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a +packet (can be used in concert with freeCallback to support some custom +allocation schemes that the normal memory allocation callbacks would +normally not allow) +* enet_address_get_host_ip() for printing address numbers +* promoted the enet_socket_*() functions to be part of the API now +* a few stability/crash fixes + + diff --git a/src/libraries/enet/libenet/LICENSE b/src/libraries/enet/libenet/LICENSE new file mode 100644 index 000000000..87961d3b6 --- /dev/null +++ b/src/libraries/enet/libenet/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2002-2013 Lee Salzman + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libraries/enet/libenet/README b/src/libraries/enet/libenet/README new file mode 100644 index 000000000..54b2d2130 --- /dev/null +++ b/src/libraries/enet/libenet/README @@ -0,0 +1,15 @@ +Please visit the ENet homepage at http://enet.bespin.org for installation +and usage instructions. + +If you obtained this package from github, the quick description on how to build +is: + +# Generate the build system. + +autoreconf -vfi + +# Compile and install the library. + +./configure && make && make install + + diff --git a/src/libraries/enet/libenet/callbacks.c b/src/libraries/enet/libenet/callbacks.c new file mode 100644 index 000000000..b3990af1f --- /dev/null +++ b/src/libraries/enet/libenet/callbacks.c @@ -0,0 +1,53 @@ +/** + @file callbacks.c + @brief ENet callback functions +*/ +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +static ENetCallbacks callbacks = { malloc, free, abort }; + +int +enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits) +{ + if (version < ENET_VERSION_CREATE (1, 3, 0)) + return -1; + + if (inits -> malloc != NULL || inits -> free != NULL) + { + if (inits -> malloc == NULL || inits -> free == NULL) + return -1; + + callbacks.malloc = inits -> malloc; + callbacks.free = inits -> free; + } + + if (inits -> no_memory != NULL) + callbacks.no_memory = inits -> no_memory; + + return enet_initialize (); +} + +ENetVersion +enet_linked_version (void) +{ + return ENET_VERSION; +} + +void * +enet_malloc (size_t size) +{ + void * memory = callbacks.malloc (size); + + if (memory == NULL) + callbacks.no_memory (); + + return memory; +} + +void +enet_free (void * memory) +{ + callbacks.free (memory); +} + diff --git a/src/libraries/enet/libenet/compress.c b/src/libraries/enet/libenet/compress.c new file mode 100644 index 000000000..784489a78 --- /dev/null +++ b/src/libraries/enet/libenet/compress.c @@ -0,0 +1,654 @@ +/** + @file compress.c + @brief An adaptive order-2 PPM range coder +*/ +#define ENET_BUILDING_LIB 1 +#include +#include "enet/enet.h" + +typedef struct _ENetSymbol +{ + /* binary indexed tree of symbols */ + enet_uint8 value; + enet_uint8 count; + enet_uint16 under; + enet_uint16 left, right; + + /* context defined by this symbol */ + enet_uint16 symbols; + enet_uint16 escapes; + enet_uint16 total; + enet_uint16 parent; +} ENetSymbol; + +/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */ +enum +{ + ENET_RANGE_CODER_TOP = 1<<24, + ENET_RANGE_CODER_BOTTOM = 1<<16, + + ENET_CONTEXT_SYMBOL_DELTA = 3, + ENET_CONTEXT_SYMBOL_MINIMUM = 1, + ENET_CONTEXT_ESCAPE_MINIMUM = 1, + + ENET_SUBCONTEXT_ORDER = 2, + ENET_SUBCONTEXT_SYMBOL_DELTA = 2, + ENET_SUBCONTEXT_ESCAPE_DELTA = 5 +}; + +/* context exclusion roughly halves compression speed, so disable for now */ +#undef ENET_CONTEXT_EXCLUSION + +typedef struct _ENetRangeCoder +{ + /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */ + ENetSymbol symbols[4096]; +} ENetRangeCoder; + +void * +enet_range_coder_create (void) +{ + ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder)); + if (rangeCoder == NULL) + return NULL; + + return rangeCoder; +} + +void +enet_range_coder_destroy (void * context) +{ + ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; + if (rangeCoder == NULL) + return; + + enet_free (rangeCoder); +} + +#define ENET_SYMBOL_CREATE(symbol, value_, count_) \ +{ \ + symbol = & rangeCoder -> symbols [nextSymbol ++]; \ + symbol -> value = value_; \ + symbol -> count = count_; \ + symbol -> under = count_; \ + symbol -> left = 0; \ + symbol -> right = 0; \ + symbol -> symbols = 0; \ + symbol -> escapes = 0; \ + symbol -> total = 0; \ + symbol -> parent = 0; \ +} + +#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \ +{ \ + ENET_SYMBOL_CREATE (context, 0, 0); \ + (context) -> escapes = escapes_; \ + (context) -> total = escapes_ + 256*minimum; \ + (context) -> symbols = 0; \ +} + +static enet_uint16 +enet_symbol_rescale (ENetSymbol * symbol) +{ + enet_uint16 total = 0; + for (;;) + { + symbol -> count -= symbol->count >> 1; + symbol -> under = symbol -> count; + if (symbol -> left) + symbol -> under += enet_symbol_rescale (symbol + symbol -> left); + total += symbol -> under; + if (! symbol -> right) break; + symbol += symbol -> right; + } + return total; +} + +#define ENET_CONTEXT_RESCALE(context, minimum) \ +{ \ + (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \ + (context) -> escapes -= (context) -> escapes >> 1; \ + (context) -> total += (context) -> escapes + 256*minimum; \ +} + +#define ENET_RANGE_CODER_OUTPUT(value) \ +{ \ + if (outData >= outEnd) \ + return 0; \ + * outData ++ = value; \ +} + +#define ENET_RANGE_CODER_ENCODE(under, count, total) \ +{ \ + encodeRange /= (total); \ + encodeLow += (under) * encodeRange; \ + encodeRange *= (count); \ + for (;;) \ + { \ + if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \ + { \ + if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ + encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ + } \ + ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \ + encodeRange <<= 8; \ + encodeLow <<= 8; \ + } \ +} + +#define ENET_RANGE_CODER_FLUSH \ +{ \ + while (encodeLow) \ + { \ + ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \ + encodeLow <<= 8; \ + } \ +} + +#define ENET_RANGE_CODER_FREE_SYMBOLS \ +{ \ + if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \ + { \ + nextSymbol = 0; \ + ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \ + predicted = 0; \ + order = 0; \ + } \ +} + +#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \ +{ \ + under_ = value*minimum; \ + count_ = minimum; \ + if (! (context) -> symbols) \ + { \ + ENET_SYMBOL_CREATE (symbol_, value_, update); \ + (context) -> symbols = symbol_ - (context); \ + } \ + else \ + { \ + ENetSymbol * node = (context) + (context) -> symbols; \ + for (;;) \ + { \ + if (value_ < node -> value) \ + { \ + node -> under += update; \ + if (node -> left) { node += node -> left; continue; } \ + ENET_SYMBOL_CREATE (symbol_, value_, update); \ + node -> left = symbol_ - node; \ + } \ + else \ + if (value_ > node -> value) \ + { \ + under_ += node -> under; \ + if (node -> right) { node += node -> right; continue; } \ + ENET_SYMBOL_CREATE (symbol_, value_, update); \ + node -> right = symbol_ - node; \ + } \ + else \ + { \ + count_ += node -> count; \ + under_ += node -> under - node -> count; \ + node -> under += update; \ + node -> count += update; \ + symbol_ = node; \ + } \ + break; \ + } \ + } \ +} + +#ifdef ENET_CONTEXT_EXCLUSION +static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +#define ENET_CONTEXT_WALK(context, body) \ +{ \ + const ENetSymbol * node = (context) + (context) -> symbols; \ + const ENetSymbol * stack [256]; \ + size_t stackSize = 0; \ + while (node -> left) \ + { \ + stack [stackSize ++] = node; \ + node += node -> left; \ + } \ + for (;;) \ + { \ + body; \ + if (node -> right) \ + { \ + node += node -> right; \ + while (node -> left) \ + { \ + stack [stackSize ++] = node; \ + node += node -> left; \ + } \ + } \ + else \ + if (stackSize <= 0) \ + break; \ + else \ + node = stack [-- stackSize]; \ + } \ +} + +#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \ +ENET_CONTEXT_WALK(context, { \ + if (node -> value != value_) \ + { \ + enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \ + if (node -> value < value_) \ + under -= parentCount; \ + total -= parentCount; \ + } \ +}) +#endif + +size_t +enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit) +{ + ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; + enet_uint8 * outStart = outData, * outEnd = & outData [outLimit]; + const enet_uint8 * inData, * inEnd; + enet_uint32 encodeLow = 0, encodeRange = ~0; + ENetSymbol * root; + enet_uint16 predicted = 0; + size_t order = 0, nextSymbol = 0; + + if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0) + return 0; + + inData = (const enet_uint8 *) inBuffers -> data; + inEnd = & inData [inBuffers -> dataLength]; + inBuffers ++; + inBufferCount --; + + ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); + + for (;;) + { + ENetSymbol * subcontext, * symbol; +#ifdef ENET_CONTEXT_EXCLUSION + const ENetSymbol * childContext = & emptyContext; +#endif + enet_uint8 value; + enet_uint16 count, under, * parent = & predicted, total; + if (inData >= inEnd) + { + if (inBufferCount <= 0) + break; + inData = (const enet_uint8 *) inBuffers -> data; + inEnd = & inData [inBuffers -> dataLength]; + inBuffers ++; + inBufferCount --; + } + value = * inData ++; + + for (subcontext = & rangeCoder -> symbols [predicted]; + subcontext != root; +#ifdef ENET_CONTEXT_EXCLUSION + childContext = subcontext, +#endif + subcontext = & rangeCoder -> symbols [subcontext -> parent]) + { + ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); + * parent = symbol - rangeCoder -> symbols; + parent = & symbol -> parent; + total = subcontext -> total; +#ifdef ENET_CONTEXT_EXCLUSION + if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) + ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0); +#endif + if (count > 0) + { + ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total); + } + else + { + if (subcontext -> escapes > 0 && subcontext -> escapes < total) + ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); + subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; + subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; + } + subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE (subcontext, 0); + if (count > 0) goto nextInput; + } + + ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM); + * parent = symbol - rangeCoder -> symbols; + parent = & symbol -> parent; + total = root -> total; +#ifdef ENET_CONTEXT_EXCLUSION + if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) + ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); +#endif + ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total); + root -> total += ENET_CONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); + + nextInput: + if (order >= ENET_SUBCONTEXT_ORDER) + predicted = rangeCoder -> symbols [predicted].parent; + else + order ++; + ENET_RANGE_CODER_FREE_SYMBOLS; + } + + ENET_RANGE_CODER_FLUSH; + + return (size_t) (outData - outStart); +} + +#define ENET_RANGE_CODER_SEED \ +{ \ + if (inData < inEnd) decodeCode |= * inData ++ << 24; \ + if (inData < inEnd) decodeCode |= * inData ++ << 16; \ + if (inData < inEnd) decodeCode |= * inData ++ << 8; \ + if (inData < inEnd) decodeCode |= * inData ++; \ +} + +#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total))) + +#define ENET_RANGE_CODER_DECODE(under, count, total) \ +{ \ + decodeLow += (under) * decodeRange; \ + decodeRange *= (count); \ + for (;;) \ + { \ + if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \ + { \ + if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ + decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ + } \ + decodeCode <<= 8; \ + if (inData < inEnd) \ + decodeCode |= * inData ++; \ + decodeRange <<= 8; \ + decodeLow <<= 8; \ + } \ +} + +#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \ +{ \ + under_ = 0; \ + count_ = minimum; \ + if (! (context) -> symbols) \ + { \ + createRoot; \ + } \ + else \ + { \ + ENetSymbol * node = (context) + (context) -> symbols; \ + for (;;) \ + { \ + enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \ + visitNode; \ + if (code >= after) \ + { \ + under_ += node -> under; \ + if (node -> right) { node += node -> right; continue; } \ + createRight; \ + } \ + else \ + if (code < after - before) \ + { \ + node -> under += update; \ + if (node -> left) { node += node -> left; continue; } \ + createLeft; \ + } \ + else \ + { \ + value_ = node -> value; \ + count_ += node -> count; \ + under_ = after - before; \ + node -> under += update; \ + node -> count += update; \ + symbol_ = node; \ + } \ + break; \ + } \ + } \ +} + +#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \ +ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0) + +#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \ +ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \ + { \ + value_ = code / minimum; \ + under_ = code - code%minimum; \ + ENET_SYMBOL_CREATE (symbol_, value_, update); \ + (context) -> symbols = symbol_ - (context); \ + }, \ + exclude (node -> value, after, before), \ + { \ + value_ = node->value + 1 + (code - after)/minimum; \ + under_ = code - (code - after)%minimum; \ + ENET_SYMBOL_CREATE (symbol_, value_, update); \ + node -> right = symbol_ - node; \ + }, \ + { \ + value_ = node->value - 1 - (after - before - code - 1)/minimum; \ + under_ = code - (after - before - code - 1)%minimum; \ + ENET_SYMBOL_CREATE (symbol_, value_, update); \ + node -> left = symbol_ - node; \ + }) \ + +#ifdef ENET_CONTEXT_EXCLUSION +typedef struct _ENetExclude +{ + enet_uint8 value; + enet_uint16 under; +} ENetExclude; + +#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \ +{ \ + enet_uint16 under = 0; \ + nextExclude = excludes; \ + ENET_CONTEXT_WALK (context, { \ + under += rangeCoder -> symbols [node -> parent].count + minimum; \ + nextExclude -> value = node -> value; \ + nextExclude -> under = under; \ + nextExclude ++; \ + }); \ + total -= under; \ +} + +#define ENET_CONTEXT_EXCLUDED(value_, after, before) \ +{ \ + size_t low = 0, high = nextExclude - excludes; \ + for(;;) \ + { \ + size_t mid = (low + high) >> 1; \ + const ENetExclude * exclude = & excludes [mid]; \ + if (value_ < exclude -> value) \ + { \ + if (low + 1 < high) \ + { \ + high = mid; \ + continue; \ + } \ + if (exclude > excludes) \ + after -= exclude [-1].under; \ + } \ + else \ + { \ + if (value_ > exclude -> value) \ + { \ + if (low + 1 < high) \ + { \ + low = mid; \ + continue; \ + } \ + } \ + else \ + before = 0; \ + after -= exclude -> under; \ + } \ + break; \ + } \ +} +#endif + +#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before) + +size_t +enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit) +{ + ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; + enet_uint8 * outStart = outData, * outEnd = & outData [outLimit]; + const enet_uint8 * inEnd = & inData [inLimit]; + enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0; + ENetSymbol * root; + enet_uint16 predicted = 0; + size_t order = 0, nextSymbol = 0; +#ifdef ENET_CONTEXT_EXCLUSION + ENetExclude excludes [256]; + ENetExclude * nextExclude = excludes; +#endif + + if (rangeCoder == NULL || inLimit <= 0) + return 0; + + ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); + + ENET_RANGE_CODER_SEED; + + for (;;) + { + ENetSymbol * subcontext, * symbol, * patch; +#ifdef ENET_CONTEXT_EXCLUSION + const ENetSymbol * childContext = & emptyContext; +#endif + enet_uint8 value = 0; + enet_uint16 code, under, count, bottom, * parent = & predicted, total; + + for (subcontext = & rangeCoder -> symbols [predicted]; + subcontext != root; +#ifdef ENET_CONTEXT_EXCLUSION + childContext = subcontext, +#endif + subcontext = & rangeCoder -> symbols [subcontext -> parent]) + { + if (subcontext -> escapes <= 0) + continue; + total = subcontext -> total; +#ifdef ENET_CONTEXT_EXCLUSION + if (childContext -> total > 0) + ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); +#endif + if (subcontext -> escapes >= total) + continue; + code = ENET_RANGE_CODER_READ (total); + if (code < subcontext -> escapes) + { + ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); + continue; + } + code -= subcontext -> escapes; +#ifdef ENET_CONTEXT_EXCLUSION + if (childContext -> total > 0) + { + ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); + } + else +#endif + { + ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); + } + bottom = symbol - rangeCoder -> symbols; + ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total); + subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE (subcontext, 0); + goto patchContexts; + } + + total = root -> total; +#ifdef ENET_CONTEXT_EXCLUSION + if (childContext -> total > 0) + ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM); +#endif + code = ENET_RANGE_CODER_READ (total); + if (code < root -> escapes) + { + ENET_RANGE_CODER_DECODE (0, root -> escapes, total); + break; + } + code -= root -> escapes; +#ifdef ENET_CONTEXT_EXCLUSION + if (childContext -> total > 0) + { + ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); + } + else +#endif + { + ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); + } + bottom = symbol - rangeCoder -> symbols; + ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total); + root -> total += ENET_CONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); + + patchContexts: + for (patch = & rangeCoder -> symbols [predicted]; + patch != subcontext; + patch = & rangeCoder -> symbols [patch -> parent]) + { + ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); + * parent = symbol - rangeCoder -> symbols; + parent = & symbol -> parent; + if (count <= 0) + { + patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; + patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; + } + patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE (patch, 0); + } + * parent = bottom; + + ENET_RANGE_CODER_OUTPUT (value); + + if (order >= ENET_SUBCONTEXT_ORDER) + predicted = rangeCoder -> symbols [predicted].parent; + else + order ++; + ENET_RANGE_CODER_FREE_SYMBOLS; + } + + return (size_t) (outData - outStart); +} + +/** @defgroup host ENet host functions + @{ +*/ + +/** Sets the packet compressor the host should use to the default range coder. + @param host host to enable the range coder for + @returns 0 on success, < 0 on failure +*/ +int +enet_host_compress_with_range_coder (ENetHost * host) +{ + ENetCompressor compressor; + memset (& compressor, 0, sizeof (compressor)); + compressor.context = enet_range_coder_create(); + if (compressor.context == NULL) + return -1; + compressor.compress = enet_range_coder_compress; + compressor.decompress = enet_range_coder_decompress; + compressor.destroy = enet_range_coder_destroy; + enet_host_compress (host, & compressor); + return 0; +} + +/** @} */ + + diff --git a/src/libraries/enet/libenet/host.c b/src/libraries/enet/libenet/host.c new file mode 100644 index 000000000..fc57f7410 --- /dev/null +++ b/src/libraries/enet/libenet/host.c @@ -0,0 +1,490 @@ +/** + @file host.c + @brief ENet host management functions +*/ +#define ENET_BUILDING_LIB 1 +#include +#include "enet/enet.h" + +/** @defgroup host ENet host functions + @{ +*/ + +/** Creates a host for communicating to peers. + + @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. + @param peerCount the maximum number of peers that should be allocated for the host. + @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT + @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. + @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. + + @returns the host on success and NULL on failure + + @remarks ENet will strategically drop packets on specific sides of a connection between hosts + to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine + the window size of a connection which limits the amount of reliable packets that may be in transit + at any given time. +*/ +ENetHost * +enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +{ + ENetHost * host; + ENetPeer * currentPeer; + + if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID) + return NULL; + + host = (ENetHost *) enet_malloc (sizeof (ENetHost)); + if (host == NULL) + return NULL; + memset (host, 0, sizeof (ENetHost)); + + host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer)); + if (host -> peers == NULL) + { + enet_free (host); + + return NULL; + } + memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); + + host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM); + if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0)) + { + if (host -> socket != ENET_SOCKET_NULL) + enet_socket_destroy (host -> socket); + + enet_free (host -> peers); + enet_free (host); + + return NULL; + } + + enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1); + enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1); + enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); + enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); + + if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0) + host -> address = * address; + + if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else + if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + + host -> randomSeed = (enet_uint32) (size_t) host; + host -> randomSeed += enet_host_random_seed (); + host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16); + host -> channelLimit = channelLimit; + host -> incomingBandwidth = incomingBandwidth; + host -> outgoingBandwidth = outgoingBandwidth; + host -> bandwidthThrottleEpoch = 0; + host -> recalculateBandwidthLimits = 0; + host -> mtu = ENET_HOST_DEFAULT_MTU; + host -> peerCount = peerCount; + host -> commandCount = 0; + host -> bufferCount = 0; + host -> checksum = NULL; + host -> receivedAddress.host = ENET_HOST_ANY; + host -> receivedAddress.port = 0; + host -> receivedData = NULL; + host -> receivedDataLength = 0; + + host -> totalSentData = 0; + host -> totalSentPackets = 0; + host -> totalReceivedData = 0; + host -> totalReceivedPackets = 0; + + host -> connectedPeers = 0; + host -> bandwidthLimitedPeers = 0; + host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID; + + host -> compressor.context = NULL; + host -> compressor.compress = NULL; + host -> compressor.decompress = NULL; + host -> compressor.destroy = NULL; + + host -> intercept = NULL; + + enet_list_clear (& host -> dispatchQueue); + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + currentPeer -> host = host; + currentPeer -> incomingPeerID = currentPeer - host -> peers; + currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF; + currentPeer -> data = NULL; + + enet_list_clear (& currentPeer -> acknowledgements); + enet_list_clear (& currentPeer -> sentReliableCommands); + enet_list_clear (& currentPeer -> sentUnreliableCommands); + enet_list_clear (& currentPeer -> outgoingReliableCommands); + enet_list_clear (& currentPeer -> outgoingUnreliableCommands); + enet_list_clear (& currentPeer -> dispatchedCommands); + + enet_peer_reset (currentPeer); + } + + return host; +} + +/** Destroys the host and all resources associated with it. + @param host pointer to the host to destroy +*/ +void +enet_host_destroy (ENetHost * host) +{ + ENetPeer * currentPeer; + + if (host == NULL) + return; + + enet_socket_destroy (host -> socket); + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + enet_peer_reset (currentPeer); + } + + if (host -> compressor.context != NULL && host -> compressor.destroy) + (* host -> compressor.destroy) (host -> compressor.context); + + enet_free (host -> peers); + enet_free (host); +} + +/** Initiates a connection to a foreign host. + @param host host seeking the connection + @param address destination for the connection + @param channelCount number of channels to allocate + @param data user data supplied to the receiving host + @returns a peer representing the foreign host on success, NULL on failure + @remarks The peer returned will have not completed the connection until enet_host_service() + notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. +*/ +ENetPeer * +enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data) +{ + ENetPeer * currentPeer; + ENetChannel * channel; + ENetProtocol command; + + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + else + if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) + break; + } + + if (currentPeer >= & host -> peers [host -> peerCount]) + return NULL; + + currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); + if (currentPeer -> channels == NULL) + return NULL; + currentPeer -> channelCount = channelCount; + currentPeer -> state = ENET_PEER_STATE_CONNECTING; + currentPeer -> address = * address; + currentPeer -> connectID = ++ host -> randomSeed; + + if (host -> outgoingBandwidth == 0) + currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + currentPeer -> windowSize = (host -> outgoingBandwidth / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + for (channel = currentPeer -> channels; + channel < & currentPeer -> channels [channelCount]; + ++ channel) + { + channel -> outgoingReliableSequenceNumber = 0; + channel -> outgoingUnreliableSequenceNumber = 0; + channel -> incomingReliableSequenceNumber = 0; + channel -> incomingUnreliableSequenceNumber = 0; + + enet_list_clear (& channel -> incomingReliableCommands); + enet_list_clear (& channel -> incomingUnreliableCommands); + + channel -> usedReliableWindows = 0; + memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); + } + + command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); + command.connect.incomingSessionID = currentPeer -> incomingSessionID; + command.connect.outgoingSessionID = currentPeer -> outgoingSessionID; + command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu); + command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize); + command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount); + command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); + command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); + command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); + command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); + command.connect.connectID = currentPeer -> connectID; + command.connect.data = ENET_HOST_TO_NET_32 (data); + + enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); + + return currentPeer; +} + +/** Queues a packet to be sent to all peers associated with the host. + @param host host on which to broadcast the packet + @param channelID channel on which to broadcast + @param packet packet to broadcast +*/ +void +enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet) +{ + ENetPeer * currentPeer; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state != ENET_PEER_STATE_CONNECTED) + continue; + + enet_peer_send (currentPeer, channelID, packet); + } + + if (packet -> referenceCount == 0) + enet_packet_destroy (packet); +} + +/** Sets the packet compressor the host should use to compress and decompress packets. + @param host host to enable or disable compression for + @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled +*/ +void +enet_host_compress (ENetHost * host, const ENetCompressor * compressor) +{ + if (host -> compressor.context != NULL && host -> compressor.destroy) + (* host -> compressor.destroy) (host -> compressor.context); + + if (compressor) + host -> compressor = * compressor; + else + host -> compressor.context = NULL; +} + +/** Limits the maximum allowed channels of future incoming connections. + @param host host to limit + @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT +*/ +void +enet_host_channel_limit (ENetHost * host, size_t channelLimit) +{ + if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else + if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + + host -> channelLimit = channelLimit; +} + + +/** Adjusts the bandwidth limits of a host. + @param host host to adjust + @param incomingBandwidth new incoming bandwidth + @param outgoingBandwidth new outgoing bandwidth + @remarks the incoming and outgoing bandwidth parameters are identical in function to those + specified in enet_host_create(). +*/ +void +enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +{ + host -> incomingBandwidth = incomingBandwidth; + host -> outgoingBandwidth = outgoingBandwidth; + host -> recalculateBandwidthLimits = 1; +} + +void +enet_host_bandwidth_throttle (ENetHost * host) +{ + enet_uint32 timeCurrent = enet_time_get (), + elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch, + peersRemaining = (enet_uint32) host -> connectedPeers, + dataTotal = ~0, + bandwidth = ~0, + throttle = 0, + bandwidthLimit = 0; + int needsAdjustment = host -> bandwidthLimitedPeers > 0 ? 1 : 0; + ENetPeer * peer; + ENetProtocol command; + + if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) + return; + + host -> bandwidthThrottleEpoch = timeCurrent; + + if (peersRemaining == 0) + return; + + if (host -> outgoingBandwidth != 0) + { + dataTotal = 0; + bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + continue; + + dataTotal += peer -> outgoingDataTotal; + } + } + + while (peersRemaining > 0 && needsAdjustment != 0) + { + needsAdjustment = 0; + + if (dataTotal <= bandwidth) + throttle = ENET_PEER_PACKET_THROTTLE_SCALE; + else + throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + enet_uint32 peerBandwidth; + + if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || + peer -> incomingBandwidth == 0 || + peer -> outgoingBandwidthThrottleEpoch == timeCurrent) + continue; + + peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000; + if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) + continue; + + peer -> packetThrottleLimit = (peerBandwidth * + ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal; + + if (peer -> packetThrottleLimit == 0) + peer -> packetThrottleLimit = 1; + + if (peer -> packetThrottle > peer -> packetThrottleLimit) + peer -> packetThrottle = peer -> packetThrottleLimit; + + peer -> outgoingBandwidthThrottleEpoch = timeCurrent; + + peer -> incomingDataTotal = 0; + peer -> outgoingDataTotal = 0; + + needsAdjustment = 1; + -- peersRemaining; + bandwidth -= peerBandwidth; + dataTotal -= peerBandwidth; + } + } + + if (peersRemaining > 0) + { + if (dataTotal <= bandwidth) + throttle = ENET_PEER_PACKET_THROTTLE_SCALE; + else + throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || + peer -> outgoingBandwidthThrottleEpoch == timeCurrent) + continue; + + peer -> packetThrottleLimit = throttle; + + if (peer -> packetThrottle > peer -> packetThrottleLimit) + peer -> packetThrottle = peer -> packetThrottleLimit; + + peer -> incomingDataTotal = 0; + peer -> outgoingDataTotal = 0; + } + } + + if (host -> recalculateBandwidthLimits) + { + host -> recalculateBandwidthLimits = 0; + + peersRemaining = (enet_uint32) host -> connectedPeers; + bandwidth = host -> incomingBandwidth; + needsAdjustment = 1; + + if (bandwidth == 0) + bandwidthLimit = 0; + else + while (peersRemaining > 0 && needsAdjustment != 0) + { + needsAdjustment = 0; + bandwidthLimit = bandwidth / peersRemaining; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || + peer -> incomingBandwidthThrottleEpoch == timeCurrent) + continue; + + if (peer -> outgoingBandwidth > 0 && + peer -> outgoingBandwidth >= bandwidthLimit) + continue; + + peer -> incomingBandwidthThrottleEpoch = timeCurrent; + + needsAdjustment = 1; + -- peersRemaining; + bandwidth -= peer -> outgoingBandwidth; + } + } + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + continue; + + command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + + if (peer -> incomingBandwidthThrottleEpoch == timeCurrent) + command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth); + else + command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + } + } +} + +/** @} */ diff --git a/src/libraries/enet/libenet/include/enet/callbacks.h b/src/libraries/enet/libenet/include/enet/callbacks.h new file mode 100644 index 000000000..340a4a989 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/callbacks.h @@ -0,0 +1,27 @@ +/** + @file callbacks.h + @brief ENet callbacks +*/ +#ifndef __ENET_CALLBACKS_H__ +#define __ENET_CALLBACKS_H__ + +#include + +typedef struct _ENetCallbacks +{ + void * (ENET_CALLBACK * malloc) (size_t size); + void (ENET_CALLBACK * free) (void * memory); + void (ENET_CALLBACK * no_memory) (void); +} ENetCallbacks; + +/** @defgroup callbacks ENet internal callbacks + @{ + @ingroup private +*/ +extern void * enet_malloc (size_t); +extern void enet_free (void *); + +/** @} */ + +#endif /* __ENET_CALLBACKS_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/enet.h b/src/libraries/enet/libenet/include/enet/enet.h new file mode 100644 index 000000000..4dda5517d --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/enet.h @@ -0,0 +1,587 @@ +/** + @file enet.h + @brief ENet public header file +*/ +#ifndef __ENET_ENET_H__ +#define __ENET_ENET_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#ifdef _WIN32 +#include "enet/win32.h" +#else +#include "enet/unix.h" +#endif + +#include "enet/types.h" +#include "enet/protocol.h" +#include "enet/list.h" +#include "enet/callbacks.h" + +#define ENET_VERSION_MAJOR 1 +#define ENET_VERSION_MINOR 3 +#define ENET_VERSION_PATCH 10 +#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) +#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF) +#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF) +#define ENET_VERSION_GET_PATCH(version) ((version)&0xFF) +#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH) + +typedef enet_uint32 ENetVersion; + +struct _ENetHost; +struct _ENetEvent; +struct _ENetPacket; + +typedef enum _ENetSocketType +{ + ENET_SOCKET_TYPE_STREAM = 1, + ENET_SOCKET_TYPE_DATAGRAM = 2 +} ENetSocketType; + +typedef enum _ENetSocketWait +{ + ENET_SOCKET_WAIT_NONE = 0, + ENET_SOCKET_WAIT_SEND = (1 << 0), + ENET_SOCKET_WAIT_RECEIVE = (1 << 1), + ENET_SOCKET_WAIT_INTERRUPT = (1 << 2) +} ENetSocketWait; + +typedef enum _ENetSocketOption +{ + ENET_SOCKOPT_NONBLOCK = 1, + ENET_SOCKOPT_BROADCAST = 2, + ENET_SOCKOPT_RCVBUF = 3, + ENET_SOCKOPT_SNDBUF = 4, + ENET_SOCKOPT_REUSEADDR = 5, + ENET_SOCKOPT_RCVTIMEO = 6, + ENET_SOCKOPT_SNDTIMEO = 7, + ENET_SOCKOPT_ERROR = 8, + ENET_SOCKOPT_NODELAY = 9 +} ENetSocketOption; + +typedef enum _ENetSocketShutdown +{ + ENET_SOCKET_SHUTDOWN_READ = 0, + ENET_SOCKET_SHUTDOWN_WRITE = 1, + ENET_SOCKET_SHUTDOWN_READ_WRITE = 2 +} ENetSocketShutdown; + +#define ENET_HOST_ANY 0 +#define ENET_HOST_BROADCAST 0xFFFFFFFFU +#define ENET_PORT_ANY 0 + +/** + * Portable internet address structure. + * + * The host must be specified in network byte-order, and the port must be in host + * byte-order. The constant ENET_HOST_ANY may be used to specify the default + * server host. The constant ENET_HOST_BROADCAST may be used to specify the + * broadcast address (255.255.255.255). This makes sense for enet_host_connect, + * but not for enet_host_create. Once a server responds to a broadcast, the + * address is updated from ENET_HOST_BROADCAST to the server's actual IP address. + */ +typedef struct _ENetAddress +{ + enet_uint32 host; + enet_uint16 port; +} ENetAddress; + +/** + * Packet flag bit constants. + * + * The host must be specified in network byte-order, and the port must be in + * host byte-order. The constant ENET_HOST_ANY may be used to specify the + * default server host. + + @sa ENetPacket +*/ +typedef enum _ENetPacketFlag +{ + /** packet must be received by the target peer and resend attempts should be + * made until the packet is delivered */ + ENET_PACKET_FLAG_RELIABLE = (1 << 0), + /** packet will not be sequenced with other packets + * not supported for reliable packets + */ + ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1), + /** packet will not allocate data, and user must supply it instead */ + ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2), + /** packet will be fragmented using unreliable (instead of reliable) sends + * if it exceeds the MTU */ + ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3), + + /** whether the packet has been sent from all queues it has been entered into */ + ENET_PACKET_FLAG_SENT = (1<<8) +} ENetPacketFlag; + +typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *); + +/** + * ENet packet structure. + * + * An ENet data packet that may be sent to or received from a peer. The shown + * fields should only be read and never modified. The data field contains the + * allocated data for the packet. The dataLength fields specifies the length + * of the allocated data. The flags field is either 0 (specifying no flags), + * or a bitwise-or of any combination of the following flags: + * + * ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer + * and resend attempts should be made until the packet is delivered + * + * ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets + * (not supported for reliable packets) + * + * ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead + + @sa ENetPacketFlag + */ +typedef struct _ENetPacket +{ + size_t referenceCount; /**< internal use only */ + enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */ + enet_uint8 * data; /**< allocated data for packet */ + size_t dataLength; /**< length of data */ + ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */ + void * userData; /**< application private data, may be freely modified */ +} ENetPacket; + +typedef struct _ENetAcknowledgement +{ + ENetListNode acknowledgementList; + enet_uint32 sentTime; + ENetProtocol command; +} ENetAcknowledgement; + +typedef struct _ENetOutgoingCommand +{ + ENetListNode outgoingCommandList; + enet_uint16 reliableSequenceNumber; + enet_uint16 unreliableSequenceNumber; + enet_uint32 sentTime; + enet_uint32 roundTripTimeout; + enet_uint32 roundTripTimeoutLimit; + enet_uint32 fragmentOffset; + enet_uint16 fragmentLength; + enet_uint16 sendAttempts; + ENetProtocol command; + ENetPacket * packet; +} ENetOutgoingCommand; + +typedef struct _ENetIncomingCommand +{ + ENetListNode incomingCommandList; + enet_uint16 reliableSequenceNumber; + enet_uint16 unreliableSequenceNumber; + ENetProtocol command; + enet_uint32 fragmentCount; + enet_uint32 fragmentsRemaining; + enet_uint32 * fragments; + ENetPacket * packet; +} ENetIncomingCommand; + +typedef enum _ENetPeerState +{ + ENET_PEER_STATE_DISCONNECTED = 0, + ENET_PEER_STATE_CONNECTING = 1, + ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, + ENET_PEER_STATE_CONNECTION_PENDING = 3, + ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, + ENET_PEER_STATE_CONNECTED = 5, + ENET_PEER_STATE_DISCONNECT_LATER = 6, + ENET_PEER_STATE_DISCONNECTING = 7, + ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, + ENET_PEER_STATE_ZOMBIE = 9 +} ENetPeerState; + +#ifndef ENET_BUFFER_MAXIMUM +#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS) +#endif + +enum +{ + ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, + ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024, + ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, + ENET_HOST_DEFAULT_MTU = 1400, + + ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, + ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, + ENET_PEER_PACKET_THROTTLE_SCALE = 32, + ENET_PEER_PACKET_THROTTLE_COUNTER = 7, + ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, + ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, + ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, + ENET_PEER_PACKET_LOSS_SCALE = (1 << 16), + ENET_PEER_PACKET_LOSS_INTERVAL = 10000, + ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, + ENET_PEER_TIMEOUT_LIMIT = 32, + ENET_PEER_TIMEOUT_MINIMUM = 5000, + ENET_PEER_TIMEOUT_MAXIMUM = 30000, + ENET_PEER_PING_INTERVAL = 500, + ENET_PEER_UNSEQUENCED_WINDOWS = 64, + ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024, + ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32, + ENET_PEER_RELIABLE_WINDOWS = 16, + ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000, + ENET_PEER_FREE_RELIABLE_WINDOWS = 8 +}; + +typedef struct _ENetChannel +{ + enet_uint16 outgoingReliableSequenceNumber; + enet_uint16 outgoingUnreliableSequenceNumber; + enet_uint16 usedReliableWindows; + enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS]; + enet_uint16 incomingReliableSequenceNumber; + enet_uint16 incomingUnreliableSequenceNumber; + ENetList incomingReliableCommands; + ENetList incomingUnreliableCommands; +} ENetChannel; + +/** + * An ENet peer which data packets may be sent or received from. + * + * No fields should be modified unless otherwise specified. + */ +typedef struct _ENetPeer +{ + ENetListNode dispatchList; + struct _ENetHost * host; + enet_uint16 outgoingPeerID; + enet_uint16 incomingPeerID; + enet_uint32 connectID; + enet_uint8 outgoingSessionID; + enet_uint8 incomingSessionID; + ENetAddress address; /**< Internet address of the peer */ + void * data; /**< Application private data, may be freely modified */ + ENetPeerState state; + ENetChannel * channels; + size_t channelCount; /**< Number of channels allocated for communication with peer */ + enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ + enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ + enet_uint32 incomingBandwidthThrottleEpoch; + enet_uint32 outgoingBandwidthThrottleEpoch; + enet_uint32 incomingDataTotal; + enet_uint32 outgoingDataTotal; + enet_uint32 lastSendTime; + enet_uint32 lastReceiveTime; + enet_uint32 nextTimeout; + enet_uint32 earliestTimeout; + enet_uint32 packetLossEpoch; + enet_uint32 packetsSent; + enet_uint32 packetsLost; + enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ + enet_uint32 packetLossVariance; + enet_uint32 packetThrottle; + enet_uint32 packetThrottleLimit; + enet_uint32 packetThrottleCounter; + enet_uint32 packetThrottleEpoch; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 packetThrottleInterval; + enet_uint32 pingInterval; + enet_uint32 timeoutLimit; + enet_uint32 timeoutMinimum; + enet_uint32 timeoutMaximum; + enet_uint32 lastRoundTripTime; + enet_uint32 lowestRoundTripTime; + enet_uint32 lastRoundTripTimeVariance; + enet_uint32 highestRoundTripTimeVariance; + enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ + enet_uint32 roundTripTimeVariance; + enet_uint32 mtu; + enet_uint32 windowSize; + enet_uint32 reliableDataInTransit; + enet_uint16 outgoingReliableSequenceNumber; + ENetList acknowledgements; + ENetList sentReliableCommands; + ENetList sentUnreliableCommands; + ENetList outgoingReliableCommands; + ENetList outgoingUnreliableCommands; + ENetList dispatchedCommands; + int needsDispatch; + enet_uint16 incomingUnsequencedGroup; + enet_uint16 outgoingUnsequencedGroup; + enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; + enet_uint32 eventData; +} ENetPeer; + +/** An ENet packet compressor for compressing UDP packets before socket sends or receives. + */ +typedef struct _ENetCompressor +{ + /** Context data for the compressor. Must be non-NULL. */ + void * context; + /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ + size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit); + /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ + size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit); + /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */ + void (ENET_CALLBACK * destroy) (void * context); +} ENetCompressor; + +/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */ +typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount); + +/** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */ +typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event); + +/** An ENet host for communicating with peers. + * + * No fields should be modified unless otherwise stated. + + @sa enet_host_create() + @sa enet_host_destroy() + @sa enet_host_connect() + @sa enet_host_service() + @sa enet_host_flush() + @sa enet_host_broadcast() + @sa enet_host_compress() + @sa enet_host_compress_with_range_coder() + @sa enet_host_channel_limit() + @sa enet_host_bandwidth_limit() + @sa enet_host_bandwidth_throttle() + */ +typedef struct _ENetHost +{ + ENetSocket socket; + ENetAddress address; /**< Internet address of the host */ + enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ + enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ + enet_uint32 bandwidthThrottleEpoch; + enet_uint32 mtu; + enet_uint32 randomSeed; + int recalculateBandwidthLimits; + ENetPeer * peers; /**< array of peers allocated for this host */ + size_t peerCount; /**< number of peers allocated for this host */ + size_t channelLimit; /**< maximum number of channels allowed for connected peers */ + enet_uint32 serviceTime; + ENetList dispatchQueue; + int continueSending; + size_t packetSize; + enet_uint16 headerFlags; + ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; + size_t commandCount; + ENetBuffer buffers [ENET_BUFFER_MAXIMUM]; + size_t bufferCount; + ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */ + ENetCompressor compressor; + enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU]; + ENetAddress receivedAddress; + enet_uint8 * receivedData; + size_t receivedDataLength; + enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */ + enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */ + enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */ + enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */ + ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */ + size_t connectedPeers; + size_t bandwidthLimitedPeers; + size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */ +} ENetHost; + +/** + * An ENet event type, as specified in @ref ENetEvent. + */ +typedef enum _ENetEventType +{ + /** no event occurred within the specified time limit */ + ENET_EVENT_TYPE_NONE = 0, + + /** a connection request initiated by enet_host_connect has completed. + * The peer field contains the peer which successfully connected. + */ + ENET_EVENT_TYPE_CONNECT = 1, + + /** a peer has disconnected. This event is generated on a successful + * completion of a disconnect initiated by enet_pper_disconnect, if + * a peer has timed out, or if a connection request intialized by + * enet_host_connect has timed out. The peer field contains the peer + * which disconnected. The data field contains user supplied data + * describing the disconnection, or 0, if none is available. + */ + ENET_EVENT_TYPE_DISCONNECT = 2, + + /** a packet has been received from a peer. The peer field specifies the + * peer which sent the packet. The channelID field specifies the channel + * number upon which the packet was received. The packet field contains + * the packet that was received; this packet must be destroyed with + * enet_packet_destroy after use. + */ + ENET_EVENT_TYPE_RECEIVE = 3 +} ENetEventType; + +/** + * An ENet event as returned by enet_host_service(). + + @sa enet_host_service + */ +typedef struct _ENetEvent +{ + ENetEventType type; /**< type of the event */ + ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ + enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */ + enet_uint32 data; /**< data associated with the event, if appropriate */ + ENetPacket * packet; /**< packet associated with the event, if appropriate */ +} ENetEvent; + +/** @defgroup global ENet global functions + @{ +*/ + +/** + Initializes ENet globally. Must be called prior to using any functions in + ENet. + @returns 0 on success, < 0 on failure +*/ +ENET_API int enet_initialize (void); + +/** + Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored. + + @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use + @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults + @returns 0 on success, < 0 on failure +*/ +ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits); + +/** + Shuts down ENet globally. Should be called when a program that has + initialized ENet exits. +*/ +ENET_API void enet_deinitialize (void); + +/** + Gives the linked version of the ENet library. + @returns the version number +*/ +ENET_API ENetVersion enet_linked_version (void); + +/** @} */ + +/** @defgroup private ENet private implementation functions */ + +/** + Returns the wall-time in milliseconds. Its initial value is unspecified + unless otherwise set. + */ +ENET_API enet_uint32 enet_time_get (void); +/** + Sets the current wall-time in milliseconds. + */ +ENET_API void enet_time_set (enet_uint32); + +/** @defgroup socket ENet socket functions + @{ +*/ +ENET_API ENetSocket enet_socket_create (ENetSocketType); +ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *); +ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *); +ENET_API int enet_socket_listen (ENetSocket, int); +ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *); +ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *); +ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); +ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t); +ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32); +ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int); +ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *); +ENET_API int enet_socket_shutdown (ENetSocket, ENetSocketShutdown); +ENET_API void enet_socket_destroy (ENetSocket); +ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32); + +/** @} */ + +/** @defgroup Address ENet address functions + @{ +*/ +/** Attempts to resolve the host named by the parameter hostName and sets + the host field in the address parameter if successful. + @param address destination to store resolved address + @param hostName host name to lookup + @retval 0 on success + @retval < 0 on failure + @returns the address of the given hostName in address on success +*/ +ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName); + +/** Gives the printable form of the ip address specified in the address parameter. + @param address address printed + @param hostName destination for name, must not be NULL + @param nameLength maximum length of hostName. + @returns the null-terminated name of the host in hostName on success + @retval 0 on success + @retval < 0 on failure +*/ +ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength); + +/** Attempts to do a reverse lookup of the host field in the address parameter. + @param address address used for reverse lookup + @param hostName destination for name, must not be NULL + @param nameLength maximum length of hostName. + @returns the null-terminated name of the host in hostName on success + @retval 0 on success + @retval < 0 on failure +*/ +ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength); + +/** @} */ + +ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32); +ENET_API void enet_packet_destroy (ENetPacket *); +ENET_API int enet_packet_resize (ENetPacket *, size_t); +ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t); + +ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); +ENET_API void enet_host_destroy (ENetHost *); +ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32); +ENET_API int enet_host_check_events (ENetHost *, ENetEvent *); +ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32); +ENET_API void enet_host_flush (ENetHost *); +ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *); +ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *); +ENET_API int enet_host_compress_with_range_coder (ENetHost * host); +ENET_API void enet_host_channel_limit (ENetHost *, size_t); +ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); +extern void enet_host_bandwidth_throttle (ENetHost *); +extern enet_uint32 enet_host_random_seed (void); + +ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *); +ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID); +ENET_API void enet_peer_ping (ENetPeer *); +ENET_API void enet_peer_ping_interval (ENetPeer *, enet_uint32); +ENET_API void enet_peer_timeout (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); +ENET_API void enet_peer_reset (ENetPeer *); +ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32); +ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32); +ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32); +ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); +extern int enet_peer_throttle (ENetPeer *, enet_uint32); +extern void enet_peer_reset_queues (ENetPeer *); +extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *); +extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); +extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32); +extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16); +extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *); +extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *); +extern void enet_peer_on_connect (ENetPeer *); +extern void enet_peer_on_disconnect (ENetPeer *); + +ENET_API void * enet_range_coder_create (void); +ENET_API void enet_range_coder_destroy (void *); +ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t); +ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t); + +extern size_t enet_protocol_command_size (enet_uint8); + +#ifdef __cplusplus +} +#endif + +#endif /* __ENET_ENET_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/list.h b/src/libraries/enet/libenet/include/enet/list.h new file mode 100644 index 000000000..d7b260084 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/list.h @@ -0,0 +1,43 @@ +/** + @file list.h + @brief ENet list management +*/ +#ifndef __ENET_LIST_H__ +#define __ENET_LIST_H__ + +#include + +typedef struct _ENetListNode +{ + struct _ENetListNode * next; + struct _ENetListNode * previous; +} ENetListNode; + +typedef ENetListNode * ENetListIterator; + +typedef struct _ENetList +{ + ENetListNode sentinel; +} ENetList; + +extern void enet_list_clear (ENetList *); + +extern ENetListIterator enet_list_insert (ENetListIterator, void *); +extern void * enet_list_remove (ENetListIterator); +extern ENetListIterator enet_list_move (ENetListIterator, void *, void *); + +extern size_t enet_list_size (ENetList *); + +#define enet_list_begin(list) ((list) -> sentinel.next) +#define enet_list_end(list) (& (list) -> sentinel) + +#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list)) + +#define enet_list_next(iterator) ((iterator) -> next) +#define enet_list_previous(iterator) ((iterator) -> previous) + +#define enet_list_front(list) ((void *) (list) -> sentinel.next) +#define enet_list_back(list) ((void *) (list) -> sentinel.previous) + +#endif /* __ENET_LIST_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/protocol.h b/src/libraries/enet/libenet/include/enet/protocol.h new file mode 100644 index 000000000..b8f841629 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/protocol.h @@ -0,0 +1,199 @@ +/** + @file protocol.h + @brief ENet protocol +*/ +#ifndef __ENET_PROTOCOL_H__ +#define __ENET_PROTOCOL_H__ + +#include "enet/types.h" + +enum +{ + ENET_PROTOCOL_MINIMUM_MTU = 576, + ENET_PROTOCOL_MAXIMUM_MTU = 4096, + ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, + ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536, + ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, + ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, + ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF, + ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024, + ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024 +}; + +typedef enum _ENetProtocolCommand +{ + ENET_PROTOCOL_COMMAND_NONE = 0, + ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, + ENET_PROTOCOL_COMMAND_CONNECT = 2, + ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, + ENET_PROTOCOL_COMMAND_DISCONNECT = 4, + ENET_PROTOCOL_COMMAND_PING = 5, + ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, + ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, + ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, + ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, + ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, + ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, + ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, + ENET_PROTOCOL_COMMAND_COUNT = 13, + + ENET_PROTOCOL_COMMAND_MASK = 0x0F +} ENetProtocolCommand; + +typedef enum _ENetProtocolFlag +{ + ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), + ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), + + ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), + ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), + ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME, + + ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), + ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12 +} ENetProtocolFlag; + +#ifdef _MSC_VER_ +#pragma pack(push, 1) +#define ENET_PACKED +#elif defined(__GNUC__) || defined(__clang__) +#define ENET_PACKED __attribute__ ((packed)) +#else +#define ENET_PACKED +#endif + +typedef struct _ENetProtocolHeader +{ + enet_uint16 peerID; + enet_uint16 sentTime; +} ENET_PACKED ENetProtocolHeader; + +typedef struct _ENetProtocolCommandHeader +{ + enet_uint8 command; + enet_uint8 channelID; + enet_uint16 reliableSequenceNumber; +} ENET_PACKED ENetProtocolCommandHeader; + +typedef struct _ENetProtocolAcknowledge +{ + ENetProtocolCommandHeader header; + enet_uint16 receivedReliableSequenceNumber; + enet_uint16 receivedSentTime; +} ENET_PACKED ENetProtocolAcknowledge; + +typedef struct _ENetProtocolConnect +{ + ENetProtocolCommandHeader header; + enet_uint16 outgoingPeerID; + enet_uint8 incomingSessionID; + enet_uint8 outgoingSessionID; + enet_uint32 mtu; + enet_uint32 windowSize; + enet_uint32 channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 connectID; + enet_uint32 data; +} ENET_PACKED ENetProtocolConnect; + +typedef struct _ENetProtocolVerifyConnect +{ + ENetProtocolCommandHeader header; + enet_uint16 outgoingPeerID; + enet_uint8 incomingSessionID; + enet_uint8 outgoingSessionID; + enet_uint32 mtu; + enet_uint32 windowSize; + enet_uint32 channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 connectID; +} ENET_PACKED ENetProtocolVerifyConnect; + +typedef struct _ENetProtocolBandwidthLimit +{ + ENetProtocolCommandHeader header; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; +} ENET_PACKED ENetProtocolBandwidthLimit; + +typedef struct _ENetProtocolThrottleConfigure +{ + ENetProtocolCommandHeader header; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; +} ENET_PACKED ENetProtocolThrottleConfigure; + +typedef struct _ENetProtocolDisconnect +{ + ENetProtocolCommandHeader header; + enet_uint32 data; +} ENET_PACKED ENetProtocolDisconnect; + +typedef struct _ENetProtocolPing +{ + ENetProtocolCommandHeader header; +} ENET_PACKED ENetProtocolPing; + +typedef struct _ENetProtocolSendReliable +{ + ENetProtocolCommandHeader header; + enet_uint16 dataLength; +} ENET_PACKED ENetProtocolSendReliable; + +typedef struct _ENetProtocolSendUnreliable +{ + ENetProtocolCommandHeader header; + enet_uint16 unreliableSequenceNumber; + enet_uint16 dataLength; +} ENET_PACKED ENetProtocolSendUnreliable; + +typedef struct _ENetProtocolSendUnsequenced +{ + ENetProtocolCommandHeader header; + enet_uint16 unsequencedGroup; + enet_uint16 dataLength; +} ENET_PACKED ENetProtocolSendUnsequenced; + +typedef struct _ENetProtocolSendFragment +{ + ENetProtocolCommandHeader header; + enet_uint16 startSequenceNumber; + enet_uint16 dataLength; + enet_uint32 fragmentCount; + enet_uint32 fragmentNumber; + enet_uint32 totalLength; + enet_uint32 fragmentOffset; +} ENET_PACKED ENetProtocolSendFragment; + +typedef union _ENetProtocol +{ + ENetProtocolCommandHeader header; + ENetProtocolAcknowledge acknowledge; + ENetProtocolConnect connect; + ENetProtocolVerifyConnect verifyConnect; + ENetProtocolDisconnect disconnect; + ENetProtocolPing ping; + ENetProtocolSendReliable sendReliable; + ENetProtocolSendUnreliable sendUnreliable; + ENetProtocolSendUnsequenced sendUnsequenced; + ENetProtocolSendFragment sendFragment; + ENetProtocolBandwidthLimit bandwidthLimit; + ENetProtocolThrottleConfigure throttleConfigure; +} ENET_PACKED ENetProtocol; + +#ifdef _MSC_VER_ +#pragma pack(pop) +#endif + +#endif /* __ENET_PROTOCOL_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/time.h b/src/libraries/enet/libenet/include/enet/time.h new file mode 100644 index 000000000..c82a54603 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/time.h @@ -0,0 +1,18 @@ +/** + @file time.h + @brief ENet time constants and macros +*/ +#ifndef __ENET_TIME_H__ +#define __ENET_TIME_H__ + +#define ENET_TIME_OVERFLOW 86400000 + +#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW) +#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW) +#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b)) +#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b)) + +#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b)) + +#endif /* __ENET_TIME_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/types.h b/src/libraries/enet/libenet/include/enet/types.h new file mode 100644 index 000000000..ab010a4b1 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/types.h @@ -0,0 +1,13 @@ +/** + @file types.h + @brief type definitions for ENet +*/ +#ifndef __ENET_TYPES_H__ +#define __ENET_TYPES_H__ + +typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ +typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ +typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ + +#endif /* __ENET_TYPES_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/unix.h b/src/libraries/enet/libenet/include/enet/unix.h new file mode 100644 index 000000000..9683c09b4 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/unix.h @@ -0,0 +1,47 @@ +/** + @file unix.h + @brief ENet Unix header +*/ +#ifndef __ENET_UNIX_H__ +#define __ENET_UNIX_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef MSG_MAXIOVLEN +#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN +#endif + +typedef int ENetSocket; + +#define ENET_SOCKET_NULL -1 + +#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */ +#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */ + +#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */ +#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */ + +typedef struct +{ + void * data; + size_t dataLength; +} ENetBuffer; + +#define ENET_CALLBACK + +#define ENET_API extern + +typedef fd_set ENetSocketSet; + +#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) +#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) +#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) +#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) + +#endif /* __ENET_UNIX_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/utility.h b/src/libraries/enet/libenet/include/enet/utility.h new file mode 100644 index 000000000..e48a476be --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/utility.h @@ -0,0 +1,12 @@ +/** + @file utility.h + @brief ENet utility header +*/ +#ifndef __ENET_UTILITY_H__ +#define __ENET_UTILITY_H__ + +#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#endif /* __ENET_UTILITY_H__ */ + diff --git a/src/libraries/enet/libenet/include/enet/win32.h b/src/libraries/enet/libenet/include/enet/win32.h new file mode 100644 index 000000000..197dfc047 --- /dev/null +++ b/src/libraries/enet/libenet/include/enet/win32.h @@ -0,0 +1,58 @@ +/** + @file win32.h + @brief ENet Win32 header +*/ +#ifndef __ENET_WIN32_H__ +#define __ENET_WIN32_H__ + +#ifdef _MSC_VER +#ifdef ENET_BUILDING_LIB +#pragma warning (disable: 4996) // 'strncpy' was declared deprecated +#pragma warning (disable: 4267) // size_t to int conversion +#pragma warning (disable: 4244) // 64bit to 32bit int +#pragma warning (disable: 4018) // signed/unsigned mismatch +#pragma warning (disable: 4146) // unary minus operator applied to unsigned type +#endif +#endif + +#include +#include + +typedef SOCKET ENetSocket; + +#define ENET_SOCKET_NULL INVALID_SOCKET + +#define ENET_HOST_TO_NET_16(value) (htons (value)) +#define ENET_HOST_TO_NET_32(value) (htonl (value)) + +#define ENET_NET_TO_HOST_16(value) (ntohs (value)) +#define ENET_NET_TO_HOST_32(value) (ntohl (value)) + +typedef struct +{ + size_t dataLength; + void * data; +} ENetBuffer; + +#define ENET_CALLBACK __cdecl + +#ifdef ENET_DLL +#ifdef ENET_BUILDING_LIB +#define ENET_API __declspec( dllexport ) +#else +#define ENET_API __declspec( dllimport ) +#endif /* ENET_BUILDING_LIB */ +#else /* !ENET_DLL */ +#define ENET_API extern +#endif /* ENET_DLL */ + +typedef fd_set ENetSocketSet; + +#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) +#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) +#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) +#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) + +#endif /* __ENET_WIN32_H__ */ + + diff --git a/src/libraries/enet/libenet/list.c b/src/libraries/enet/libenet/list.c new file mode 100644 index 000000000..1c1a8dfaa --- /dev/null +++ b/src/libraries/enet/libenet/list.c @@ -0,0 +1,75 @@ +/** + @file list.c + @brief ENet linked list functions +*/ +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +/** + @defgroup list ENet linked list utility functions + @ingroup private + @{ +*/ +void +enet_list_clear (ENetList * list) +{ + list -> sentinel.next = & list -> sentinel; + list -> sentinel.previous = & list -> sentinel; +} + +ENetListIterator +enet_list_insert (ENetListIterator position, void * data) +{ + ENetListIterator result = (ENetListIterator) data; + + result -> previous = position -> previous; + result -> next = position; + + result -> previous -> next = result; + position -> previous = result; + + return result; +} + +void * +enet_list_remove (ENetListIterator position) +{ + position -> previous -> next = position -> next; + position -> next -> previous = position -> previous; + + return position; +} + +ENetListIterator +enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast) +{ + ENetListIterator first = (ENetListIterator) dataFirst, + last = (ENetListIterator) dataLast; + + first -> previous -> next = last -> next; + last -> next -> previous = first -> previous; + + first -> previous = position -> previous; + last -> next = position; + + first -> previous -> next = first; + position -> previous = last; + + return first; +} + +size_t +enet_list_size (ENetList * list) +{ + size_t size = 0; + ENetListIterator position; + + for (position = enet_list_begin (list); + position != enet_list_end (list); + position = enet_list_next (position)) + ++ size; + + return size; +} + +/** @} */ diff --git a/src/libraries/enet/libenet/packet.c b/src/libraries/enet/libenet/packet.c new file mode 100644 index 000000000..9a997be4e --- /dev/null +++ b/src/libraries/enet/libenet/packet.c @@ -0,0 +1,165 @@ +/** + @file packet.c + @brief ENet packet management functions +*/ +#include +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +/** @defgroup Packet ENet packet functions + @{ +*/ + +/** Creates a packet that may be sent to a peer. + @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL. + @param dataLength size of the data allocated for this packet + @param flags flags for this packet as described for the ENetPacket structure. + @returns the packet on success, NULL on failure +*/ +ENetPacket * +enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags) +{ + ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket)); + if (packet == NULL) + return NULL; + + if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) + packet -> data = (enet_uint8 *) data; + else + if (dataLength <= 0) + packet -> data = NULL; + else + { + packet -> data = (enet_uint8 *) enet_malloc (dataLength); + if (packet -> data == NULL) + { + enet_free (packet); + return NULL; + } + + if (data != NULL) + memcpy (packet -> data, data, dataLength); + } + + packet -> referenceCount = 0; + packet -> flags = flags; + packet -> dataLength = dataLength; + packet -> freeCallback = NULL; + packet -> userData = NULL; + + return packet; +} + +/** Destroys the packet and deallocates its data. + @param packet packet to be destroyed +*/ +void +enet_packet_destroy (ENetPacket * packet) +{ + if (packet == NULL) + return; + + if (packet -> freeCallback != NULL) + (* packet -> freeCallback) (packet); + if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) && + packet -> data != NULL) + enet_free (packet -> data); + enet_free (packet); +} + +/** Attempts to resize the data in the packet to length specified in the + dataLength parameter + @param packet packet to resize + @param dataLength new size for the packet data + @returns 0 on success, < 0 on failure +*/ +int +enet_packet_resize (ENetPacket * packet, size_t dataLength) +{ + enet_uint8 * newData; + + if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) + { + packet -> dataLength = dataLength; + + return 0; + } + + newData = (enet_uint8 *) enet_malloc (dataLength); + if (newData == NULL) + return -1; + + memcpy (newData, packet -> data, packet -> dataLength); + enet_free (packet -> data); + + packet -> data = newData; + packet -> dataLength = dataLength; + + return 0; +} + +static int initializedCRC32 = 0; +static enet_uint32 crcTable [256]; + +static enet_uint32 +reflect_crc (int val, int bits) +{ + int result = 0, bit; + + for (bit = 0; bit < bits; bit ++) + { + if(val & 1) result |= 1 << (bits - 1 - bit); + val >>= 1; + } + + return result; +} + +static void +initialize_crc32 (void) +{ + int byte; + + for (byte = 0; byte < 256; ++ byte) + { + enet_uint32 crc = reflect_crc (byte, 8) << 24; + int offset; + + for(offset = 0; offset < 8; ++ offset) + { + if (crc & 0x80000000) + crc = (crc << 1) ^ 0x04c11db7; + else + crc <<= 1; + } + + crcTable [byte] = reflect_crc (crc, 32); + } + + initializedCRC32 = 1; +} + +enet_uint32 +enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) +{ + enet_uint32 crc = 0xFFFFFFFF; + + if (! initializedCRC32) initialize_crc32 (); + + while (bufferCount -- > 0) + { + const enet_uint8 * data = (const enet_uint8 *) buffers -> data, + * dataEnd = & data [buffers -> dataLength]; + + while (data < dataEnd) + { + crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; + } + + ++ buffers; + } + + return ENET_HOST_TO_NET_32 (~ crc); +} + +/** @} */ diff --git a/src/libraries/enet/libenet/peer.c b/src/libraries/enet/libenet/peer.c new file mode 100644 index 000000000..318f2c259 --- /dev/null +++ b/src/libraries/enet/libenet/peer.c @@ -0,0 +1,989 @@ +/** + @file peer.c + @brief ENet peer management functions +*/ +#include +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +/** @defgroup peer ENet peer functions + @{ +*/ + +/** Configures throttle parameter for a peer. + + Unreliable packets are dropped by ENet in response to the varying conditions + of the Internet connection to the peer. The throttle represents a probability + that an unreliable packet should not be dropped and thus sent by ENet to the peer. + The lowest mean round trip time from the sending of a reliable packet to the + receipt of its acknowledgement is measured over an amount of time specified by + the interval parameter in milliseconds. If a measured round trip time happens to + be significantly less than the mean round trip time measured over the interval, + then the throttle probability is increased to allow more traffic by an amount + specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE + constant. If a measured round trip time happens to be significantly greater than + the mean round trip time measured over the interval, then the throttle probability + is decreased to limit traffic by an amount specified in the deceleration parameter, which + is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has + a value of ENET_PEER_PACKET_THROTTLE_SCALE, no unreliable packets are dropped by + ENet, and so 100% of all unreliable packets will be sent. When the throttle has a + value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable + packets will be sent. Intermediate values for the throttle represent intermediate + probabilities between 0% and 100% of unreliable packets being sent. The bandwidth + limits of the local and foreign hosts are taken into account to determine a + sensible limit for the throttle probability above which it should not raise even in + the best of conditions. + + @param peer peer to configure + @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL. + @param acceleration rate at which to increase the throttle probability as mean RTT declines + @param deceleration rate at which to decrease the throttle probability as mean RTT increases +*/ +void +enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration) +{ + ENetProtocol command; + + peer -> packetThrottleInterval = interval; + peer -> packetThrottleAcceleration = acceleration; + peer -> packetThrottleDeceleration = deceleration; + + command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + + command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval); + command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration); + command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); +} + +int +enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) +{ + if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance) + { + peer -> packetThrottle = peer -> packetThrottleLimit; + } + else + if (rtt < peer -> lastRoundTripTime) + { + peer -> packetThrottle += peer -> packetThrottleAcceleration; + + if (peer -> packetThrottle > peer -> packetThrottleLimit) + peer -> packetThrottle = peer -> packetThrottleLimit; + + return 1; + } + else + if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance) + { + if (peer -> packetThrottle > peer -> packetThrottleDeceleration) + peer -> packetThrottle -= peer -> packetThrottleDeceleration; + else + peer -> packetThrottle = 0; + + return -1; + } + + return 0; +} + +/** Queues a packet to be sent. + @param peer destination for the packet + @param channelID channel on which to send + @param packet packet to send + @retval 0 on success + @retval < 0 on failure +*/ +int +enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) +{ + ENetChannel * channel = & peer -> channels [channelID]; + ENetProtocol command; + size_t fragmentLength; + + if (peer -> state != ENET_PEER_STATE_CONNECTED || + channelID >= peer -> channelCount || + packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE) + return -1; + + fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); + if (peer -> host -> checksum != NULL) + fragmentLength -= sizeof(enet_uint32); + + if (packet -> dataLength > fragmentLength) + { + enet_uint32 fragmentCount = (packet -> dataLength + fragmentLength - 1) / fragmentLength, + fragmentNumber, + fragmentOffset; + enet_uint8 commandNumber; + enet_uint16 startSequenceNumber; + ENetList fragments; + ENetOutgoingCommand * fragment; + + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) + return -1; + + if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT && + channel -> outgoingUnreliableSequenceNumber < 0xFFFF) + { + commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT; + startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1); + } + else + { + commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1); + } + + enet_list_clear (& fragments); + + for (fragmentNumber = 0, + fragmentOffset = 0; + fragmentOffset < packet -> dataLength; + ++ fragmentNumber, + fragmentOffset += fragmentLength) + { + if (packet -> dataLength - fragmentOffset < fragmentLength) + fragmentLength = packet -> dataLength - fragmentOffset; + + fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); + if (fragment == NULL) + { + while (! enet_list_empty (& fragments)) + { + fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); + + enet_free (fragment); + } + + return -1; + } + + fragment -> fragmentOffset = fragmentOffset; + fragment -> fragmentLength = fragmentLength; + fragment -> packet = packet; + fragment -> command.header.command = commandNumber; + fragment -> command.header.channelID = channelID; + fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber; + fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength); + fragment -> command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32 (fragmentCount); + fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); + fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); + fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); + + enet_list_insert (enet_list_end (& fragments), fragment); + } + + packet -> referenceCount += fragmentNumber; + + while (! enet_list_empty (& fragments)) + { + fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); + + enet_peer_setup_outgoing_command (peer, fragment); + } + + return 0; + } + + command.header.channelID = channelID; + + if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED) + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; + command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); + } + else + if (packet -> flags & ENET_PACKET_FLAG_RELIABLE || channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); + } + else + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; + command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); + } + + if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL) + return -1; + + return 0; +} + +/** Attempts to dequeue any incoming queued packet. + @param peer peer to dequeue packets from + @param channelID holds the channel ID of the channel the packet was received on success + @returns a pointer to the packet, or NULL if there are no available incoming queued packets +*/ +ENetPacket * +enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID) +{ + ENetIncomingCommand * incomingCommand; + ENetPacket * packet; + + if (enet_list_empty (& peer -> dispatchedCommands)) + return NULL; + + incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands)); + + if (channelID != NULL) + * channelID = incomingCommand -> command.header.channelID; + + packet = incomingCommand -> packet; + + -- packet -> referenceCount; + + if (incomingCommand -> fragments != NULL) + enet_free (incomingCommand -> fragments); + + enet_free (incomingCommand); + + return packet; +} + +static void +enet_peer_reset_outgoing_commands (ENetList * queue) +{ + ENetOutgoingCommand * outgoingCommand; + + while (! enet_list_empty (queue)) + { + outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue)); + + if (outgoingCommand -> packet != NULL) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); + } + + enet_free (outgoingCommand); + } +} + +static void +enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand) +{ + ENetListIterator currentCommand; + + for (currentCommand = startCommand; currentCommand != endCommand; ) + { + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + + currentCommand = enet_list_next (currentCommand); + + enet_list_remove (& incomingCommand -> incomingCommandList); + + if (incomingCommand -> packet != NULL) + { + -- incomingCommand -> packet -> referenceCount; + + if (incomingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (incomingCommand -> packet); + } + + if (incomingCommand -> fragments != NULL) + enet_free (incomingCommand -> fragments); + + enet_free (incomingCommand); + } +} + +static void +enet_peer_reset_incoming_commands (ENetList * queue) +{ + enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue)); +} + +void +enet_peer_reset_queues (ENetPeer * peer) +{ + ENetChannel * channel; + + if (peer -> needsDispatch) + { + enet_list_remove (& peer -> dispatchList); + + peer -> needsDispatch = 0; + } + + while (! enet_list_empty (& peer -> acknowledgements)) + enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements))); + + enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); + enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); + enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands); + enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands); + enet_peer_reset_incoming_commands (& peer -> dispatchedCommands); + + if (peer -> channels != NULL && peer -> channelCount > 0) + { + for (channel = peer -> channels; + channel < & peer -> channels [peer -> channelCount]; + ++ channel) + { + enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands); + enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands); + } + + enet_free (peer -> channels); + } + + peer -> channels = NULL; + peer -> channelCount = 0; +} + +void +enet_peer_on_connect (ENetPeer * peer) +{ + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + { + if (peer -> incomingBandwidth != 0) + ++ peer -> host -> bandwidthLimitedPeers; + + ++ peer -> host -> connectedPeers; + } +} + +void +enet_peer_on_disconnect (ENetPeer * peer) +{ + if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) + { + if (peer -> incomingBandwidth != 0) + -- peer -> host -> bandwidthLimitedPeers; + + -- peer -> host -> connectedPeers; + } +} + +/** Forcefully disconnects a peer. + @param peer peer to forcefully disconnect + @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout + on its connection to the local host. +*/ +void +enet_peer_reset (ENetPeer * peer) +{ + enet_peer_on_disconnect (peer); + + peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; + peer -> connectID = 0; + + peer -> state = ENET_PEER_STATE_DISCONNECTED; + + peer -> incomingBandwidth = 0; + peer -> outgoingBandwidth = 0; + peer -> incomingBandwidthThrottleEpoch = 0; + peer -> outgoingBandwidthThrottleEpoch = 0; + peer -> incomingDataTotal = 0; + peer -> outgoingDataTotal = 0; + peer -> lastSendTime = 0; + peer -> lastReceiveTime = 0; + peer -> nextTimeout = 0; + peer -> earliestTimeout = 0; + peer -> packetLossEpoch = 0; + peer -> packetsSent = 0; + peer -> packetsLost = 0; + peer -> packetLoss = 0; + peer -> packetLossVariance = 0; + peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE; + peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE; + peer -> packetThrottleCounter = 0; + peer -> packetThrottleEpoch = 0; + peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION; + peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION; + peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL; + peer -> pingInterval = ENET_PEER_PING_INTERVAL; + peer -> timeoutLimit = ENET_PEER_TIMEOUT_LIMIT; + peer -> timeoutMinimum = ENET_PEER_TIMEOUT_MINIMUM; + peer -> timeoutMaximum = ENET_PEER_TIMEOUT_MAXIMUM; + peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer -> lastRoundTripTimeVariance = 0; + peer -> highestRoundTripTimeVariance = 0; + peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer -> roundTripTimeVariance = 0; + peer -> mtu = peer -> host -> mtu; + peer -> reliableDataInTransit = 0; + peer -> outgoingReliableSequenceNumber = 0; + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + peer -> incomingUnsequencedGroup = 0; + peer -> outgoingUnsequencedGroup = 0; + peer -> eventData = 0; + + memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); + + enet_peer_reset_queues (peer); +} + +/** Sends a ping request to a peer. + @param peer destination for the ping request + @remarks ping requests factor into the mean round trip time as designated by the + roundTripTime field in the ENetPeer structure. Enet automatically pings all connected + peers at regular intervals, however, this function may be called to ensure more + frequent ping requests. +*/ +void +enet_peer_ping (ENetPeer * peer) +{ + ENetProtocol command; + + if (peer -> state != ENET_PEER_STATE_CONNECTED) + return; + + command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); +} + +/** Sets the interval at which pings will be sent to a peer. + + Pings are used both to monitor the liveness of the connection and also to dynamically + adjust the throttle during periods of low traffic so that the throttle has reasonable + responsiveness during traffic spikes. + + @param peer the peer to adjust + @param pingInterval the interval at which to send pings; defaults to ENET_PEER_PING_INTERVAL if 0 +*/ +void +enet_peer_ping_interval (ENetPeer * peer, enet_uint32 pingInterval) +{ + peer -> pingInterval = pingInterval ? pingInterval : ENET_PEER_PING_INTERVAL; +} + +/** Sets the timeout parameters for a peer. + + The timeout parameter control how and when a peer will timeout from a failure to acknowledge + reliable traffic. Timeout values use an exponential backoff mechanism, where if a reliable + packet is not acknowledge within some multiple of the average RTT plus a variance tolerance, + the timeout will be doubled until it reaches a set limit. If the timeout is thus at this + limit and reliable packets have been sent but not acknowledged within a certain minimum time + period, the peer will be disconnected. Alternatively, if reliable packets have been sent + but not acknowledged for a certain maximum time period, the peer will be disconnected regardless + of the current timeout limit value. + + @param peer the peer to adjust + @param timeoutLimit the timeout limit; defaults to ENET_PEER_TIMEOUT_LIMIT if 0 + @param timeoutMinimum the timeout minimum; defaults to ENET_PEER_TIMEOUT_MINIMUM if 0 + @param timeoutMaximum the timeout maximum; defaults to ENET_PEER_TIMEOUT_MAXIMUM if 0 +*/ + +void +enet_peer_timeout (ENetPeer * peer, enet_uint32 timeoutLimit, enet_uint32 timeoutMinimum, enet_uint32 timeoutMaximum) +{ + peer -> timeoutLimit = timeoutLimit ? timeoutLimit : ENET_PEER_TIMEOUT_LIMIT; + peer -> timeoutMinimum = timeoutMinimum ? timeoutMinimum : ENET_PEER_TIMEOUT_MINIMUM; + peer -> timeoutMaximum = timeoutMaximum ? timeoutMaximum : ENET_PEER_TIMEOUT_MAXIMUM; +} + +/** Force an immediate disconnection from a peer. + @param peer peer to disconnect + @param data data describing the disconnection + @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not + guarenteed to receive the disconnect notification, and is reset immediately upon + return from this function. +*/ +void +enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data) +{ + ENetProtocol command; + + if (peer -> state == ENET_PEER_STATE_DISCONNECTED) + return; + + if (peer -> state != ENET_PEER_STATE_ZOMBIE && + peer -> state != ENET_PEER_STATE_DISCONNECTING) + { + enet_peer_reset_queues (peer); + + command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; + command.header.channelID = 0xFF; + command.disconnect.data = ENET_HOST_TO_NET_32 (data); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + + enet_host_flush (peer -> host); + } + + enet_peer_reset (peer); +} + +/** Request a disconnection from a peer. + @param peer peer to request a disconnection + @param data data describing the disconnection + @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() + once the disconnection is complete. +*/ +void +enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) +{ + ENetProtocol command; + + if (peer -> state == ENET_PEER_STATE_DISCONNECTING || + peer -> state == ENET_PEER_STATE_DISCONNECTED || + peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT || + peer -> state == ENET_PEER_STATE_ZOMBIE) + return; + + enet_peer_reset_queues (peer); + + command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; + command.header.channelID = 0xFF; + command.disconnect.data = ENET_HOST_TO_NET_32 (data); + + if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) + command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + else + command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + + if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) + { + enet_peer_on_disconnect (peer); + + peer -> state = ENET_PEER_STATE_DISCONNECTING; + } + else + { + enet_host_flush (peer -> host); + enet_peer_reset (peer); + } +} + +/** Request a disconnection from a peer, but only after all queued outgoing packets are sent. + @param peer peer to request a disconnection + @param data data describing the disconnection + @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() + once the disconnection is complete. +*/ +void +enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) +{ + if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && + ! (enet_list_empty (& peer -> outgoingReliableCommands) && + enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> sentReliableCommands))) + { + peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; + peer -> eventData = data; + } + else + enet_peer_disconnect (peer, data); +} + +ENetAcknowledgement * +enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime) +{ + ENetAcknowledgement * acknowledgement; + + if (command -> header.channelID < peer -> channelCount) + { + ENetChannel * channel = & peer -> channels [command -> header.channelID]; + enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, + currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + + if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + + if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS) + return NULL; + } + + acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement)); + if (acknowledgement == NULL) + return NULL; + + peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge); + + acknowledgement -> sentTime = sentTime; + acknowledgement -> command = * command; + + enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement); + + return acknowledgement; +} + +void +enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand) +{ + ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID]; + + peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength; + + if (outgoingCommand -> command.header.channelID == 0xFF) + { + ++ peer -> outgoingReliableSequenceNumber; + + outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + { + ++ channel -> outgoingReliableSequenceNumber; + channel -> outgoingUnreliableSequenceNumber = 0; + + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) + { + ++ peer -> outgoingUnsequencedGroup; + + outgoingCommand -> reliableSequenceNumber = 0; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + { + if (outgoingCommand -> fragmentOffset == 0) + ++ channel -> outgoingUnreliableSequenceNumber; + + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; + } + + outgoingCommand -> sendAttempts = 0; + outgoingCommand -> sentTime = 0; + outgoingCommand -> roundTripTimeout = 0; + outgoingCommand -> roundTripTimeoutLimit = 0; + outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber); + + switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + outgoingCommand -> command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> unreliableSequenceNumber); + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + outgoingCommand -> command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup); + break; + + default: + break; + } + + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); + else + enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); +} + +ENetOutgoingCommand * +enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length) +{ + ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); + if (outgoingCommand == NULL) + return NULL; + + outgoingCommand -> command = * command; + outgoingCommand -> fragmentOffset = offset; + outgoingCommand -> fragmentLength = length; + outgoingCommand -> packet = packet; + if (packet != NULL) + ++ packet -> referenceCount; + + enet_peer_setup_outgoing_command (peer, outgoingCommand); + + return outgoingCommand; +} + +void +enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) +{ + ENetListIterator droppedCommand, startCommand, currentCommand; + + for (droppedCommand = startCommand = currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); + currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); + currentCommand = enet_list_next (currentCommand)) + { + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + + if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + continue; + + if (incomingCommand -> reliableSequenceNumber == channel -> incomingReliableSequenceNumber) + { + if (incomingCommand -> fragmentsRemaining <= 0) + { + channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; + continue; + } + + if (startCommand != currentCommand) + { + enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } + + droppedCommand = currentCommand; + } + else + if (droppedCommand != currentCommand) + droppedCommand = enet_list_previous (currentCommand); + } + else + { + enet_uint16 reliableWindow = incomingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, + currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + if (reliableWindow >= currentWindow && reliableWindow < currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + break; + + droppedCommand = enet_list_next (currentCommand); + + if (startCommand != currentCommand) + { + enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } + } + } + + startCommand = enet_list_next (currentCommand); + } + + if (startCommand != currentCommand) + { + enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } + + droppedCommand = currentCommand; + } + + enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand); +} + +void +enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel) +{ + ENetListIterator currentCommand; + + for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands); + currentCommand != enet_list_end (& channel -> incomingReliableCommands); + currentCommand = enet_list_next (currentCommand)) + { + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (incomingCommand -> fragmentsRemaining > 0 || + incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1)) + break; + + channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber; + + if (incomingCommand -> fragmentCount > 0) + channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1; + } + + if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands)) + return; + + channel -> incomingUnreliableSequenceNumber = 0; + + enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand)); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } + + if (! enet_list_empty (& channel -> incomingUnreliableCommands)) + enet_peer_dispatch_incoming_unreliable_commands (peer, channel); +} + +ENetIncomingCommand * +enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) +{ + static ENetIncomingCommand dummyCommand; + + ENetChannel * channel = & peer -> channels [command -> header.channelID]; + enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber = 0; + enet_uint16 reliableWindow, currentWindow; + ENetIncomingCommand * incomingCommand; + ENetListIterator currentCommand; + + if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) + goto freePacket; + + if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + { + reliableSequenceNumber = command -> header.reliableSequenceNumber; + reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + + if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + goto freePacket; + } + + switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber) + goto freePacket; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); + currentCommand != enet_list_end (& channel -> incomingReliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) + break; + + goto freePacket; + } + } + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: + unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber); + + if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && + unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) + goto freePacket; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); + currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + incomingCommand = (ENetIncomingCommand *) currentCommand; + + if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + continue; + + if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber) + continue; + + if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber) + { + if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) + break; + + goto freePacket; + } + } + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + currentCommand = enet_list_end (& channel -> incomingUnreliableCommands); + break; + + default: + goto freePacket; + } + + incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); + if (incomingCommand == NULL) + goto notifyError; + + incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; + incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; + incomingCommand -> command = * command; + incomingCommand -> fragmentCount = fragmentCount; + incomingCommand -> fragmentsRemaining = fragmentCount; + incomingCommand -> packet = packet; + incomingCommand -> fragments = NULL; + + if (fragmentCount > 0) + { + if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) + incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); + if (incomingCommand -> fragments == NULL) + { + enet_free (incomingCommand); + + goto notifyError; + } + memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32)); + } + + if (packet != NULL) + ++ packet -> referenceCount; + + enet_list_insert (enet_list_next (currentCommand), incomingCommand); + + switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + enet_peer_dispatch_incoming_reliable_commands (peer, channel); + break; + + default: + enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + break; + } + + return incomingCommand; + +freePacket: + if (fragmentCount > 0) + goto notifyError; + + if (packet != NULL && packet -> referenceCount == 0) + enet_packet_destroy (packet); + + return & dummyCommand; + +notifyError: + if (packet != NULL && packet -> referenceCount == 0) + enet_packet_destroy (packet); + + return NULL; +} + +/** @} */ diff --git a/src/libraries/enet/libenet/protocol.c b/src/libraries/enet/libenet/protocol.c new file mode 100644 index 000000000..3438a5dad --- /dev/null +++ b/src/libraries/enet/libenet/protocol.c @@ -0,0 +1,1925 @@ +/** + @file protocol.c + @brief ENet protocol functions +*/ +#include +#include +#define ENET_BUILDING_LIB 1 +#include "enet/utility.h" +#include "enet/time.h" +#include "enet/enet.h" + +static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = +{ + 0, + sizeof (ENetProtocolAcknowledge), + sizeof (ENetProtocolConnect), + sizeof (ENetProtocolVerifyConnect), + sizeof (ENetProtocolDisconnect), + sizeof (ENetProtocolPing), + sizeof (ENetProtocolSendReliable), + sizeof (ENetProtocolSendUnreliable), + sizeof (ENetProtocolSendFragment), + sizeof (ENetProtocolSendUnsequenced), + sizeof (ENetProtocolBandwidthLimit), + sizeof (ENetProtocolThrottleConfigure), + sizeof (ENetProtocolSendFragment) +}; + +size_t +enet_protocol_command_size (enet_uint8 commandNumber) +{ + return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK]; +} + +static void +enet_protocol_change_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) +{ + if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER) + enet_peer_on_connect (peer); + else + enet_peer_on_disconnect (peer); + + peer -> state = state; +} + +static void +enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) +{ + enet_protocol_change_state (host, peer, state); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } +} + +static int +enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) +{ + while (! enet_list_empty (& host -> dispatchQueue)) + { + ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue)); + + peer -> needsDispatch = 0; + + switch (peer -> state) + { + case ENET_PEER_STATE_CONNECTION_PENDING: + case ENET_PEER_STATE_CONNECTION_SUCCEEDED: + enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED); + + event -> type = ENET_EVENT_TYPE_CONNECT; + event -> peer = peer; + event -> data = peer -> eventData; + + return 1; + + case ENET_PEER_STATE_ZOMBIE: + host -> recalculateBandwidthLimits = 1; + + event -> type = ENET_EVENT_TYPE_DISCONNECT; + event -> peer = peer; + event -> data = peer -> eventData; + + enet_peer_reset (peer); + + return 1; + + case ENET_PEER_STATE_CONNECTED: + if (enet_list_empty (& peer -> dispatchedCommands)) + continue; + + event -> packet = enet_peer_receive (peer, & event -> channelID); + if (event -> packet == NULL) + continue; + + event -> type = ENET_EVENT_TYPE_RECEIVE; + event -> peer = peer; + + if (! enet_list_empty (& peer -> dispatchedCommands)) + { + peer -> needsDispatch = 1; + + enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); + } + + return 1; + + default: + break; + } + } + + return 0; +} + +static void +enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event) +{ + host -> recalculateBandwidthLimits = 1; + + if (event != NULL) + { + enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED); + + event -> type = ENET_EVENT_TYPE_CONNECT; + event -> peer = peer; + event -> data = peer -> eventData; + } + else + enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); +} + +static void +enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event) +{ + if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING) + host -> recalculateBandwidthLimits = 1; + + if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) + enet_peer_reset (peer); + else + if (event != NULL) + { + event -> type = ENET_EVENT_TYPE_DISCONNECT; + event -> peer = peer; + event -> data = 0; + + enet_peer_reset (peer); + } + else + { + peer -> eventData = 0; + + enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + } +} + +static void +enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) +{ + ENetOutgoingCommand * outgoingCommand; + + while (! enet_list_empty (& peer -> sentUnreliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + { + outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; + + enet_packet_destroy (outgoingCommand -> packet); + } + } + + enet_free (outgoingCommand); + } +} + +static ENetProtocolCommand +enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) +{ + ENetOutgoingCommand * outgoingCommand = NULL; + ENetListIterator currentCommand; + ENetProtocolCommand commandNumber; + int wasSent = 1; + + for (currentCommand = enet_list_begin (& peer -> sentReliableCommands); + currentCommand != enet_list_end (& peer -> sentReliableCommands); + currentCommand = enet_list_next (currentCommand)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && + outgoingCommand -> command.header.channelID == channelID) + break; + } + + if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) + { + for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); + currentCommand != enet_list_end (& peer -> outgoingReliableCommands); + currentCommand = enet_list_next (currentCommand)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE; + + if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && + outgoingCommand -> command.header.channelID == channelID) + break; + } + + if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands)) + return ENET_PROTOCOL_COMMAND_NONE; + + wasSent = 0; + } + + if (outgoingCommand == NULL) + return ENET_PROTOCOL_COMMAND_NONE; + + if (channelID < peer -> channelCount) + { + ENetChannel * channel = & peer -> channels [channelID]; + enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (channel -> reliableWindows [reliableWindow] > 0) + { + -- channel -> reliableWindows [reliableWindow]; + if (! channel -> reliableWindows [reliableWindow]) + channel -> usedReliableWindows &= ~ (1 << reliableWindow); + } + } + + commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK); + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + { + if (wasSent) + peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; + + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + { + outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; + + enet_packet_destroy (outgoingCommand -> packet); + } + } + + enet_free (outgoingCommand); + + if (enet_list_empty (& peer -> sentReliableCommands)) + return commandNumber; + + outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands); + + peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; + + return commandNumber; +} + +static ENetPeer * +enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command) +{ + enet_uint8 incomingSessionID, outgoingSessionID; + enet_uint32 mtu, windowSize; + ENetChannel * channel; + size_t channelCount, duplicatePeers = 0; + ENetPeer * currentPeer, * peer = NULL; + ENetProtocol verifyCommand; + + channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); + + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || + channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + return NULL; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) + { + if (peer == NULL) + peer = currentPeer; + } + else + if (currentPeer -> address.host == host -> receivedAddress.host) + { + if (currentPeer -> address.port == host -> receivedAddress.port && + currentPeer -> connectID == command -> connect.connectID) + return NULL; + + ++ duplicatePeers; + } + } + + if (peer == NULL || duplicatePeers >= host -> duplicatePeers) + return NULL; + + if (channelCount > host -> channelLimit) + channelCount = host -> channelLimit; + peer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); + if (peer -> channels == NULL) + return NULL; + peer -> channelCount = channelCount; + peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; + peer -> connectID = command -> connect.connectID; + peer -> address = host -> receivedAddress; + peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); + peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); + peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); + peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); + peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); + peer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); + + incomingSessionID = command -> connect.incomingSessionID == 0xFF ? peer -> outgoingSessionID : command -> connect.incomingSessionID; + incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + if (incomingSessionID == peer -> outgoingSessionID) + incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + peer -> outgoingSessionID = incomingSessionID; + + outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? peer -> incomingSessionID : command -> connect.outgoingSessionID; + outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + if (outgoingSessionID == peer -> incomingSessionID) + outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + peer -> incomingSessionID = outgoingSessionID; + + for (channel = peer -> channels; + channel < & peer -> channels [channelCount]; + ++ channel) + { + channel -> outgoingReliableSequenceNumber = 0; + channel -> outgoingUnreliableSequenceNumber = 0; + channel -> incomingReliableSequenceNumber = 0; + channel -> incomingUnreliableSequenceNumber = 0; + + enet_list_clear (& channel -> incomingReliableCommands); + enet_list_clear (& channel -> incomingUnreliableCommands); + + channel -> usedReliableWindows = 0; + memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); + } + + mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu); + + if (mtu < ENET_PROTOCOL_MINIMUM_MTU) + mtu = ENET_PROTOCOL_MINIMUM_MTU; + else + if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) + mtu = ENET_PROTOCOL_MAXIMUM_MTU; + + peer -> mtu = mtu; + + if (host -> outgoingBandwidth == 0 && + peer -> incomingBandwidth == 0) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + if (host -> outgoingBandwidth == 0 || + peer -> incomingBandwidth == 0) + peer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, peer -> incomingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + peer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, peer -> incomingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + if (host -> incomingBandwidth == 0) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize)) + windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize); + + if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + verifyCommand.header.channelID = 0xFF; + verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (peer -> incomingPeerID); + verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; + verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; + verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (peer -> mtu); + verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); + verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); + verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); + verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (peer -> packetThrottleInterval); + verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleAcceleration); + verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleDeceleration); + verifyCommand.verifyConnect.connectID = peer -> connectID; + + enet_peer_queue_outgoing_command (peer, & verifyCommand, NULL, 0, 0); + + return peer; +} + +static int +enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +{ + ENetPacket * packet; + size_t dataLength; + + if (command -> header.channelID >= peer -> channelCount || + (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; + + dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength); + * currentData += dataLength; + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) + return -1; + + packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), + dataLength, + ENET_PACKET_FLAG_RELIABLE); + if (packet == NULL || + enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) + return -1; + + return 0; +} + +static int +enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +{ + ENetPacket * packet; + enet_uint32 unsequencedGroup, index; + size_t dataLength; + + if (command -> header.channelID >= peer -> channelCount || + (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; + + dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength); + * currentData += dataLength; + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) + return -1; + + unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); + index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; + + if (unsequencedGroup < peer -> incomingUnsequencedGroup) + unsequencedGroup += 0x10000; + + if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE) + return 0; + + unsequencedGroup &= 0xFFFF; + + if (unsequencedGroup - index != peer -> incomingUnsequencedGroup) + { + peer -> incomingUnsequencedGroup = unsequencedGroup - index; + + memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); + } + else + if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) + return 0; + + packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), + dataLength, + ENET_PACKET_FLAG_UNSEQUENCED); + if (packet == NULL || + enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) + return -1; + + peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); + + return 0; +} + +static int +enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +{ + ENetPacket * packet; + size_t dataLength; + + if (command -> header.channelID >= peer -> channelCount || + (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; + + dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength); + * currentData += dataLength; + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) + return -1; + + packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), + dataLength, + 0); + if (packet == NULL || + enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) + return -1; + + return 0; +} + +static int +enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +{ + enet_uint32 fragmentNumber, + fragmentCount, + fragmentOffset, + fragmentLength, + startSequenceNumber, + totalLength; + ENetChannel * channel; + enet_uint16 startWindow, currentWindow; + ENetListIterator currentCommand; + ENetIncomingCommand * startCommand = NULL; + + if (command -> header.channelID >= peer -> channelCount || + (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; + + fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); + * currentData += fragmentLength; + if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) + return -1; + + channel = & peer -> channels [command -> header.channelID]; + startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); + startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + + if (startSequenceNumber < channel -> incomingReliableSequenceNumber) + startWindow += ENET_PEER_RELIABLE_WINDOWS; + + if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + return 0; + + fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); + fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); + fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); + totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); + + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || + fragmentNumber >= fragmentCount || + totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) + return -1; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); + currentCommand != enet_list_end (& channel -> incomingReliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (startSequenceNumber >= channel -> incomingReliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < startSequenceNumber) + break; + + if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || + totalLength != incomingCommand -> packet -> dataLength || + fragmentCount != incomingCommand -> fragmentCount) + return -1; + + startCommand = incomingCommand; + break; + } + } + + if (startCommand == NULL) + { + ENetProtocol hostCommand = * command; + ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE); + if (packet == NULL) + return -1; + + hostCommand.header.reliableSequenceNumber = startSequenceNumber; + + startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount); + if (startCommand == NULL) + return -1; + } + + if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) + { + -- startCommand -> fragmentsRemaining; + + startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); + + if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) + fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; + + memcpy (startCommand -> packet -> data + fragmentOffset, + (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), + fragmentLength); + + if (startCommand -> fragmentsRemaining <= 0) + enet_peer_dispatch_incoming_reliable_commands (peer, channel); + } + + return 0; +} + +static int +enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +{ + enet_uint32 fragmentNumber, + fragmentCount, + fragmentOffset, + fragmentLength, + reliableSequenceNumber, + startSequenceNumber, + totalLength; + enet_uint16 reliableWindow, currentWindow; + ENetChannel * channel; + ENetListIterator currentCommand; + ENetIncomingCommand * startCommand = NULL; + + if (command -> header.channelID >= peer -> channelCount || + (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; + + fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); + * currentData += fragmentLength; + if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) + return -1; + + channel = & peer -> channels [command -> header.channelID]; + reliableSequenceNumber = command -> header.reliableSequenceNumber; + startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); + + reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + + if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + return 0; + + if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && + startSequenceNumber <= channel -> incomingUnreliableSequenceNumber) + return 0; + + fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); + fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); + fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); + totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); + + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || + fragmentNumber >= fragmentCount || + totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) + return -1; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); + currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber) + continue; + + if (incomingCommand -> unreliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand -> unreliableSequenceNumber < startSequenceNumber) + break; + + if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT || + totalLength != incomingCommand -> packet -> dataLength || + fragmentCount != incomingCommand -> fragmentCount) + return -1; + + startCommand = incomingCommand; + break; + } + } + + if (startCommand == NULL) + { + ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); + if (packet == NULL) + return -1; + + startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount); + if (startCommand == NULL) + return -1; + } + + if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) + { + -- startCommand -> fragmentsRemaining; + + startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); + + if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) + fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; + + memcpy (startCommand -> packet -> data + fragmentOffset, + (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), + fragmentLength); + + if (startCommand -> fragmentsRemaining <= 0) + enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + } + + return 0; +} + +static int +enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; + + return 0; +} + +static int +enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; + + if (peer -> incomingBandwidth != 0) + -- host -> bandwidthLimitedPeers; + + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); + peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); + + if (peer -> incomingBandwidth != 0) + ++ host -> bandwidthLimitedPeers; + + if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + return 0; +} + +static int +enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; + + peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); + peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); + peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); + + return 0; +} + +static int +enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) + return 0; + + enet_peer_reset_queues (peer); + + if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING) + enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + else + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + { + if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; + + enet_peer_reset (peer); + } + else + if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT); + else + enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + + if (peer -> state != ENET_PEER_STATE_DISCONNECTED) + peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data); + + return 0; +} + +static int +enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) +{ + enet_uint32 roundTripTime, + receivedSentTime, + receivedReliableSequenceNumber; + ENetProtocolCommand commandNumber; + + if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE) + return 0; + + receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime); + receivedSentTime |= host -> serviceTime & 0xFFFF0000; + if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000)) + receivedSentTime -= 0x10000; + + if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime)) + return 0; + + peer -> lastReceiveTime = host -> serviceTime; + peer -> earliestTimeout = 0; + + roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime); + + enet_peer_throttle (peer, roundTripTime); + + peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; + + if (roundTripTime >= peer -> roundTripTime) + { + peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8; + peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4; + } + else + { + peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8; + peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4; + } + + if (peer -> roundTripTime < peer -> lowestRoundTripTime) + peer -> lowestRoundTripTime = peer -> roundTripTime; + + if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) + peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; + + if (peer -> packetThrottleEpoch == 0 || + ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) + { + peer -> lastRoundTripTime = peer -> lowestRoundTripTime; + peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance; + peer -> lowestRoundTripTime = peer -> roundTripTime; + peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; + peer -> packetThrottleEpoch = host -> serviceTime; + } + + receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber); + + commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); + + switch (peer -> state) + { + case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: + if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) + return -1; + + enet_protocol_notify_connect (host, peer, event); + break; + + case ENET_PEER_STATE_DISCONNECTING: + if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) + return -1; + + enet_protocol_notify_disconnect (host, peer, event); + break; + + case ENET_PEER_STATE_DISCONNECT_LATER: + if (enet_list_empty (& peer -> outgoingReliableCommands) && + enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> sentReliableCommands)) + enet_peer_disconnect (peer, peer -> eventData); + break; + + default: + break; + } + + return 0; +} + +static int +enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) +{ + enet_uint32 mtu, windowSize; + size_t channelCount; + + if (peer -> state != ENET_PEER_STATE_CONNECTING) + return 0; + + channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount); + + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || + ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || + ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration || + ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration || + command -> verifyConnect.connectID != peer -> connectID) + { + peer -> eventData = 0; + + enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + + return -1; + } + + enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF); + + if (channelCount < peer -> channelCount) + peer -> channelCount = channelCount; + + peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); + peer -> incomingSessionID = command -> verifyConnect.incomingSessionID; + peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID; + + mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu); + + if (mtu < ENET_PROTOCOL_MINIMUM_MTU) + mtu = ENET_PROTOCOL_MINIMUM_MTU; + else + if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) + mtu = ENET_PROTOCOL_MAXIMUM_MTU; + + if (mtu < peer -> mtu) + peer -> mtu = mtu; + + windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize); + + if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + if (windowSize < peer -> windowSize) + peer -> windowSize = windowSize; + + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); + peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); + + enet_protocol_notify_connect (host, peer, event); + return 0; +} + +static int +enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) +{ + ENetProtocolHeader * header; + ENetProtocol * command; + ENetPeer * peer; + enet_uint8 * currentData; + size_t headerSize; + enet_uint16 peerID, flags; + enet_uint8 sessionID; + + if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime) + return 0; + + header = (ENetProtocolHeader *) host -> receivedData; + + peerID = ENET_NET_TO_HOST_16 (header -> peerID); + sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; + flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; + peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); + + headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime); + if (host -> checksum != NULL) + headerSize += sizeof (enet_uint32); + + if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) + peer = NULL; + else + if (peerID >= host -> peerCount) + return 0; + else + { + peer = & host -> peers [peerID]; + + if (peer -> state == ENET_PEER_STATE_DISCONNECTED || + peer -> state == ENET_PEER_STATE_ZOMBIE || + ((host -> receivedAddress.host != peer -> address.host || + host -> receivedAddress.port != peer -> address.port) && + peer -> address.host != ENET_HOST_BROADCAST) || + (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && + sessionID != peer -> incomingSessionID)) + return 0; + } + + if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) + { + size_t originalSize; + if (host -> compressor.context == NULL || host -> compressor.decompress == NULL) + return 0; + + originalSize = host -> compressor.decompress (host -> compressor.context, + host -> receivedData + headerSize, + host -> receivedDataLength - headerSize, + host -> packetData [1] + headerSize, + sizeof (host -> packetData [1]) - headerSize); + if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize) + return 0; + + memcpy (host -> packetData [1], header, headerSize); + host -> receivedData = host -> packetData [1]; + host -> receivedDataLength = headerSize + originalSize; + } + + if (host -> checksum != NULL) + { + enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)], + desiredChecksum = * checksum; + ENetBuffer buffer; + + * checksum = peer != NULL ? peer -> connectID : 0; + + buffer.data = host -> receivedData; + buffer.dataLength = host -> receivedDataLength; + + if (host -> checksum (& buffer, 1) != desiredChecksum) + return 0; + } + + if (peer != NULL) + { + peer -> address.host = host -> receivedAddress.host; + peer -> address.port = host -> receivedAddress.port; + peer -> incomingDataTotal += host -> receivedDataLength; + } + + currentData = host -> receivedData + headerSize; + + while (currentData < & host -> receivedData [host -> receivedDataLength]) + { + enet_uint8 commandNumber; + size_t commandSize; + + command = (ENetProtocol *) currentData; + + if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) + break; + + commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK; + if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) + break; + + commandSize = commandSizes [commandNumber]; + if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength]) + break; + + currentData += commandSize; + + if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) + break; + + command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); + + switch (commandNumber) + { + case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: + if (enet_protocol_handle_acknowledge (host, event, peer, command)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_CONNECT: + if (peer != NULL) + goto commandError; + peer = enet_protocol_handle_connect (host, header, command); + if (peer == NULL) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: + if (enet_protocol_handle_verify_connect (host, event, peer, command)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_DISCONNECT: + if (enet_protocol_handle_disconnect (host, peer, command)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_PING: + if (enet_protocol_handle_ping (host, peer, command)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + if (enet_protocol_handle_send_reliable (host, peer, command, & currentData)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + if (enet_protocol_handle_send_fragment (host, peer, command, & currentData)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: + if (enet_protocol_handle_bandwidth_limit (host, peer, command)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: + if (enet_protocol_handle_throttle_configure (host, peer, command)) + goto commandError; + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: + if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData)) + goto commandError; + break; + + default: + goto commandError; + } + + if (peer != NULL && + (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) + { + enet_uint16 sentTime; + + if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) + break; + + sentTime = ENET_NET_TO_HOST_16 (header -> sentTime); + + switch (peer -> state) + { + case ENET_PEER_STATE_DISCONNECTING: + case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: + case ENET_PEER_STATE_DISCONNECTED: + case ENET_PEER_STATE_ZOMBIE: + break; + + case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: + if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) + enet_peer_queue_acknowledgement (peer, command, sentTime); + break; + + default: + enet_peer_queue_acknowledgement (peer, command, sentTime); + break; + } + } + } + +commandError: + if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) + return 1; + + return 0; +} + +static int +enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) +{ + for (;;) + { + int receivedLength; + ENetBuffer buffer; + + buffer.data = host -> packetData [0]; + buffer.dataLength = sizeof (host -> packetData [0]); + + receivedLength = enet_socket_receive (host -> socket, + & host -> receivedAddress, + & buffer, + 1); + + if (receivedLength < 0) + return -1; + + if (receivedLength == 0) + return 0; + + host -> receivedData = host -> packetData [0]; + host -> receivedDataLength = receivedLength; + + host -> totalReceivedData += receivedLength; + host -> totalReceivedPackets ++; + + if (host -> intercept != NULL) + { + switch (host -> intercept (host, event)) + { + case 1: + if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) + return 1; + + continue; + + case -1: + return -1; + + default: + break; + } + } + + switch (enet_protocol_handle_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: + return -1; + + default: + break; + } + } + + return -1; +} + +static void +enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) +{ + ENetProtocol * command = & host -> commands [host -> commandCount]; + ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; + ENetAcknowledgement * acknowledgement; + ENetListIterator currentAcknowledgement; + enet_uint16 reliableSequenceNumber; + + currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); + + while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) + { + if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || + buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || + peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) + { + host -> continueSending = 1; + + break; + } + + acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; + + currentAcknowledgement = enet_list_next (currentAcknowledgement); + + buffer -> data = command; + buffer -> dataLength = sizeof (ENetProtocolAcknowledge); + + host -> packetSize += buffer -> dataLength; + + reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); + + command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; + command -> header.channelID = acknowledgement -> command.header.channelID; + command -> header.reliableSequenceNumber = reliableSequenceNumber; + command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; + command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); + + if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) + enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + + enet_list_remove (& acknowledgement -> acknowledgementList); + enet_free (acknowledgement); + + ++ command; + ++ buffer; + } + + host -> commandCount = command - host -> commands; + host -> bufferCount = buffer - host -> buffers; +} + +static void +enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +{ + ENetProtocol * command = & host -> commands [host -> commandCount]; + ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand; + + currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); + + while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) + { + size_t commandSize; + + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; + + if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || + buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || + peer -> mtu - host -> packetSize < commandSize || + (outgoingCommand -> packet != NULL && + peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength)) + { + host -> continueSending = 1; + + break; + } + + currentCommand = enet_list_next (currentCommand); + + if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0) + { + peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; + peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; + + if (peer -> packetThrottleCounter > peer -> packetThrottle) + { + enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, + unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; + for (;;) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + enet_free (outgoingCommand); + + if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands)) + break; + + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || + outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) + break; + + currentCommand = enet_list_next (currentCommand); + } + + continue; + } + } + + buffer -> data = command; + buffer -> dataLength = commandSize; + + host -> packetSize += buffer -> dataLength; + + * command = outgoingCommand -> command; + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + { + ++ buffer; + + buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; + buffer -> dataLength = outgoingCommand -> fragmentLength; + + host -> packetSize += buffer -> dataLength; + + enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); + } + else + enet_free (outgoingCommand); + + ++ command; + ++ buffer; + } + + host -> commandCount = command - host -> commands; + host -> bufferCount = buffer - host -> buffers; + + if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && + enet_list_empty (& peer -> outgoingReliableCommands) && + enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> sentReliableCommands)) + enet_peer_disconnect (peer, peer -> eventData); +} + +static int +enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) +{ + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand, insertPosition; + + currentCommand = enet_list_begin (& peer -> sentReliableCommands); + insertPosition = enet_list_begin (& peer -> outgoingReliableCommands); + + while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + currentCommand = enet_list_next (currentCommand); + + if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) + continue; + + if (peer -> earliestTimeout == 0 || + ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout)) + peer -> earliestTimeout = outgoingCommand -> sentTime; + + if (peer -> earliestTimeout != 0 && + (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum || + (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && + ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum))) + { + enet_protocol_notify_disconnect (host, peer, event); + + return 1; + } + + if (outgoingCommand -> packet != NULL) + peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; + + ++ peer -> packetsLost; + + outgoingCommand -> roundTripTimeout *= 2; + + enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); + + if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && + ! enet_list_empty (& peer -> sentReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; + } + } + + return 0; +} + +static int +enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +{ + ENetProtocol * command = & host -> commands [host -> commandCount]; + ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand; + ENetChannel *channel; + enet_uint16 reliableWindow; + size_t commandSize; + int windowExceeded = 0, windowWrap = 0, canPing = 1; + + currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); + + while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; + reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (channel != NULL) + { + if (! windowWrap && + outgoingCommand -> sendAttempts < 1 && + ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && + (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || + channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | + (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow))))) + windowWrap = 1; + if (windowWrap) + { + currentCommand = enet_list_next (currentCommand); + + continue; + } + } + + if (outgoingCommand -> packet != NULL) + { + if (! windowExceeded) + { + enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; + + if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) + windowExceeded = 1; + } + if (windowExceeded) + { + currentCommand = enet_list_next (currentCommand); + + continue; + } + } + + canPing = 0; + + commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; + if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || + buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || + peer -> mtu - host -> packetSize < commandSize || + (outgoingCommand -> packet != NULL && + (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))) + { + host -> continueSending = 1; + + break; + } + + currentCommand = enet_list_next (currentCommand); + + if (channel != NULL && outgoingCommand -> sendAttempts < 1) + { + channel -> usedReliableWindows |= 1 << reliableWindow; + ++ channel -> reliableWindows [reliableWindow]; + } + + ++ outgoingCommand -> sendAttempts; + + if (outgoingCommand -> roundTripTimeout == 0) + { + outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; + outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; + } + + if (enet_list_empty (& peer -> sentReliableCommands)) + peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; + + enet_list_insert (enet_list_end (& peer -> sentReliableCommands), + enet_list_remove (& outgoingCommand -> outgoingCommandList)); + + outgoingCommand -> sentTime = host -> serviceTime; + + buffer -> data = command; + buffer -> dataLength = commandSize; + + host -> packetSize += buffer -> dataLength; + host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; + + * command = outgoingCommand -> command; + + if (outgoingCommand -> packet != NULL) + { + ++ buffer; + + buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; + buffer -> dataLength = outgoingCommand -> fragmentLength; + + host -> packetSize += outgoingCommand -> fragmentLength; + + peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; + } + + ++ peer -> packetsSent; + + ++ command; + ++ buffer; + } + + host -> commandCount = command - host -> commands; + host -> bufferCount = buffer - host -> buffers; + + return canPing; +} + +static int +enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) +{ + enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; + ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; + ENetPeer * currentPeer; + int sentLength; + size_t shouldCompress = 0; + + host -> continueSending = 1; + + while (host -> continueSending) + for (host -> continueSending = 0, + currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || + currentPeer -> state == ENET_PEER_STATE_ZOMBIE) + continue; + + host -> headerFlags = 0; + host -> commandCount = 0; + host -> bufferCount = 1; + host -> packetSize = sizeof (ENetProtocolHeader); + + if (! enet_list_empty (& currentPeer -> acknowledgements)) + enet_protocol_send_acknowledgements (host, currentPeer); + + if (checkForTimeouts != 0 && + ! enet_list_empty (& currentPeer -> sentReliableCommands) && + ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) && + enet_protocol_check_timeouts (host, currentPeer, event) == 1) + { + if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) + return 1; + else + continue; + } + + if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) || + enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) && + enet_list_empty (& currentPeer -> sentReliableCommands) && + ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && + currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) + { + enet_peer_ping (currentPeer); + enet_protocol_send_reliable_outgoing_commands (host, currentPeer); + } + + if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands)) + enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); + + if (host -> commandCount == 0) + continue; + + if (currentPeer -> packetLossEpoch == 0) + currentPeer -> packetLossEpoch = host -> serviceTime; + else + if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && + currentPeer -> packetsSent > 0) + { + enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; + +#ifdef ENET_DEBUG + printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); +#endif + + currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; + + if (packetLoss >= currentPeer -> packetLoss) + { + currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8; + currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4; + } + else + { + currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8; + currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4; + } + + currentPeer -> packetLossEpoch = host -> serviceTime; + currentPeer -> packetsSent = 0; + currentPeer -> packetsLost = 0; + } + + host -> buffers -> data = headerData; + if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) + { + header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF); + + host -> buffers -> dataLength = sizeof (ENetProtocolHeader); + } + else + host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime; + + shouldCompress = 0; + if (host -> compressor.context != NULL && host -> compressor.compress != NULL) + { + size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader), + compressedSize = host -> compressor.compress (host -> compressor.context, + & host -> buffers [1], host -> bufferCount - 1, + originalSize, + host -> packetData [1], + originalSize); + if (compressedSize > 0 && compressedSize < originalSize) + { + host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; + shouldCompress = compressedSize; +#ifdef ENET_DEBUG_COMPRESS + printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); +#endif + } + } + + if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) + host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; + header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags); + if (host -> checksum != NULL) + { + enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength]; + * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0; + host -> buffers -> dataLength += sizeof (enet_uint32); + * checksum = host -> checksum (host -> buffers, host -> bufferCount); + } + + if (shouldCompress > 0) + { + host -> buffers [1].data = host -> packetData [1]; + host -> buffers [1].dataLength = shouldCompress; + host -> bufferCount = 2; + } + + currentPeer -> lastSendTime = host -> serviceTime; + + sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); + + enet_protocol_remove_sent_unreliable_commands (currentPeer); + + if (sentLength < 0) + return -1; + + host -> totalSentData += sentLength; + host -> totalSentPackets ++; + } + + return 0; +} + +/** Sends any queued packets on the host specified to its designated peers. + + @param host host to flush + @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service(). + @ingroup host +*/ +void +enet_host_flush (ENetHost * host) +{ + host -> serviceTime = enet_time_get (); + + enet_protocol_send_outgoing_commands (host, NULL, 0); +} + +/** Checks for any queued events on the host and dispatches one if available. + + @param host host to check for events + @param event an event structure where event details will be placed if available + @retval > 0 if an event was dispatched + @retval 0 if no events are available + @retval < 0 on failure + @ingroup host +*/ +int +enet_host_check_events (ENetHost * host, ENetEvent * event) +{ + if (event == NULL) return -1; + + event -> type = ENET_EVENT_TYPE_NONE; + event -> peer = NULL; + event -> packet = NULL; + + return enet_protocol_dispatch_incoming_commands (host, event); +} + +/** Waits for events on the host specified and shuttles packets between + the host and its peers. + + @param host host to service + @param event an event structure where event details will be placed if one occurs + if event == NULL then no events will be delivered + @param timeout number of milliseconds that ENet should wait for events + @retval > 0 if an event occurred within the specified time limit + @retval 0 if no event occurred + @retval < 0 on failure + @remarks enet_host_service should be called fairly regularly for adequate performance + @ingroup host +*/ +int +enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) +{ + enet_uint32 waitCondition; + + if (event != NULL) + { + event -> type = ENET_EVENT_TYPE_NONE; + event -> peer = NULL; + event -> packet = NULL; + + switch (enet_protocol_dispatch_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: +#ifdef ENET_DEBUG + perror ("Error dispatching incoming packets"); +#endif + + return -1; + + default: + break; + } + } + + host -> serviceTime = enet_time_get (); + + timeout += host -> serviceTime; + + do + { + if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) + enet_host_bandwidth_throttle (host); + + switch (enet_protocol_send_outgoing_commands (host, event, 1)) + { + case 1: + return 1; + + case -1: +#ifdef ENET_DEBUG + perror ("Error sending outgoing packets"); +#endif + + return -1; + + default: + break; + } + + switch (enet_protocol_receive_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: +#ifdef ENET_DEBUG + perror ("Error receiving incoming packets"); +#endif + + return -1; + + default: + break; + } + + switch (enet_protocol_send_outgoing_commands (host, event, 1)) + { + case 1: + return 1; + + case -1: +#ifdef ENET_DEBUG + perror ("Error sending outgoing packets"); +#endif + + return -1; + + default: + break; + } + + if (event != NULL) + { + switch (enet_protocol_dispatch_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: +#ifdef ENET_DEBUG + perror ("Error dispatching incoming packets"); +#endif + + return -1; + + default: + break; + } + } + + do + { + host -> serviceTime = enet_time_get (); + + if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) + return 0; + + waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT; + + if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) + return -1; + } + while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT); + + host -> serviceTime = enet_time_get (); + } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE); + + return 0; +} + diff --git a/src/libraries/enet/libenet/unix.c b/src/libraries/enet/libenet/unix.c new file mode 100644 index 000000000..111d8e661 --- /dev/null +++ b/src/libraries/enet/libenet/unix.c @@ -0,0 +1,548 @@ +/** + @file unix.c + @brief ENet Unix system specific functions +*/ +#ifndef _WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +#ifdef __APPLE__ +#ifdef HAS_POLL +#undef HAS_POLL +#endif +#ifndef HAS_FCNTL +#define HAS_FCNTL 1 +#endif +#ifndef HAS_INET_PTON +#define HAS_INET_PTON 1 +#endif +#ifndef HAS_INET_NTOP +#define HAS_INET_NTOP 1 +#endif +#ifndef HAS_MSGHDR_FLAGS +#define HAS_MSGHDR_FLAGS 1 +#endif +#ifndef HAS_SOCKLEN_T +#define HAS_SOCKLEN_T 1 +#endif +#endif + +#ifdef HAS_FCNTL +#include +#endif + +#ifdef HAS_POLL +#include +#endif + +#include "common/config.h" +#ifndef HAS_SOCKLEN_T +typedef int socklen_t; +#endif + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +static enet_uint32 timeBase = 0; + +int +enet_initialize (void) +{ + return 0; +} + +void +enet_deinitialize (void) +{ +} + +enet_uint32 +enet_host_random_seed (void) +{ + return (enet_uint32) time (NULL); +} + +enet_uint32 +enet_time_get (void) +{ + struct timeval timeVal; + + gettimeofday (& timeVal, NULL); + + return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase; +} + +void +enet_time_set (enet_uint32 newTimeBase) +{ + struct timeval timeVal; + + gettimeofday (& timeVal, NULL); + + timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; +} + +int +enet_address_set_host (ENetAddress * address, const char * name) +{ + struct hostent * hostEntry = NULL; +#ifdef HAS_GETHOSTBYNAME_R + struct hostent hostData; + char buffer [2048]; + int errnum; + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); +#else + hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum); +#endif +#else + hostEntry = gethostbyname (name); +#endif + + if (hostEntry == NULL || + hostEntry -> h_addrtype != AF_INET) + { +#ifdef HAS_INET_PTON + if (! inet_pton (AF_INET, name, & address -> host)) +#else + if (! inet_aton (name, (struct in_addr *) & address -> host)) +#endif + return -1; + return 0; + } + + address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; + + return 0; +} + +int +enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) +{ +#ifdef HAS_INET_NTOP + if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL) +#else + char * addr = inet_ntoa (* (struct in_addr *) & address -> host); + if (addr != NULL) + strncpy (name, addr, nameLength); + else +#endif + return -1; + return 0; +} + +int +enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) +{ + struct in_addr in; + struct hostent * hostEntry = NULL; +#ifdef HAS_GETHOSTBYADDR_R + struct hostent hostData; + char buffer [2048]; + int errnum; + + in.s_addr = address -> host; + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); +#else + hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum); +#endif +#else + in.s_addr = address -> host; + + hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); +#endif + + if (hostEntry == NULL) + return enet_address_get_host_ip (address, name, nameLength); + + strncpy (name, hostEntry -> h_name, nameLength); + + return 0; +} + +int +enet_socket_bind (ENetSocket socket, const ENetAddress * address) +{ + struct sockaddr_in sin; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + + if (address != NULL) + { + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + } + else + { + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; + } + + return bind (socket, + (struct sockaddr *) & sin, + sizeof (struct sockaddr_in)); +} + +int +enet_socket_get_address (ENetSocket socket, ENetAddress * address) +{ + struct sockaddr_in sin; + socklen_t sinLength = sizeof (struct sockaddr_in); + + if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1) + return -1; + + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + + return 0; +} + +int +enet_socket_listen (ENetSocket socket, int backlog) +{ + return listen (socket, backlog < 0 ? SOMAXCONN : backlog); +} + +ENetSocket +enet_socket_create (ENetSocketType type) +{ + return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); +} + +int +enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) +{ + int result = -1; + switch (option) + { + case ENET_SOCKOPT_NONBLOCK: +#ifdef HAS_FCNTL + result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL)); +#else + result = ioctl (socket, FIONBIO, & value); +#endif + break; + + case ENET_SOCKOPT_BROADCAST: + result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_REUSEADDR: + result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_RCVBUF: + result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_SNDBUF: + result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_RCVTIMEO: + { + struct timeval timeVal; + timeVal.tv_sec = value / 1000; + timeVal.tv_usec = (value % 1000) * 1000; + result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & timeVal, sizeof (struct timeval)); + break; + } + + case ENET_SOCKOPT_SNDTIMEO: + { + struct timeval timeVal; + timeVal.tv_sec = value / 1000; + timeVal.tv_usec = (value % 1000) * 1000; + result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval)); + break; + } + + case ENET_SOCKOPT_NODELAY: + result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int)); + break; + + default: + break; + } + return result == -1 ? -1 : 0; +} + +int +enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value) +{ + int result = -1; + socklen_t len; + switch (option) + { + case ENET_SOCKOPT_ERROR: + len = sizeof (int); + result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len); + break; + + default: + break; + } + return result == -1 ? -1 : 0; +} + +int +enet_socket_connect (ENetSocket socket, const ENetAddress * address) +{ + struct sockaddr_in sin; + int result; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); + if (result == -1 && errno == EINPROGRESS) + return 0; + + return result; +} + +ENetSocket +enet_socket_accept (ENetSocket socket, ENetAddress * address) +{ + int result; + struct sockaddr_in sin; + socklen_t sinLength = sizeof (struct sockaddr_in); + + result = accept (socket, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? & sinLength : NULL); + + if (result == -1) + return ENET_SOCKET_NULL; + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return result; +} + +int +enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how) +{ + return shutdown (socket, (int) how); +} + +void +enet_socket_destroy (ENetSocket socket) +{ + if (socket != -1) + close (socket); +} + +int +enet_socket_send (ENetSocket socket, + const ENetAddress * address, + const ENetBuffer * buffers, + size_t bufferCount) +{ + struct msghdr msgHdr; + struct sockaddr_in sin; + int sentLength; + + memset (& msgHdr, 0, sizeof (struct msghdr)); + + if (address != NULL) + { + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + msgHdr.msg_name = & sin; + msgHdr.msg_namelen = sizeof (struct sockaddr_in); + } + + msgHdr.msg_iov = (struct iovec *) buffers; + msgHdr.msg_iovlen = bufferCount; + + sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL); + + if (sentLength == -1) + { + if (errno == EWOULDBLOCK) + return 0; + + return -1; + } + + return sentLength; +} + +int +enet_socket_receive (ENetSocket socket, + ENetAddress * address, + ENetBuffer * buffers, + size_t bufferCount) +{ + struct msghdr msgHdr; + struct sockaddr_in sin; + int recvLength; + + memset (& msgHdr, 0, sizeof (struct msghdr)); + + if (address != NULL) + { + msgHdr.msg_name = & sin; + msgHdr.msg_namelen = sizeof (struct sockaddr_in); + } + + msgHdr.msg_iov = (struct iovec *) buffers; + msgHdr.msg_iovlen = bufferCount; + + recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL); + + if (recvLength == -1) + { + if (errno == EWOULDBLOCK) + return 0; + + return -1; + } + +#ifdef HAS_MSGHDR_FLAGS + if (msgHdr.msg_flags & MSG_TRUNC) + return -1; +#endif + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return recvLength; +} + +int +enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) +{ + struct timeval timeVal; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); +} + +int +enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) +{ +#ifdef HAS_POLL + struct pollfd pollSocket; + int pollCount; + + pollSocket.fd = socket; + pollSocket.events = 0; + + if (* condition & ENET_SOCKET_WAIT_SEND) + pollSocket.events |= POLLOUT; + + if (* condition & ENET_SOCKET_WAIT_RECEIVE) + pollSocket.events |= POLLIN; + + pollCount = poll (& pollSocket, 1, timeout); + + if (pollCount < 0) + { + if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT) + { + * condition = ENET_SOCKET_WAIT_INTERRUPT; + + return 0; + } + + return -1; + } + + * condition = ENET_SOCKET_WAIT_NONE; + + if (pollCount == 0) + return 0; + + if (pollSocket.revents & POLLOUT) + * condition |= ENET_SOCKET_WAIT_SEND; + + if (pollSocket.revents & POLLIN) + * condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +#else + fd_set readSet, writeSet; + struct timeval timeVal; + int selectCount; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO (& readSet); + FD_ZERO (& writeSet); + + if (* condition & ENET_SOCKET_WAIT_SEND) + FD_SET (socket, & writeSet); + + if (* condition & ENET_SOCKET_WAIT_RECEIVE) + FD_SET (socket, & readSet); + + selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); + + if (selectCount < 0) + { + if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT) + { + * condition = ENET_SOCKET_WAIT_INTERRUPT; + + return 0; + } + + return -1; + } + + * condition = ENET_SOCKET_WAIT_NONE; + + if (selectCount == 0) + return 0; + + if (FD_ISSET (socket, & writeSet)) + * condition |= ENET_SOCKET_WAIT_SEND; + + if (FD_ISSET (socket, & readSet)) + * condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +#endif +} + +#endif + diff --git a/src/libraries/enet/libenet/win32.c b/src/libraries/enet/libenet/win32.c new file mode 100644 index 000000000..c441841d4 --- /dev/null +++ b/src/libraries/enet/libenet/win32.c @@ -0,0 +1,410 @@ +/** + @file win32.c + @brief ENet Win32 system specific functions +*/ +#ifdef _WIN32 + +#include +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +static enet_uint32 timeBase = 0; + +int +enet_initialize (void) +{ + WORD versionRequested = MAKEWORD (1, 1); + WSADATA wsaData; + + if (WSAStartup (versionRequested, & wsaData)) + return -1; + + if (LOBYTE (wsaData.wVersion) != 1|| + HIBYTE (wsaData.wVersion) != 1) + { + WSACleanup (); + + return -1; + } + + timeBeginPeriod (1); + + return 0; +} + +void +enet_deinitialize (void) +{ + timeEndPeriod (1); + + WSACleanup (); +} + +enet_uint32 +enet_host_random_seed (void) +{ + return (enet_uint32) timeGetTime (); +} + +enet_uint32 +enet_time_get (void) +{ + return (enet_uint32) timeGetTime () - timeBase; +} + +void +enet_time_set (enet_uint32 newTimeBase) +{ + timeBase = (enet_uint32) timeGetTime () - newTimeBase; +} + +int +enet_address_set_host (ENetAddress * address, const char * name) +{ + struct hostent * hostEntry; + + hostEntry = gethostbyname (name); + if (hostEntry == NULL || + hostEntry -> h_addrtype != AF_INET) + { + unsigned long host = inet_addr (name); + if (host == INADDR_NONE) + return -1; + address -> host = host; + return 0; + } + + address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; + + return 0; +} + +int +enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) +{ + char * addr = inet_ntoa (* (struct in_addr *) & address -> host); + if (addr == NULL) + return -1; + strncpy (name, addr, nameLength); + return 0; +} + +int +enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) +{ + struct in_addr in; + struct hostent * hostEntry; + + in.s_addr = address -> host; + + hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); + if (hostEntry == NULL) + return enet_address_get_host_ip (address, name, nameLength); + + strncpy (name, hostEntry -> h_name, nameLength); + + return 0; +} + +int +enet_socket_bind (ENetSocket socket, const ENetAddress * address) +{ + struct sockaddr_in sin; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + + if (address != NULL) + { + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + } + else + { + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; + } + + return bind (socket, + (struct sockaddr *) & sin, + sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; +} + +int +enet_socket_get_address (ENetSocket socket, ENetAddress * address) +{ + struct sockaddr_in sin; + int sinLength = sizeof (struct sockaddr_in); + + if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1) + return -1; + + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + + return 0; +} + +int +enet_socket_listen (ENetSocket socket, int backlog) +{ + return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0; +} + +ENetSocket +enet_socket_create (ENetSocketType type) +{ + return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); +} + +int +enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) +{ + int result = SOCKET_ERROR; + switch (option) + { + case ENET_SOCKOPT_NONBLOCK: + { + u_long nonBlocking = (u_long) value; + result = ioctlsocket (socket, FIONBIO, & nonBlocking); + break; + } + + case ENET_SOCKOPT_BROADCAST: + result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_REUSEADDR: + result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_RCVBUF: + result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_SNDBUF: + result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_RCVTIMEO: + result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_SNDTIMEO: + result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_NODELAY: + result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int)); + break; + + default: + break; + } + return result == SOCKET_ERROR ? -1 : 0; +} + +int +enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value) +{ + int result = SOCKET_ERROR, len; + switch (option) + { + case ENET_SOCKOPT_ERROR: + len = sizeof(int); + result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len); + break; + + default: + break; + } + return result == SOCKET_ERROR ? -1 : 0; +} + +int +enet_socket_connect (ENetSocket socket, const ENetAddress * address) +{ + struct sockaddr_in sin; + int result; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); + if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK) + return -1; + + return 0; +} + +ENetSocket +enet_socket_accept (ENetSocket socket, ENetAddress * address) +{ + SOCKET result; + struct sockaddr_in sin; + int sinLength = sizeof (struct sockaddr_in); + + result = accept (socket, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? & sinLength : NULL); + + if (result == INVALID_SOCKET) + return ENET_SOCKET_NULL; + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return result; +} + +int +enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how) +{ + return shutdown (socket, (int) how) == SOCKET_ERROR ? -1 : 0; +} + +void +enet_socket_destroy (ENetSocket socket) +{ + if (socket != INVALID_SOCKET) + closesocket (socket); +} + +int +enet_socket_send (ENetSocket socket, + const ENetAddress * address, + const ENetBuffer * buffers, + size_t bufferCount) +{ + struct sockaddr_in sin; + DWORD sentLength; + + if (address != NULL) + { + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + } + + if (WSASendTo (socket, + (LPWSABUF) buffers, + (DWORD) bufferCount, + & sentLength, + 0, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? sizeof (struct sockaddr_in) : 0, + NULL, + NULL) == SOCKET_ERROR) + { + if (WSAGetLastError () == WSAEWOULDBLOCK) + return 0; + + return -1; + } + + return (int) sentLength; +} + +int +enet_socket_receive (ENetSocket socket, + ENetAddress * address, + ENetBuffer * buffers, + size_t bufferCount) +{ + INT sinLength = sizeof (struct sockaddr_in); + DWORD flags = 0, + recvLength; + struct sockaddr_in sin; + + if (WSARecvFrom (socket, + (LPWSABUF) buffers, + (DWORD) bufferCount, + & recvLength, + & flags, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? & sinLength : NULL, + NULL, + NULL) == SOCKET_ERROR) + { + switch (WSAGetLastError ()) + { + case WSAEWOULDBLOCK: + case WSAECONNRESET: + return 0; + } + + return -1; + } + + if (flags & MSG_PARTIAL) + return -1; + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return (int) recvLength; +} + +int +enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) +{ + struct timeval timeVal; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); +} + +int +enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) +{ + fd_set readSet, writeSet; + struct timeval timeVal; + int selectCount; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO (& readSet); + FD_ZERO (& writeSet); + + if (* condition & ENET_SOCKET_WAIT_SEND) + FD_SET (socket, & writeSet); + + if (* condition & ENET_SOCKET_WAIT_RECEIVE) + FD_SET (socket, & readSet); + + selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); + + if (selectCount < 0) + return -1; + + * condition = ENET_SOCKET_WAIT_NONE; + + if (selectCount == 0) + return 0; + + if (FD_ISSET (socket, & writeSet)) + * condition |= ENET_SOCKET_WAIT_SEND; + + if (FD_ISSET (socket, & readSet)) + * condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +} + +#endif + diff --git a/src/libraries/enet/lua-enet.h b/src/libraries/enet/lua-enet.h new file mode 100644 index 000000000..e42fcf0fe --- /dev/null +++ b/src/libraries/enet/lua-enet.h @@ -0,0 +1,26 @@ +/** +* Copyright (c) 2006-2014 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. +**/ + +#ifndef LOVE_LUAENET_LUAENET_H +#define LOVE_LUAENET_LUAENET_H + +int luaopen_enet(lua_State * L); + +#endif // LOVE_LUAENET_LUAENET_H diff --git a/src/libraries/luasocket/libluasocket/lua.h b/src/libraries/luasocket/libluasocket/lua.h new file mode 100644 index 000000000..e97bc2ac2 --- /dev/null +++ b/src/libraries/luasocket/libluasocket/lua.h @@ -0,0 +1,12 @@ +#define LUA_COMPAT_ALL +#include +#include +#include + +#if LUA_VERSION_NUM > 501 +# define luaL_reg luaL_Reg +# define luaL_putchar(B, c) luaL_addchar(B, c) +# define luaL_typerror(L, n, t) luax_typerror(L, n, t) + +extern int luax_typerror(lua_State *L, int narg, const char *type); +#endif diff --git a/src/libraries/luasocket/libluasocket/luasocket.c b/src/libraries/luasocket/libluasocket/luasocket.c index 798a3116d..0d10bb1de 100644 --- a/src/libraries/luasocket/libluasocket/luasocket.c +++ b/src/libraries/luasocket/libluasocket/luasocket.c @@ -110,7 +110,7 @@ static int base_open(lua_State *L) { /*-------------------------------------------------------------------------*\ * Initializes all library modules. \*-------------------------------------------------------------------------*/ -LUASOCKET_API luaopen_socket_core(lua_State *L) { +int LUASOCKET_API luaopen_socket_core(lua_State *L) { int i; base_open(L); for (i = 0; mod[i].name; i++) mod[i].func(L); diff --git a/src/libraries/luasocket/luasocket.cpp b/src/libraries/luasocket/luasocket.cpp index 13af3eaec..b7a5cb211 100644 --- a/src/libraries/luasocket/luasocket.cpp +++ b/src/libraries/luasocket/luasocket.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,82 +39,83 @@ namespace love { namespace luasocket { - int __open(lua_State * L) - { - // Preload code from LuaSocket. - PRELOAD("socket.core", luaopen_socket_core); - PRELOAD("mime.core", luaopen_mime_core); +int __open(lua_State * L) +{ - PRELOAD("socket", __open_luasocket_socket); - PRELOAD("socket.ftp", __open_luasocket_ftp) - PRELOAD("socket.http", __open_luasocket_http); - PRELOAD("ltn12", __open_luasocket_ltn12); - PRELOAD("mime", __open_luasocket_mime) - PRELOAD("socket.smtp", __open_luasocket_smtp); - PRELOAD("socket.tp", __open_luasocket_tp) - PRELOAD("socket.url", __open_luasocket_url) + // Preload code from LuaSocket. + PRELOAD("socket.core", luaopen_socket_core); + PRELOAD("mime.core", luaopen_mime_core); - // No need to register garbage collector function. + PRELOAD("socket", __open_luasocket_socket); + PRELOAD("socket.ftp", __open_luasocket_ftp) + PRELOAD("socket.http", __open_luasocket_http); + PRELOAD("ltn12", __open_luasocket_ltn12); + PRELOAD("mime", __open_luasocket_mime) + PRELOAD("socket.smtp", __open_luasocket_smtp); + PRELOAD("socket.tp", __open_luasocket_tp) + PRELOAD("socket.url", __open_luasocket_url) - return 0; - } + // No need to register garbage collector function. - int __open_luasocket_socket(lua_State * L) - { - #include "libluasocket/socket.lua.h" - lua_getglobal(L, "socket"); - return 1; - } + return 0; +} - int __open_luasocket_ftp(lua_State * L) - { - #include "libluasocket/ftp.lua.h" - lua_getglobal(L, "socket.ftp"); - return 1; - } +int __open_luasocket_socket(lua_State * L) +{ + #include "libluasocket/socket.lua.h" + lua_getglobal(L, "socket"); + return 1; +} - int __open_luasocket_http(lua_State * L) - { - #include "libluasocket/http.lua.h" - lua_getglobal(L, "socket.http"); - return 1; - } +int __open_luasocket_ftp(lua_State * L) +{ + #include "libluasocket/ftp.lua.h" + lua_getglobal(L, "socket.ftp"); + return 1; +} - int __open_luasocket_ltn12(lua_State * L) - { - #include "libluasocket/ltn12.lua.h" - lua_getglobal(L, "ltn12"); - return 1; - } +int __open_luasocket_http(lua_State * L) +{ + #include "libluasocket/http.lua.h" + lua_getglobal(L, "socket.http"); + return 1; +} - int __open_luasocket_mime(lua_State * L) - { - #include "libluasocket/mime.lua.h" - lua_getglobal(L, "mime"); - return 1; - } +int __open_luasocket_ltn12(lua_State * L) +{ + #include "libluasocket/ltn12.lua.h" + lua_getglobal(L, "ltn12"); + return 1; +} - int __open_luasocket_smtp(lua_State * L) - { - #include "libluasocket/smtp.lua.h" - lua_getglobal(L, "socket.smtp"); - return 1; - } +int __open_luasocket_mime(lua_State * L) +{ + #include "libluasocket/mime.lua.h" + lua_getglobal(L, "mime"); + return 1; +} - int __open_luasocket_tp(lua_State * L) - { - #include "libluasocket/tp.lua.h" - lua_getglobal(L, "socket.tp"); - return 1; - } +int __open_luasocket_smtp(lua_State * L) +{ + #include "libluasocket/smtp.lua.h" + lua_getglobal(L, "socket.smtp"); + return 1; +} - int __open_luasocket_url(lua_State * L) - { - #include "libluasocket/url.lua.h" - lua_getglobal(L, "socket.url"); - return 1; - } +int __open_luasocket_tp(lua_State * L) +{ + #include "libluasocket/tp.lua.h" + lua_getglobal(L, "socket.tp"); + return 1; +} + +int __open_luasocket_url(lua_State * L) +{ + #include "libluasocket/url.lua.h" + lua_getglobal(L, "socket.url"); + return 1; +} } // luasocket } // love diff --git a/src/libraries/luasocket/luasocket.h b/src/libraries/luasocket/luasocket.h index d0319e105..804061e62 100644 --- a/src/libraries/luasocket/luasocket.h +++ b/src/libraries/luasocket/luasocket.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -28,19 +28,20 @@ namespace love { namespace luasocket { - int __open(lua_State * L); - // Loaders for all lua files. We want to be able - // to load these dynamically. (Identical in the LuaSocket - // documentation. These functions wrap the parsing of code, etc). - int __open_luasocket_socket(lua_State * L); - int __open_luasocket_ftp(lua_State * L); - int __open_luasocket_http(lua_State * L); - int __open_luasocket_ltn12(lua_State * L); - int __open_luasocket_mime(lua_State * L); - int __open_luasocket_smtp(lua_State * L); - int __open_luasocket_tp(lua_State * L); - int __open_luasocket_url(lua_State * L); +int __open(lua_State * L); + +// Loaders for all lua files. We want to be able +// to load these dynamically. (Identical in the LuaSocket +// documentation. These functions wrap the parsing of code, etc). +int __open_luasocket_socket(lua_State * L); +int __open_luasocket_ftp(lua_State * L); +int __open_luasocket_http(lua_State * L); +int __open_luasocket_ltn12(lua_State * L); +int __open_luasocket_mime(lua_State * L); +int __open_luasocket_smtp(lua_State * L); +int __open_luasocket_tp(lua_State * L); +int __open_luasocket_url(lua_State * L); } // luasocket } // love diff --git a/src/libraries/noise1234/simplexnoise1234.cpp b/src/libraries/noise1234/simplexnoise1234.cpp new file mode 100644 index 000000000..d5d24bfaa --- /dev/null +++ b/src/libraries/noise1234/simplexnoise1234.cpp @@ -0,0 +1,470 @@ +// SimplexNoise1234 +// Copyright © 2003-2011, Stefan Gustavson +// +// Contact: stegu@itn.liu.se +// +// This library is public domain software, released by the author +// into the public domain in February 2011. You may do anything +// you like with it. You may even remove all attributions, +// but of course I'd appreciate it if you kept my name somewhere. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +/** \file + \brief Implements the SimplexNoise1234 class for producing Perlin simplex noise. + \author Stefan Gustavson (stegu@itn.liu.se) +*/ + +/* + * This implementation is "Simplex Noise" as presented by + * Ken Perlin at a relatively obscure and not often cited course + * session "Real-Time Shading" at Siggraph 2001 (before real + * time shading actually took on), under the title "hardware noise". + * The 3D function is numerically equivalent to his Java reference + * code available in the PDF course notes, although I re-implemented + * it from scratch to get more readable code. The 1D, 2D and 4D cases + * were implemented from scratch by me from Ken Perlin's text. + * + * This is a highly reusable class. It has no dependencies + * on any other file, apart from its own header file. + */ + + +#include "simplexnoise1234.h" + +#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) ) + +//--------------------------------------------------------------------- +// Static data + +/* + * Permutation table. This is just a random jumble of all numbers 0-255, + * repeated twice to avoid wrapping the index at 255 for each lookup. + * This needs to be exactly the same for all instances on all platforms, + * so it's easiest to just keep it as static explicit data. + * This also removes the need for any initialisation of this class. + * + * Note that making this an int[] instead of a char[] might make the + * code run faster on platforms with a high penalty for unaligned single + * byte addressing. Intel x86 is generally single-byte-friendly, but + * some other CPUs are faster with 4-aligned reads. + * However, a char[] is smaller, which avoids cache trashing, and that + * is probably the most important aspect on most architectures. + * This array is accessed a *lot* by the noise functions. + * A vector-valued noise over 3D accesses it 96 times, and a + * float-valued 4D noise 64 times. We want this to fit in the cache! + */ +unsigned char SimplexNoise1234::perm[512] = {151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 +}; + +//--------------------------------------------------------------------- + +/* + * Helper functions to compute gradients-dot-residualvectors (1D to 4D) + * Note that these generate gradients of more than unit length. To make + * a close match with the value range of classic Perlin noise, the final + * noise values need to be rescaled to fit nicely within [-1,1]. + * (The simplex noise functions as such also have different scaling.) + * Note also that these noise functions are the most practical and useful + * signed version of Perlin noise. To return values according to the + * RenderMan specification from the SL noise() and pnoise() functions, + * the noise values need to be scaled and offset to [0,1], like this: + * float SLnoise = (SimplexNoise1234::noise(x,y,z) + 1.0) * 0.5; + */ + +float SimplexNoise1234::grad( int hash, float x ) { + int h = hash & 15; + float grad = 1.0f + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0 + if (h&8) grad = -grad; // Set a random sign for the gradient + return ( grad * x ); // Multiply the gradient with the distance +} + +float SimplexNoise1234::grad( int hash, float x, float y ) { + int h = hash & 7; // Convert low 3 bits of hash code + float u = h<4 ? x : y; // into 8 simple gradient directions, + float v = h<4 ? y : x; // and compute the dot product with (x,y). + return ((h&1)? -u : u) + ((h&2)? -2.0f*v : 2.0f*v); +} + +float SimplexNoise1234::grad( int hash, float x, float y , float z ) { + int h = hash & 15; // Convert low 4 bits of hash code into 12 simple + float u = h<8 ? x : y; // gradient directions, and compute dot product. + float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15 + return ((h&1)? -u : u) + ((h&2)? -v : v); +} + +float SimplexNoise1234::grad( int hash, float x, float y, float z, float t ) { + int h = hash & 31; // Convert low 5 bits of hash code into 32 simple + float u = h<24 ? x : y; // gradient directions, and compute dot product. + float v = h<16 ? y : z; + float w = h<8 ? z : t; + return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w); +} + + // A lookup table to traverse the simplex around a given point in 4D. + // Details can be found where this table is used, in the 4D noise method. + /* TODO: This should not be required, backport it from Bill's GLSL code! */ + static unsigned char simplex[64][4] = { + {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, + {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, + {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, + {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0}}; + +// 1D simplex noise +float SimplexNoise1234::noise(float x) { + + int i0 = FASTFLOOR(x); + int i1 = i0 + 1; + float x0 = x - i0; + float x1 = x0 - 1.0f; + + float n0, n1; + + float t0 = 1.0f - x0*x0; +// if(t0 < 0.0f) t0 = 0.0f; + t0 *= t0; + n0 = t0 * t0 * grad(perm[i0 & 0xff], x0); + + float t1 = 1.0f - x1*x1; +// if(t1 < 0.0f) t1 = 0.0f; + t1 *= t1; + n1 = t1 * t1 * grad(perm[i1 & 0xff], x1); + // The maximum value of this noise is 8*(3/4)^4 = 2.53125 + // A factor of 0.395 will scale to fit exactly within [-1,1] + return 0.395f * (n0 + n1); + +} + +// 2D simplex noise +float SimplexNoise1234::noise(float x, float y) { + +#define F2 0.366025403 // F2 = 0.5*(sqrt(3.0)-1.0) +#define G2 0.211324865 // G2 = (3.0-Math.sqrt(3.0))/6.0 + + float n0, n1, n2; // Noise contributions from the three corners + + // Skew the input space to determine which simplex cell we're in + float s = (x+y)*F2; // Hairy factor for 2D + float xs = x + s; + float ys = y + s; + int i = FASTFLOOR(xs); + int j = FASTFLOOR(ys); + + float t = (float)(i+j)*G2; + float X0 = i-t; // Unskew the cell origin back to (x,y) space + float Y0 = j-t; + float x0 = x-X0; // The x,y distances from the cell origin + float y0 = y-Y0; + + // For the 2D case, the simplex shape is an equilateral triangle. + // Determine which simplex we are in. + int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords + if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) + else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) + + // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and + // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where + // c = (3-sqrt(3))/6 + + float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + float y1 = y0 - j1 + G2; + float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords + float y2 = y0 - 1.0f + 2.0f * G2; + + // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds + int ii = i & 0xff; + int jj = j & 0xff; + + // Calculate the contribution from the three corners + float t0 = 0.5f - x0*x0-y0*y0; + if(t0 < 0.0f) n0 = 0.0f; + else { + t0 *= t0; + n0 = t0 * t0 * grad(perm[ii+perm[jj]], x0, y0); + } + + float t1 = 0.5f - x1*x1-y1*y1; + if(t1 < 0.0f) n1 = 0.0f; + else { + t1 *= t1; + n1 = t1 * t1 * grad(perm[ii+i1+perm[jj+j1]], x1, y1); + } + + float t2 = 0.5f - x2*x2-y2*y2; + if(t2 < 0.0f) n2 = 0.0f; + else { + t2 *= t2; + n2 = t2 * t2 * grad(perm[ii+1+perm[jj+1]], x2, y2); + } + + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. + return 45.23f * (n0 + n1 + n2); // TODO: The scale factor is preliminary! + } + +// 3D simplex noise +float SimplexNoise1234::noise(float x, float y, float z) { + +// Simple skewing factors for the 3D case +#define F3 0.333333333 +#define G3 0.166666667 + + float n0, n1, n2, n3; // Noise contributions from the four corners + + // Skew the input space to determine which simplex cell we're in + float s = (x+y+z)*F3; // Very nice and simple skew factor for 3D + float xs = x+s; + float ys = y+s; + float zs = z+s; + int i = FASTFLOOR(xs); + int j = FASTFLOOR(ys); + int k = FASTFLOOR(zs); + + float t = (float)(i+j+k)*G3; + float X0 = i-t; // Unskew the cell origin back to (x,y,z) space + float Y0 = j-t; + float Z0 = k-t; + float x0 = x-X0; // The x,y,z distances from the cell origin + float y0 = y-Y0; + float z0 = z-Z0; + + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + // Determine which simplex we are in. + int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords + int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords + +/* This code would benefit from a backport from the GLSL version! */ + if(x0>=y0) { + if(y0>=z0) + { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order + else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order + else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order + } + else { // x0 y0) ? 32 : 0; + int c2 = (x0 > z0) ? 16 : 0; + int c3 = (y0 > z0) ? 8 : 0; + int c4 = (x0 > w0) ? 4 : 0; + int c5 = (y0 > w0) ? 2 : 0; + int c6 = (z0 > w0) ? 1 : 0; + int c = c1 + c2 + c3 + c4 + c5 + c6; + + int i1, j1, k1, l1; // The integer offsets for the second simplex corner + int i2, j2, k2, l2; // The integer offsets for the third simplex corner + int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner + + // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. + // Many values of c will never occur, since e.g. x>y>z>w makes x=3 ? 1 : 0; + j1 = simplex[c][1]>=3 ? 1 : 0; + k1 = simplex[c][2]>=3 ? 1 : 0; + l1 = simplex[c][3]>=3 ? 1 : 0; + // The number 2 in the "simplex" array is at the second largest coordinate. + i2 = simplex[c][0]>=2 ? 1 : 0; + j2 = simplex[c][1]>=2 ? 1 : 0; + k2 = simplex[c][2]>=2 ? 1 : 0; + l2 = simplex[c][3]>=2 ? 1 : 0; + // The number 1 in the "simplex" array is at the second smallest coordinate. + i3 = simplex[c][0]>=1 ? 1 : 0; + j3 = simplex[c][1]>=1 ? 1 : 0; + k3 = simplex[c][2]>=1 ? 1 : 0; + l3 = simplex[c][3]>=1 ? 1 : 0; + // The fifth corner has all coordinate offsets = 1, so no need to look that up. + + float x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords + float y1 = y0 - j1 + G4; + float z1 = z0 - k1 + G4; + float w1 = w0 - l1 + G4; + float x2 = x0 - i2 + 2.0f*G4; // Offsets for third corner in (x,y,z,w) coords + float y2 = y0 - j2 + 2.0f*G4; + float z2 = z0 - k2 + 2.0f*G4; + float w2 = w0 - l2 + 2.0f*G4; + float x3 = x0 - i3 + 3.0f*G4; // Offsets for fourth corner in (x,y,z,w) coords + float y3 = y0 - j3 + 3.0f*G4; + float z3 = z0 - k3 + 3.0f*G4; + float w3 = w0 - l3 + 3.0f*G4; + float x4 = x0 - 1.0f + 4.0f*G4; // Offsets for last corner in (x,y,z,w) coords + float y4 = y0 - 1.0f + 4.0f*G4; + float z4 = z0 - 1.0f + 4.0f*G4; + float w4 = w0 - 1.0f + 4.0f*G4; + + // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds + int ii = i & 0xff; + int jj = j & 0xff; + int kk = k & 0xff; + int ll = l & 0xff; + + // Calculate the contribution from the five corners + float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0 - w0*w0; + if(t0 < 0.0f) n0 = 0.0f; + else { + t0 *= t0; + n0 = t0 * t0 * grad(perm[ii+perm[jj+perm[kk+perm[ll]]]], x0, y0, z0, w0); + } + + float t1 = 0.6f - x1*x1 - y1*y1 - z1*z1 - w1*w1; + if(t1 < 0.0f) n1 = 0.0f; + else { + t1 *= t1; + n1 = t1 * t1 * grad(perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]], x1, y1, z1, w1); + } + + float t2 = 0.6f - x2*x2 - y2*y2 - z2*z2 - w2*w2; + if(t2 < 0.0f) n2 = 0.0f; + else { + t2 *= t2; + n2 = t2 * t2 * grad(perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]], x2, y2, z2, w2); + } + + float t3 = 0.6f - x3*x3 - y3*y3 - z3*z3 - w3*w3; + if(t3 < 0.0f) n3 = 0.0f; + else { + t3 *= t3; + n3 = t3 * t3 * grad(perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]], x3, y3, z3, w3); + } + + float t4 = 0.6f - x4*x4 - y4*y4 - z4*z4 - w4*w4; + if(t4 < 0.0f) n4 = 0.0f; + else { + t4 *= t4; + n4 = t4 * t4 * grad(perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]], x4, y4, z4, w4); + } + + // Sum up and scale the result to cover the range [-1,1] + return 27.3f * (n0 + n1 + n2 + n3 + n4); // TODO: The scale factor is preliminary! + } +//--------------------------------------------------------------------- diff --git a/src/libraries/noise1234/simplexnoise1234.h b/src/libraries/noise1234/simplexnoise1234.h new file mode 100644 index 000000000..1f74226c0 --- /dev/null +++ b/src/libraries/noise1234/simplexnoise1234.h @@ -0,0 +1,60 @@ +// SimplexNoise1234 +// Copyright � 2003-2011, Stefan Gustavson +// +// Contact: stegu@itn.liu.se +// +// This library is public domain software, released by the author +// into the public domain in February 2011. You may do anything +// you like with it. You may even remove all attributions, +// but of course I'd appreciate it if you kept my name somewhere. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +/** \file + \brief Declares the SimplexNoise1234 class for producing Perlin simplex noise. + \author Stefan Gustavson (stegu@itn.liu.se) +*/ + +/* + * This is a clean, fast, modern and free Perlin Simplex noise class in C++. + * Being a stand-alone class with no external dependencies, it is + * highly reusable without source code modifications. + * + * + * Note: + * Replacing the "float" type with "double" can actually make this run faster + * on some platforms. A templatized version of SimplexNoise1234 could be useful. + */ + +class SimplexNoise1234 { + + public: + SimplexNoise1234() {} + ~SimplexNoise1234() {} + +/** 1D, 2D, 3D and 4D float Perlin noise + */ + static float noise( float x ); + static float noise( float x, float y ); + static float noise( float x, float y, float z ); + static float noise( float x, float y, float z, float w ); + +/** 1D, 2D, 3D and 4D float Perlin noise, with a specified integer period + */ + static float pnoise( float x, int px ); + static float pnoise( float x, float y, int px, int py ); + static float pnoise( float x, float y, float z, int px, int py, int pz ); + static float pnoise( float x, float y, float z, float w, + int px, int py, int pz, int pw ); + + private: + static unsigned char perm[]; + static float grad( int hash, float x ); + static float grad( int hash, float x, float y ); + static float grad( int hash, float x, float y , float z ); + static float grad( int hash, float x, float y, float z, float t ); + +}; diff --git a/src/love.cpp b/src/love.cpp index 200a5db9d..0d7b5bc57 100644 --- a/src/love.cpp +++ b/src/love.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -34,6 +34,10 @@ extern "C" { #include #endif // LOVE_WINDOWS +#ifdef LOVE_MACOSX +#include "OSX.h" +#endif // LOVE_MACOSX + #ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK void get_utf8_arguments(int &argc, char **&argv) @@ -71,48 +75,53 @@ void get_utf8_arguments(int &argc, char **&argv) #endif // LOVE_LEGENDARY_UTF8_ARGV_HACK -#ifdef LOVE_LEGENDARY_LIBSTDCXX_HACK +#ifdef LOVE_LEGENDARY_APP_ARGV_HACK -#include +#include -// Workarounds for symbols that are missing from Leopard stdlibc++.dylib. -// http://stackoverflow.com/questions/3484043/os-x-program-runs-on-dev-machine-crashing-horribly-on-others -_GLIBCXX_BEGIN_NAMESPACE(std) -// From ostream_insert.h -template ostream& __ostream_insert(ostream&, const char*, streamsize); +static void get_app_arguments(int argc, char **argv, int &new_argc, char **&new_argv) +{ + std::vector temp_argv; + for (int i = 0; i < argc; i++) + { + // Don't copy -psn_xxx argument from argv. + if (i == 0 || strncmp(argv[i], "-psn_", 5) != 0) + temp_argv.push_back(std::string(argv[i])); + } -#ifdef _GLIBCXX_USE_WCHAR_T -template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize); -#endif + // Check for a drop file string. + std::string dropfilestr = love::osx::checkDropEvents(); + if (!dropfilestr.empty()) + { + temp_argv.insert(temp_argv.begin() + 1, dropfilestr); + } + else + { + // If it exists, add the love file in love.app/Contents/Resources/ to argv. + std::string loveResourcesPath = love::osx::getLoveInResources(); + if (!loveResourcesPath.empty()) + { + // Run in pseudo-fused mode. + std::vector::iterator it = temp_argv.begin(); + it = temp_argv.insert(it + 1, loveResourcesPath); + temp_argv.insert(it + 1, std::string("--fused")); + } + } -// From ostream.tcc -template ostream& ostream::_M_insert(long); -template ostream& ostream::_M_insert(unsigned long); -template ostream& ostream::_M_insert(bool); -#ifdef _GLIBCXX_USE_LONG_LONG -template ostream& ostream::_M_insert(long long); -template ostream& ostream::_M_insert(unsigned long long); -#endif -template ostream& ostream::_M_insert(double); -template ostream& ostream::_M_insert(long double); -template ostream& ostream::_M_insert(const void*); + // Copy temp argv vector to new argv array. + new_argc = (int) temp_argv.size(); + new_argv = new char *[new_argc+1]; -#ifdef _GLIBCXX_USE_WCHAR_T -template wostream& wostream::_M_insert(long); -template wostream& wostream::_M_insert(unsigned long); -template wostream& wostream::_M_insert(bool); -#ifdef _GLIBCXX_USE_LONG_LONG -template wostream& wostream::_M_insert(long long); -template wostream& wostream::_M_insert(unsigned long long); -#endif -template wostream& wostream::_M_insert(double); -template wostream& wostream::_M_insert(long double); -template wostream& wostream::_M_insert(const void*); -#endif + for (int i = 0; i < new_argc; i++) + { + new_argv[i] = new char[temp_argv[i].length() + 1]; + strcpy(new_argv[i], temp_argv[i].c_str()); + } -_GLIBCXX_END_NAMESPACE + new_argv[new_argc] = NULL; +} -#endif // LOVE_LEGENDARY_LIBSTDCXX_HACK +#endif // LOVE_LEGENDARY_APP_ARGV_HACK static int love_preload(lua_State *L, lua_CFunction f, const char *name) { @@ -133,8 +142,16 @@ int main(int argc, char **argv) argv = hack_argv; #endif // LOVE_LEGENDARY_UTF8_ARGV_HACK +#ifdef LOVE_LEGENDARY_APP_ARGV_HACK + int hack_argc = 0; + char **hack_argv = 0; + get_app_arguments(argc, argv, hack_argc, hack_argv); + argc = hack_argc; + argv = hack_argv; +#endif // LOVE_LEGENDARY_APP_ARGV_HACK + // Oh, you just want the version? Okay! - if (argc > 1 && strcmp(argv[1],"--version") == 0) + if (argc > 1 && strcmp(argv[1], "--version") == 0) { printf("LOVE %s (%s)\n", love_version(), love_codename()); return 0; @@ -144,10 +161,9 @@ int main(int argc, char **argv) lua_State *L = luaL_newstate(); luaL_openlibs(L); + // Add love to package.preload for easy requiring. love_preload(L, luaopen_love, "love"); - luaopen_love(L); - // Add command line arguments to global arg (like stand-alone Lua). { lua_newtable(L); @@ -161,7 +177,7 @@ int main(int argc, char **argv) lua_pushstring(L, "embedded boot.lua"); lua_rawseti(L, -2, -1); - for (int i = 1; iretain(); return this; @@ -135,6 +135,30 @@ void Source::getDirection(float *) const { } +void Source::setCone(float innerAngle, float outerAngle, float outerVolume) +{ + coneInnerAngle = innerAngle; + coneOuterAngle = outerAngle; + coneOuterVolume = outerVolume; +} + +void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume) const +{ + innerAngle = coneInnerAngle; + outerAngle = coneOuterAngle; + outerVolume = coneOuterVolume; +} + +void Source::setRelative(bool enable) +{ + relative = enable; +} + +bool Source::isRelative() const +{ + return relative; +} + void Source::setLooping(bool looping) { this->looping = looping; @@ -200,6 +224,11 @@ float Source::getMaxDistance() const return this->maxDistance; } +int Source::getChannels() const +{ + return 2; +} + } // null } // audio } // love diff --git a/src/modules/audio/null/Source.h b/src/modules/audio/null/Source.h index e79a37d74..887b3ef56 100644 --- a/src/modules/audio/null/Source.h +++ b/src/modules/audio/null/Source.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -38,7 +38,7 @@ public: Source(); virtual ~Source(); - virtual love::audio::Source *copy(); + virtual love::audio::Source *clone(); virtual void play(); virtual void stop(); virtual void pause(); @@ -60,6 +60,10 @@ public: virtual void getVelocity(float *v) const; virtual void setDirection(float *v); virtual void getDirection(float *v) const; + virtual void setCone(float innerAngle, float outerAngle, float outerVolume); + virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const; + virtual void setRelative(bool enable); + virtual bool isRelative() const; void setLooping(bool looping); bool isLooping() const; bool isStatic() const; @@ -73,11 +77,16 @@ public: virtual float getRolloffFactor() const; virtual void setMaxDistance(float distance); virtual float getMaxDistance() const; + virtual int getChannels() const; private: float pitch; float volume; + float coneInnerAngle; + float coneOuterAngle; + float coneOuterVolume; + bool relative; bool looping; float minVolume; float maxVolume; diff --git a/src/modules/audio/openal/Audio.cpp b/src/modules/audio/openal/Audio.cpp index aa32410df..07ce2959d 100644 --- a/src/modules/audio/openal/Audio.cpp +++ b/src/modules/audio/openal/Audio.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -68,7 +68,8 @@ void Audio::PoolThread::setFinish() finish = true; } -Audio::Audio() : distanceModel(DISTANCE_INVERSE_CLAMPED) +Audio::Audio() + : distanceModel(DISTANCE_INVERSE_CLAMPED) { // Passing zero for default device. device = alcOpenDevice(0); @@ -143,9 +144,9 @@ love::audio::Source *Audio::newSource(love::sound::SoundData *soundData) return new Source(pool, soundData); } -int Audio::getNumSources() const +int Audio::getSourceCount() const { - return pool->getNumSources(); + return pool->getSourceCount(); } int Audio::getMaxSources() const diff --git a/src/modules/audio/openal/Audio.h b/src/modules/audio/openal/Audio.h index e4febe87f..a40494b2a 100644 --- a/src/modules/audio/openal/Audio.h +++ b/src/modules/audio/openal/Audio.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -37,7 +37,7 @@ #include "thread/threads.h" // OpenAL -#ifdef LOVE_MACOSX +#ifdef LOVE_MACOSX_USE_FRAMEWORKS // Frameworks have different include paths. #include #include #else @@ -65,7 +65,7 @@ public: // Implements Audio. love::audio::Source *newSource(love::sound::Decoder *decoder); love::audio::Source *newSource(love::sound::SoundData *soundData); - int getNumSources() const; + int getSourceCount() const; int getMaxSources() const; void play(love::audio::Source *source); void play(); diff --git a/src/modules/audio/openal/Pool.cpp b/src/modules/audio/openal/Pool.cpp index 28eeccaf5..f3d74a91a 100644 --- a/src/modules/audio/openal/Pool.cpp +++ b/src/modules/audio/openal/Pool.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -76,7 +76,7 @@ bool Pool::isPlaying(Source *s) bool p = false; { thread::Lock lock(mutex); - for (std::map::iterator i = playing.begin(); i != playing.end(); i++) + for (auto i = playing.begin(); i != playing.end(); i++) { if (i->first == s) p = true; @@ -106,7 +106,7 @@ void Pool::update() } } -int Pool::getNumSources() const +int Pool::getSourceCount() const { return playing.size(); } @@ -118,11 +118,11 @@ int Pool::getMaxSources() const bool Pool::play(Source *source, ALuint &out) { - bool ok; - out = 0; - thread::Lock lock(mutex); + bool ok = true; + out = 0; + bool alreadyPlaying = findSource(source, out); if (!alreadyPlaying) @@ -161,7 +161,7 @@ bool Pool::play(Source *source, ALuint &out) void Pool::stop() { thread::Lock lock(mutex); - for (std::map::iterator i = playing.begin(); i != playing.end(); i++) + for (auto i = playing.begin(); i != playing.end(); i++) { i->first->stopAtomic(); i->first->release(); @@ -180,7 +180,7 @@ void Pool::stop(Source *source) void Pool::pause() { thread::Lock lock(mutex); - for (std::map::iterator i = playing.begin(); i != playing.end(); i++) + for (auto i = playing.begin(); i != playing.end(); i++) i->first->pauseAtomic(); } @@ -195,7 +195,7 @@ void Pool::pause(Source *source) void Pool::resume() { thread::Lock lock(mutex); - for (std::map::iterator i = playing.begin(); i != playing.end(); i++) + for (auto i = playing.begin(); i != playing.end(); i++) i->first->resumeAtomic(); } @@ -210,7 +210,7 @@ void Pool::resume(Source *source) void Pool::rewind() { thread::Lock lock(mutex); - for (std::map::iterator i = playing.begin(); i != playing.end(); i++) + for (auto i = playing.begin(); i != playing.end(); i++) i->first->rewindAtomic(); } diff --git a/src/modules/audio/openal/Pool.h b/src/modules/audio/openal/Pool.h index fce12ecbc..46353e759 100644 --- a/src/modules/audio/openal/Pool.h +++ b/src/modules/audio/openal/Pool.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,7 +33,7 @@ #include "thread/threads.h" // OpenAL -#ifdef LOVE_MACOSX +#ifdef LOVE_MACOSX_USE_FRAMEWORKS #include #include #else @@ -71,7 +71,7 @@ public: void update(); - int getNumSources() const; + int getSourceCount() const; int getMaxSources() const; bool play(Source *source, ALuint &out); diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index c416eaba6..332eb336e 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,8 +19,8 @@ **/ #include "Source.h" - #include "Pool.h" +#include "common/math.h" // STD #include @@ -33,12 +33,25 @@ namespace audio namespace openal { +StaticDataBuffer::StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq) +{ + alGenBuffers(1, &buffer); + alBufferData(buffer, format, data, size, freq); +} + +StaticDataBuffer::~StaticDataBuffer() +{ + alDeleteBuffers(1, &buffer); +} + Source::Source(Pool *pool, love::sound::SoundData *soundData) : love::audio::Source(Source::TYPE_STATIC) , pool(pool) , valid(false) + , staticBuffer(nullptr) , pitch(1.0f) , volume(1.0f) + , relative(false) , looping(false) , paused(false) , minVolume(0.0f) @@ -46,16 +59,17 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData) , referenceDistance(1.0f) , rolloffFactor(1.0f) , maxDistance(FLT_MAX) + , cone() , offsetSamples(0) , offsetSeconds(0) - , decoder(0) + , channels(soundData->getChannels()) + , decoder(nullptr) , toLoop(0) { - alGenBuffers(1, buffers); - ALenum fmt = getFormat(soundData->getChannels(), soundData->getBits()); - alBufferData(buffers[0], fmt, soundData->getData(), soundData->getSize(), soundData->getSampleRate()); + ALenum fmt = getFormat(soundData->getChannels(), soundData->getBitDepth()); + staticBuffer = new StaticDataBuffer(fmt, soundData->getData(), soundData->getSize(), soundData->getSampleRate()); - static float z[3] = {0, 0, 0}; + float z[3] = {0, 0, 0}; setFloatv(position, z); setFloatv(velocity, z); @@ -66,8 +80,10 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder) : love::audio::Source(Source::TYPE_STREAM) , pool(pool) , valid(false) + , staticBuffer(nullptr) , pitch(1.0f) , volume(1.0f) + , relative(false) , looping(false) , paused(false) , minVolume(0.0f) @@ -75,33 +91,78 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder) , referenceDistance(1.0f) , rolloffFactor(1.0f) , maxDistance(FLT_MAX) + , cone() , offsetSamples(0) , offsetSeconds(0) + , channels(decoder->getChannels()) , decoder(decoder) , toLoop(0) { decoder->retain(); - alGenBuffers(MAX_BUFFERS, buffers); + alGenBuffers(MAX_BUFFERS, streamBuffers); - static float z[3] = {0, 0, 0}; + float z[3] = {0, 0, 0}; setFloatv(position, z); setFloatv(velocity, z); setFloatv(direction, z); } +Source::Source(const Source &s) + : love::audio::Source(s.type) + , pool(s.pool) + , valid(false) + , staticBuffer(s.staticBuffer) + , pitch(s.pitch) + , volume(s.volume) + , relative(s.relative) + , looping(s.looping) + , paused(false) + , minVolume(s.minVolume) + , maxVolume(s.maxVolume) + , referenceDistance(s.referenceDistance) + , rolloffFactor(s.rolloffFactor) + , maxDistance(s.maxDistance) + , cone(s.cone) + , offsetSamples(0) + , offsetSeconds(0) + , channels(s.channels) + , decoder(nullptr) + , toLoop(0) +{ + if (type == TYPE_STREAM) + { + if (s.decoder) + decoder = s.decoder->clone(); + + alGenBuffers(MAX_BUFFERS, streamBuffers); + } + else + staticBuffer->retain(); + + setFloatv(position, s.position); + setFloatv(velocity, s.velocity); + setFloatv(direction, s.direction); +} + Source::~Source() { if (valid) pool->stop(this); - alDeleteBuffers((type == TYPE_STATIC) ? 1 : MAX_BUFFERS, buffers); + + if (type == TYPE_STREAM) + alDeleteBuffers(MAX_BUFFERS, streamBuffers); + + if (staticBuffer) + staticBuffer->release(); + if (decoder) decoder->release(); } -love::audio::Source *Source::copy() +love::audio::Source *Source::clone() { - return 0; + return new Source(*this); } void Source::play() @@ -113,9 +174,6 @@ void Source::play() } valid = pool->play(this, source); - - if (valid) - reset(source); } void Source::stop() @@ -338,13 +396,15 @@ float Source::tellAtomic(void *unit) const break; case Source::UNIT_SECONDS: default: - alGetSourcef(source, AL_SAMPLE_OFFSET, &offset); - ALint buffer; - alGetSourcei(source, AL_BUFFER, &buffer); - int freq; - alGetBufferi(buffer, AL_FREQUENCY, &freq); - offset /= freq; - if (type == TYPE_STREAM) offset += offsetSeconds; + { + alGetSourcef(source, AL_SAMPLE_OFFSET, &offset); + ALint buffer; + alGetSourcei(source, AL_BUFFER, &buffer); + int freq; + alGetBufferi(buffer, AL_FREQUENCY, &freq); + offset /= freq; + if (type == TYPE_STREAM) offset += offsetSeconds; + } break; } return offset; @@ -405,6 +465,40 @@ void Source::getDirection(float *v) const setFloatv(v, direction); } +void Source::setCone(float innerAngle, float outerAngle, float outerVolume) +{ + cone.innerAngle = LOVE_TODEG(innerAngle); + cone.outerAngle = LOVE_TODEG(outerAngle); + cone.outerVolume = outerVolume; + + if (valid) + { + alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle); + alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle); + alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume); + } +} + +void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume) const +{ + innerAngle = LOVE_TORAD(cone.innerAngle); + outerAngle = LOVE_TORAD(cone.outerAngle); + outerVolume = cone.outerVolume; +} + +void Source::setRelative(bool enable) +{ + if (valid) + alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); + + relative = enable; +} + +bool Source::isRelative() const +{ + return relative; +} + void Source::setLooping(bool looping) { if (valid && type == TYPE_STATIC) @@ -422,7 +516,7 @@ void Source::playAtomic() { if (type == TYPE_STATIC) { - alSourcei(source, AL_BUFFER, buffers[0]); + alSourcei(source, AL_BUFFER, staticBuffer->getBuffer()); } else if (type == TYPE_STREAM) { @@ -430,25 +524,20 @@ void Source::playAtomic() for (unsigned int i = 0; i < MAX_BUFFERS; i++) { - streamAtomic(buffers[i], decoder); + streamAtomic(streamBuffers[i], decoder); ++usedBuffers; if (decoder->isFinished()) break; } if (usedBuffers > 0) - alSourceQueueBuffers(source, usedBuffers, buffers); + alSourceQueueBuffers(source, usedBuffers, streamBuffers); } - // Set these properties. These may have changed while we've - // been without an AL source. - alSourcef(source, AL_PITCH, pitch); - alSourcef(source, AL_GAIN, volume); - alSourcef(source, AL_MIN_GAIN, minVolume); - alSourcef(source, AL_MAX_GAIN, maxVolume); - alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance); - alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor); - alSourcef(source, AL_MAX_DISTANCE, maxDistance); + // This Source may now be associated with an OpenAL source that still has + // the properties of another love Source. Let's reset it to the settings + // of the new one. + reset(); alSourcePlay(source); @@ -530,7 +619,7 @@ void Source::rewindAtomic() } } -void Source::reset(ALenum source) +void Source::reset() { alSourcefv(source, AL_POSITION, position); alSourcefv(source, AL_VELOCITY, velocity); @@ -542,6 +631,11 @@ void Source::reset(ALenum source) alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance); alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor); alSourcef(source, AL_MAX_DISTANCE, maxDistance); + alSourcei(source, AL_LOOPING, isStatic() && isLooping() ? AL_TRUE : AL_FALSE); + alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); + alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle); + alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle); + alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume); } void Source::setFloatv(float *dst, const float *src) const @@ -551,15 +645,15 @@ void Source::setFloatv(float *dst, const float *src) const dst[2] = src[2]; } -ALenum Source::getFormat(int channels, int bits) const +ALenum Source::getFormat(int channels, int bitDepth) const { - if (channels == 1 && bits == 8) + if (channels == 1 && bitDepth == 8) return AL_FORMAT_MONO8; - else if (channels == 1 && bits == 16) + else if (channels == 1 && bitDepth == 16) return AL_FORMAT_MONO16; - else if (channels == 2 && bits == 8) + else if (channels == 2 && bitDepth == 8) return AL_FORMAT_STEREO8; - else if (channels == 2 && bits == 16) + else if (channels == 2 && bitDepth == 16) return AL_FORMAT_STEREO16; else return 0; @@ -570,7 +664,7 @@ int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d) // Get more sound data. int decoded = d->decode(); - int fmt = getFormat(d->getChannels(), d->getBits()); + int fmt = getFormat(d->getChannels(), d->getBitDepth()); if (fmt != 0) alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate()); @@ -719,6 +813,11 @@ float Source::getMaxDistance() const return this->maxDistance; } +int Source::getChannels() const +{ + return channels; +} + } // openal } // audio } // love diff --git a/src/modules/audio/openal/Source.h b/src/modules/audio/openal/Source.h index eebe453e7..9a1182d74 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,7 +29,7 @@ #include "sound/Decoder.h" // OpenAL -#ifdef LOVE_MACOSX +#ifdef LOVE_MACOSX_USE_FRAMEWORKS #include #include #else @@ -47,14 +47,35 @@ namespace openal class Audio; class Pool; +// Basically just a reference-counted non-streaming OpenAL buffer object. +class StaticDataBuffer : public love::Object +{ +public: + + StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); + virtual ~StaticDataBuffer(); + + inline ALuint getBuffer() const + { + return buffer; + } + +private: + + ALuint buffer; + +}; // StaticDataBuffer + class Source : public love::audio::Source { public: + Source(Pool *pool, love::sound::SoundData *soundData); Source(Pool *pool, love::sound::Decoder *decoder); + Source(const Source &s); virtual ~Source(); - virtual love::audio::Source *copy(); + virtual love::audio::Source *clone(); virtual void play(); virtual void stop(); virtual void pause(); @@ -78,6 +99,10 @@ public: virtual void getVelocity(float *v) const; virtual void setDirection(float *v); virtual void getDirection(float *v) const; + virtual void setCone(float innerAngle, float outerAngle, float outerVolume); + virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const; + virtual void setRelative(bool enable); + virtual bool isRelative() const; void setLooping(bool looping); bool isLooping() const; bool isStatic() const; @@ -91,6 +116,7 @@ public: virtual float getRolloffFactor() const; virtual void setMaxDistance(float distance); virtual float getMaxDistance() const; + virtual int getChannels() const; void playAtomic(); void stopAtomic(); @@ -100,7 +126,7 @@ public: private: - void reset(ALenum source); + void reset(); void setFloatv(float *dst, const float *src) const; @@ -108,24 +134,28 @@ private: * Gets the OpenAL format identifier based on number of * channels and bits. * @param channels Either 1 (mono) or 2 (stereo). - * @param bits Either 8-bit samples, or 16-bit samples. + * @param bitDepth Either 8-bit samples, or 16-bit samples. * @return One of AL_FORMAT_*, or 0 if unsupported format. **/ - ALenum getFormat(int channels, int bits) const; + ALenum getFormat(int channels, int bitDepth) const; int streamAtomic(ALuint buffer, love::sound::Decoder *d); Pool *pool; ALuint source; bool valid; + static const unsigned int MAX_BUFFERS = 32; - ALuint buffers[MAX_BUFFERS]; + ALuint streamBuffers[MAX_BUFFERS]; + + StaticDataBuffer *staticBuffer; float pitch; float volume; float position[3]; float velocity[3]; float direction[3]; + bool relative; bool looping; bool paused; float minVolume; @@ -134,9 +164,24 @@ private: float rolloffFactor; float maxDistance; + struct Cone + { + int innerAngle; // degrees + int outerAngle; // degrees + float outerVolume; + + Cone() + : innerAngle(360) + , outerAngle(360) + , outerVolume(0.0f) + {} + } cone; + float offsetSamples; float offsetSeconds; + int channels; + love::sound::Decoder *decoder; unsigned int toLoop; diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index 5234f757c..4b8e39969 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,8 +24,6 @@ #include "openal/Audio.h" #include "null/Audio.h" -#include "scripts/audio.lua.h" - #include "common/runtime.h" namespace love @@ -35,14 +33,29 @@ namespace audio static Audio *instance = 0; -int w_getNumSources(lua_State *L) +int w_getSourceCount(lua_State *L) { - lua_pushinteger(L, instance->getNumSources()); + lua_pushinteger(L, instance->getSourceCount()); return 1; } -int w_newSource1(lua_State *L) +int w_newSource(lua_State *L) { + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); + + if (luax_istype(L, 1, FILESYSTEM_FILE_DATA_T)) + luax_convobj(L, 1, "sound", "newDecoder"); + + Source::Type stype = Source::TYPE_STREAM; + + const char *stypestr = lua_isnoneornil(L, 2) ? 0 : lua_tostring(L, 2); + if (stypestr && !Source::getConstant(stypestr, stype)) + return luaL_error(L, "Invalid source type: %s", stypestr); + + if (stype == Source::TYPE_STATIC && luax_istype(L, 1, SOUND_DECODER_T)) + luax_convobj(L, 1, "sound", "newSoundData"); + Source *t = 0; if (luax_istype(L, 1, SOUND_SOUND_DATA_T)) @@ -52,13 +65,11 @@ int w_newSource1(lua_State *L) if (t) { - luax_newtype(L, "Source", AUDIO_SOURCE_T, (void *)t); + luax_pushtype(L, "Source", AUDIO_SOURCE_T, t); return 1; } else - return luaL_error(L, "No matching overload"); - - return 0; + return luax_typerror(L, 1, "Decoder or SoundData"); } int w_play(lua_State *L) @@ -216,7 +227,7 @@ int w_getRecordedData(lua_State *L) if (!sd) lua_pushnil(L); else - luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void *)sd); + luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, sd); return 1; } @@ -226,7 +237,7 @@ int w_stopRecording(lua_State *L) { love::sound::SoundData *sd = instance->stopRecording(true); if (!sd) lua_pushnil(L); - else luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void *)sd); + else luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, sd); return 1; } instance->stopRecording(false); @@ -262,8 +273,8 @@ int w_getDistanceModel(lua_State *L) // List of functions to wrap. static const luaL_Reg functions[] = { - { "getNumSources", w_getNumSources }, - { "newSource1", w_newSource1 }, + { "getSourceCount", w_getSourceCount }, + { "newSource", w_newSource }, { "play", w_play }, { "stop", w_stop }, { "pause", w_pause }, @@ -293,6 +304,7 @@ static const lua_CFunction types[] = extern "C" int luaopen_love_audio(lua_State *L) { +#ifdef LOVE_ENABLE_AUDIO_OPENAL if (instance == 0) { // Try OpenAL first. @@ -307,7 +319,9 @@ extern "C" int luaopen_love_audio(lua_State *L) } else instance->retain(); +#endif +#ifdef LOVE_ENABLE_AUDIO_NULL if (instance == 0) { // Fall back to nullaudio. @@ -320,6 +334,7 @@ extern "C" int luaopen_love_audio(lua_State *L) std::cout << e.what() << std::endl; } } +#endif if (instance == 0) return luaL_error(L, "Could not open any audio module."); @@ -333,9 +348,6 @@ extern "C" int luaopen_love_audio(lua_State *L) int n = luax_register_module(L, w); - if (luaL_loadbuffer(L, (const char *)audio_lua, sizeof(audio_lua), "audio.lua") == 0) - lua_call(L, 0, 0); - return n; } diff --git a/src/modules/audio/wrap_Audio.h b/src/modules/audio/wrap_Audio.h index 01d45e817..1960e0d1e 100644 --- a/src/modules/audio/wrap_Audio.h +++ b/src/modules/audio/wrap_Audio.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -32,8 +32,8 @@ namespace love namespace audio { -int w_getNumSources(lua_State *L); -int w_newSource1(lua_State *L); +int w_getSourceCount(lua_State *L); +int w_newSource(lua_State *L); int w_play(lua_State *L); int w_stop(lua_State *L); int w_pause(lua_State *L); diff --git a/src/modules/audio/wrap_Source.cpp b/src/modules/audio/wrap_Source.cpp index 74dd8cab3..d1f3e61a1 100644 --- a/src/modules/audio/wrap_Source.cpp +++ b/src/modules/audio/wrap_Source.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,6 +18,8 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +#include + #include "wrap_Source.h" namespace love @@ -30,6 +32,15 @@ Source *luax_checksource(lua_State *L, int idx) return luax_checktype(L, idx, "Source", AUDIO_SOURCE_T); } +int w_Source_clone(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + Source *clone = nullptr; + EXCEPT_GUARD(clone = t->clone();) + luax_pushtype(L, "Source", AUDIO_SOURCE_T, clone); + return 1; +} + int w_Source_play(lua_State *L) { Source *t = luax_checksource(L, 1); @@ -69,6 +80,10 @@ int w_Source_setPitch(lua_State *L) { Source *t = luax_checksource(L, 1); float p = (float)luaL_checknumber(L, 2); + if (p > std::numeric_limits::max() || + p < std::numeric_limits::min() || + p != p) + return luaL_error(L, "Pitch has to be finite and not NaN."); t->setPitch(p); return 0; } @@ -99,9 +114,14 @@ int w_Source_seek(lua_State *L) { Source *t = luax_checksource(L, 1); float offset = (float)luaL_checknumber(L, 2); - const char *unit = luaL_optstring(L, 3, "seconds"); - Source::Unit u; - t->getConstant(unit, u); + if (offset < 0) + return luaL_argerror(L, 2, "can't seek to a negative position"); + + Source::Unit u = Source::UNIT_SECONDS; + const char *unit = lua_isnoneornil(L, 3) ? 0 : lua_tostring(L, 3); + if (unit && !t->getConstant(unit, u)) + return luaL_error(L, "Invalid Source time unit: %s", unit); + t->seek(offset, u); return 0; } @@ -109,9 +129,12 @@ int w_Source_seek(lua_State *L) int w_Source_tell(lua_State *L) { Source *t = luax_checksource(L, 1); - const char *unit = luaL_optstring(L, 2, "seconds"); - Source::Unit u; - t->getConstant(unit, u); + + Source::Unit u = Source::UNIT_SECONDS; + const char *unit = lua_isnoneornil(L, 2) ? 0 : lua_tostring(L, 2); + if (unit && !t->getConstant(unit, u)) + return luaL_error(L, "Invalid Source time unit: %s", unit); + lua_pushnumber(L, t->tell(u)); return 1; } @@ -182,6 +205,41 @@ int w_Source_getDirection(lua_State *L) return 3; } +int w_Source_setCone(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + float innerAngle = (float) luaL_checknumber(L, 2); + float outerAngle = (float) luaL_checknumber(L, 3); + float outerVolume = (float) luaL_optnumber(L, 4, 0.0); + t->setCone(innerAngle, outerAngle, outerVolume); + return 0; +} + +int w_Source_getCone(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + float innerAngle, outerAngle, outerVolume; + t->getCone(innerAngle, outerAngle, outerVolume); + lua_pushnumber(L, innerAngle); + lua_pushnumber(L, outerAngle); + lua_pushnumber(L, outerVolume); + return 3; +} + +int w_Source_setRelative(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + t->setRelative(luax_toboolean(L, 2)); + return 0; +} + +int w_Source_isRelative(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + luax_pushboolean(L, t->isRelative()); + return 1; +} + int w_Source_setLooping(lua_State *L) { Source *t = luax_checksource(L, 1); @@ -244,7 +302,7 @@ int w_Source_getVolumeLimits(lua_State *L) return 2; } -int w_Source_setDistance(lua_State *L) +int w_Source_setAttenuationDistances(lua_State *L) { Source *t = luax_checksource(L, 1); float dref = (float)luaL_checknumber(L, 2); @@ -256,7 +314,7 @@ int w_Source_setDistance(lua_State *L) return 0; } -int w_Source_getDistance(lua_State *L) +int w_Source_getAttenuationDistances(lua_State *L) { Source *t = luax_checksource(L, 1); lua_pushnumber(L, t->getReferenceDistance()); @@ -281,8 +339,17 @@ int w_Source_getRolloff(lua_State *L) return 1; } +int w_Source_getChannels(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + lua_pushinteger(L, t->getChannels()); + return 1; +} + static const luaL_Reg functions[] = { + { "clone", w_Source_clone }, + { "play", w_Source_play }, { "stop", w_Source_stop }, { "pause", w_Source_pause }, @@ -301,6 +368,11 @@ static const luaL_Reg functions[] = { "getVelocity", w_Source_getVelocity }, { "setDirection", w_Source_setDirection }, { "getDirection", w_Source_getDirection }, + { "setCone", w_Source_setCone }, + { "getCone", w_Source_getCone }, + + { "setRelative", w_Source_setRelative }, + { "isRelative", w_Source_isRelative }, { "setLooping", w_Source_setLooping }, { "isLooping", w_Source_isLooping }, @@ -311,11 +383,13 @@ static const luaL_Reg functions[] = { "setVolumeLimits", w_Source_setVolumeLimits }, { "getVolumeLimits", w_Source_getVolumeLimits }, - { "setDistance", w_Source_setDistance }, - { "getDistance", w_Source_getDistance }, + { "setAttenuationDistances", w_Source_setAttenuationDistances }, + { "getAttenuationDistances", w_Source_getAttenuationDistances }, { "setRolloff", w_Source_setRolloff}, { "getRolloff", w_Source_getRolloff}, + { "getChannels", w_Source_getChannels }, + { 0, 0 } }; diff --git a/src/modules/audio/wrap_Source.h b/src/modules/audio/wrap_Source.h index 8ec0faebb..0a49b4c6d 100644 --- a/src/modules/audio/wrap_Source.h +++ b/src/modules/audio/wrap_Source.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -30,6 +30,7 @@ namespace audio { Source *luax_checksource(lua_State *L, int idx); +int w_Source_clone(lua_State *L); int w_Source_play(lua_State *L); int w_Source_stop(lua_State *L); int w_Source_pause(lua_State *L); @@ -47,6 +48,10 @@ int w_Source_setVelocity(lua_State *L); int w_Source_getVelocity(lua_State *L); int w_Source_setDirection(lua_State *L); int w_Source_getDirection(lua_State *L); +int w_Source_setCone(lua_State *L); +int w_Source_getCone(lua_State *L); +int w_Source_setRelative(lua_State *L); +int w_Source_isRelative(lua_State *L); int w_Source_setLooping(lua_State *L); int w_Source_isLooping(lua_State *L); int w_Source_isStopped(lua_State *L); @@ -55,10 +60,11 @@ int w_Source_isPlaying(lua_State *L); int w_Source_isStatic(lua_State *L); int w_Source_setVolumeLimits(lua_State *L); int w_Source_getVolumeLimits(lua_State *L); -int w_Source_setDistance(lua_State *L); -int w_Source_getDistance(lua_State *L); +int w_Source_setAttenuationDistances(lua_State *L); +int w_Source_getAttenuationDistances(lua_State *L); int w_Source_setRolloff(lua_State *L); int w_Source_getRolloff(lua_State *L); +int w_Source_getChannels(lua_State *L); extern "C" int luaopen_source(lua_State *L); } // audio diff --git a/src/modules/event/Event.cpp b/src/modules/event/Event.cpp index 973eacd55..1c7999ec3 100644 --- a/src/modules/event/Event.cpp +++ b/src/modules/event/Event.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -28,7 +28,7 @@ namespace love namespace event { -Message::Message(std::string name, Variant *a, Variant *b, Variant *c, Variant *d) +Message::Message(const std::string &name, Variant *a, Variant *b, Variant *c, Variant *d) : name(name) , nargs(0) { @@ -39,7 +39,7 @@ Message::Message(std::string name, Variant *a, Variant *b, Variant *c, Variant * for (int i = 0; i < 4; i++) { if (!args[i]) - continue; + break; args[i]->retain(); nargs++; } @@ -112,192 +112,11 @@ void Event::clear() Lock lock(mutex); while (!queue.empty()) { - queue.back()->release(); + // std::queue::pop will remove the first (front) element. + queue.front()->release(); queue.pop(); } } -bool Event::getConstant(const char *in, love::mouse::Mouse::Button &out) -{ - return buttons.find(in, out); -} - -bool Event::getConstant(love::mouse::Mouse::Button in, const char *&out) -{ - return buttons.find(in, out); -} - -bool Event::getConstant(const char *in, love::keyboard::Keyboard::Key &out) -{ - return keys.find(in, out); -} - -bool Event::getConstant(love::keyboard::Keyboard::Key in, const char *&out) -{ - return keys.find(in, out); -} - -StringMap::Entry Event::buttonEntries[] = -{ - {"l", love::mouse::Mouse::BUTTON_LEFT}, - {"m", love::mouse::Mouse::BUTTON_MIDDLE}, - {"r", love::mouse::Mouse::BUTTON_RIGHT}, - {"wu", love::mouse::Mouse::BUTTON_WHEELUP}, - {"wd", love::mouse::Mouse::BUTTON_WHEELDOWN}, - {"x1", love::mouse::Mouse::BUTTON_X1}, - {"x2", love::mouse::Mouse::BUTTON_X2}, -}; - -StringMap Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries)); - -StringMap::Entry Event::keyEntries[] = -{ - {"backspace", love::keyboard::Keyboard::KEY_BACKSPACE}, - {"tab", love::keyboard::Keyboard::KEY_TAB}, - {"clear", love::keyboard::Keyboard::KEY_CLEAR}, - {"return", love::keyboard::Keyboard::KEY_RETURN}, - {"pause", love::keyboard::Keyboard::KEY_PAUSE}, - {"escape", love::keyboard::Keyboard::KEY_ESCAPE}, - {" ", love::keyboard::Keyboard::KEY_SPACE}, - {"!", love::keyboard::Keyboard::KEY_EXCLAIM}, - {"\"", love::keyboard::Keyboard::KEY_QUOTEDBL}, - {"#", love::keyboard::Keyboard::KEY_HASH}, - {"$", love::keyboard::Keyboard::KEY_DOLLAR}, - {"&", love::keyboard::Keyboard::KEY_AMPERSAND}, - {"'", love::keyboard::Keyboard::KEY_QUOTE}, - {"(", love::keyboard::Keyboard::KEY_LEFTPAREN}, - {")", love::keyboard::Keyboard::KEY_RIGHTPAREN}, - {"*", love::keyboard::Keyboard::KEY_ASTERISK}, - {"+", love::keyboard::Keyboard::KEY_PLUS}, - {",", love::keyboard::Keyboard::KEY_COMMA}, - {"-", love::keyboard::Keyboard::KEY_MINUS}, - {".", love::keyboard::Keyboard::KEY_PERIOD}, - {"/", love::keyboard::Keyboard::KEY_SLASH}, - {"0", love::keyboard::Keyboard::KEY_0}, - {"1", love::keyboard::Keyboard::KEY_1}, - {"2", love::keyboard::Keyboard::KEY_2}, - {"3", love::keyboard::Keyboard::KEY_3}, - {"4", love::keyboard::Keyboard::KEY_4}, - {"5", love::keyboard::Keyboard::KEY_5}, - {"6", love::keyboard::Keyboard::KEY_6}, - {"7", love::keyboard::Keyboard::KEY_7}, - {"8", love::keyboard::Keyboard::KEY_8}, - {"9", love::keyboard::Keyboard::KEY_9}, - {":", love::keyboard::Keyboard::KEY_COLON}, - {";", love::keyboard::Keyboard::KEY_SEMICOLON}, - {"<", love::keyboard::Keyboard::KEY_LESS}, - {"=", love::keyboard::Keyboard::KEY_EQUALS}, - {">", love::keyboard::Keyboard::KEY_GREATER}, - {"?", love::keyboard::Keyboard::KEY_QUESTION}, - {"@", love::keyboard::Keyboard::KEY_AT}, - - {"[", love::keyboard::Keyboard::KEY_LEFTBRACKET}, - {"\\", love::keyboard::Keyboard::KEY_BACKSLASH}, - {"]", love::keyboard::Keyboard::KEY_RIGHTBRACKET}, - {"^", love::keyboard::Keyboard::KEY_CARET}, - {"_", love::keyboard::Keyboard::KEY_UNDERSCORE}, - {"`", love::keyboard::Keyboard::KEY_BACKQUOTE}, - {"a", love::keyboard::Keyboard::KEY_A}, - {"b", love::keyboard::Keyboard::KEY_B}, - {"c", love::keyboard::Keyboard::KEY_C}, - {"d", love::keyboard::Keyboard::KEY_D}, - {"e", love::keyboard::Keyboard::KEY_E}, - {"f", love::keyboard::Keyboard::KEY_F}, - {"g", love::keyboard::Keyboard::KEY_G}, - {"h", love::keyboard::Keyboard::KEY_H}, - {"i", love::keyboard::Keyboard::KEY_I}, - {"j", love::keyboard::Keyboard::KEY_J}, - {"k", love::keyboard::Keyboard::KEY_K}, - {"l", love::keyboard::Keyboard::KEY_L}, - {"m", love::keyboard::Keyboard::KEY_M}, - {"n", love::keyboard::Keyboard::KEY_N}, - {"o", love::keyboard::Keyboard::KEY_O}, - {"p", love::keyboard::Keyboard::KEY_P}, - {"q", love::keyboard::Keyboard::KEY_Q}, - {"r", love::keyboard::Keyboard::KEY_R}, - {"s", love::keyboard::Keyboard::KEY_S}, - {"t", love::keyboard::Keyboard::KEY_T}, - {"u", love::keyboard::Keyboard::KEY_U}, - {"v", love::keyboard::Keyboard::KEY_V}, - {"w", love::keyboard::Keyboard::KEY_W}, - {"x", love::keyboard::Keyboard::KEY_X}, - {"y", love::keyboard::Keyboard::KEY_Y}, - {"z", love::keyboard::Keyboard::KEY_Z}, - {"delete", love::keyboard::Keyboard::KEY_DELETE}, - - {"kp0", love::keyboard::Keyboard::KEY_KP0}, - {"kp1", love::keyboard::Keyboard::KEY_KP1}, - {"kp2", love::keyboard::Keyboard::KEY_KP2}, - {"kp3", love::keyboard::Keyboard::KEY_KP3}, - {"kp4", love::keyboard::Keyboard::KEY_KP4}, - {"kp5", love::keyboard::Keyboard::KEY_KP5}, - {"kp6", love::keyboard::Keyboard::KEY_KP6}, - {"kp7", love::keyboard::Keyboard::KEY_KP7}, - {"kp8", love::keyboard::Keyboard::KEY_KP8}, - {"kp9", love::keyboard::Keyboard::KEY_KP9}, - {"kp.", love::keyboard::Keyboard::KEY_KP_PERIOD}, - {"kp/", love::keyboard::Keyboard::KEY_KP_DIVIDE}, - {"kp*", love::keyboard::Keyboard::KEY_KP_MULTIPLY}, - {"kp-", love::keyboard::Keyboard::KEY_KP_MINUS}, - {"kp+", love::keyboard::Keyboard::KEY_KP_PLUS}, - {"kpenter", love::keyboard::Keyboard::KEY_KP_ENTER}, - {"kp=", love::keyboard::Keyboard::KEY_KP_EQUALS}, - - {"up", love::keyboard::Keyboard::KEY_UP}, - {"down", love::keyboard::Keyboard::KEY_DOWN}, - {"right", love::keyboard::Keyboard::KEY_RIGHT}, - {"left", love::keyboard::Keyboard::KEY_LEFT}, - {"insert", love::keyboard::Keyboard::KEY_INSERT}, - {"home", love::keyboard::Keyboard::KEY_HOME}, - {"end", love::keyboard::Keyboard::KEY_END}, - {"pageup", love::keyboard::Keyboard::KEY_PAGEUP}, - {"pagedown", love::keyboard::Keyboard::KEY_PAGEDOWN}, - - {"f1", love::keyboard::Keyboard::KEY_F1}, - {"f2", love::keyboard::Keyboard::KEY_F2}, - {"f3", love::keyboard::Keyboard::KEY_F3}, - {"f4", love::keyboard::Keyboard::KEY_F4}, - {"f5", love::keyboard::Keyboard::KEY_F5}, - {"f6", love::keyboard::Keyboard::KEY_F6}, - {"f7", love::keyboard::Keyboard::KEY_F7}, - {"f8", love::keyboard::Keyboard::KEY_F8}, - {"f9", love::keyboard::Keyboard::KEY_F9}, - {"f10", love::keyboard::Keyboard::KEY_F10}, - {"f11", love::keyboard::Keyboard::KEY_F11}, - {"f12", love::keyboard::Keyboard::KEY_F12}, - {"f13", love::keyboard::Keyboard::KEY_F13}, - {"f14", love::keyboard::Keyboard::KEY_F14}, - {"f15", love::keyboard::Keyboard::KEY_F15}, - - {"numlock", love::keyboard::Keyboard::KEY_NUMLOCK}, - {"capslock", love::keyboard::Keyboard::KEY_CAPSLOCK}, - {"scrollock", love::keyboard::Keyboard::KEY_SCROLLOCK}, - {"rshift", love::keyboard::Keyboard::KEY_RSHIFT}, - {"lshift", love::keyboard::Keyboard::KEY_LSHIFT}, - {"rctrl", love::keyboard::Keyboard::KEY_RCTRL}, - {"lctrl", love::keyboard::Keyboard::KEY_LCTRL}, - {"ralt", love::keyboard::Keyboard::KEY_RALT}, - {"lalt", love::keyboard::Keyboard::KEY_LALT}, - {"rmeta", love::keyboard::Keyboard::KEY_RMETA}, - {"lmeta", love::keyboard::Keyboard::KEY_LMETA}, - {"lsuper", love::keyboard::Keyboard::KEY_LSUPER}, - {"rsuper", love::keyboard::Keyboard::KEY_RSUPER}, - {"mode", love::keyboard::Keyboard::KEY_MODE}, - {"compose", love::keyboard::Keyboard::KEY_COMPOSE}, - - {"help", love::keyboard::Keyboard::KEY_HELP}, - {"print", love::keyboard::Keyboard::KEY_PRINT}, - {"sysreq", love::keyboard::Keyboard::KEY_SYSREQ}, - {"break", love::keyboard::Keyboard::KEY_BREAK}, - {"menu", love::keyboard::Keyboard::KEY_MENU}, - {"power", love::keyboard::Keyboard::KEY_POWER}, - {"euro", love::keyboard::Keyboard::KEY_EURO}, - {"undo", love::keyboard::Keyboard::KEY_UNDO}, - - {"unknown", love::keyboard::Keyboard::KEY_UNKNOWN}, -}; - -StringMap Event::keys(Event::keyEntries, sizeof(Event::keyEntries)); - } // event } // love diff --git a/src/modules/event/Event.h b/src/modules/event/Event.h index e28f36c8c..38037edc5 100644 --- a/src/modules/event/Event.h +++ b/src/modules/event/Event.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -27,6 +27,7 @@ #include "common/Variant.h" #include "keyboard/Keyboard.h" #include "mouse/Mouse.h" +#include "joystick/Joystick.h" #include "thread/threads.h" // STL @@ -44,7 +45,7 @@ private: int nargs; public: - Message(std::string name, Variant *a = NULL, Variant *b = NULL, Variant *c = NULL, Variant *d = NULL); + Message(const std::string &name, Variant *a = NULL, Variant *b = NULL, Variant *c = NULL, Variant *d = NULL); ~Message(); int toLua(lua_State *L); @@ -63,18 +64,10 @@ public: virtual void pump() = 0; - static bool getConstant(const char *in, love::mouse::Mouse::Button &out); - static bool getConstant(love::mouse::Mouse::Button in, const char *&out); - static bool getConstant(const char *in, love::keyboard::Keyboard::Key &out); - static bool getConstant(love::keyboard::Keyboard::Key in, const char *&out); - protected: thread::Mutex *mutex; std::queue queue; - static StringMap::Entry buttonEntries[]; - static StringMap buttons; - static StringMap::Entry keyEntries[]; - static StringMap keys; + }; // Event } // event diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 25ce5f1f6..ece1f7bfd 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,6 +22,13 @@ #include "keyboard/Keyboard.h" #include "mouse/Mouse.h" +#include "joystick/JoystickModule.h" +#include "joystick/sdl/Joystick.h" +#include "graphics/Graphics.h" +#include "window/Window.h" +#include "common/Exception.h" + +#include namespace love { @@ -37,7 +44,13 @@ const char *Event::getName() const Event::Event() { - SDL_EnableUNICODE(1); + if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) + throw love::Exception("%s", SDL_GetError()); +} + +Event::~Event() +{ + SDL_QuitSubSystem(SDL_INIT_EVENTS); } void Event::pump() @@ -45,7 +58,6 @@ void Event::pump() SDL_PumpEvents(); static SDL_Event e; - SDL_EnableUNICODE(1); Message *msg; @@ -81,38 +93,74 @@ void Event::clear() love::event::Event::clear(); } -Message *Event::convert(SDL_Event &e) +Message *Event::convert(const SDL_Event &e) const { Message *msg = NULL; + + love::keyboard::Keyboard *kb = 0; + love::keyboard::Keyboard::Key key; love::mouse::Mouse::Button button; Variant *arg1, *arg2, *arg3; const char *txt; + std::map::const_iterator keyit; + switch (e.type) { case SDL_KEYDOWN: - if (!keys.find(e.key.keysym.sym, key)) + if (e.key.repeat) + { + kb = (love::keyboard::Keyboard *) Module::findInstance("love.keyboard."); + if (kb && !kb->hasKeyRepeat()) + break; + } + + keyit = keys.find(e.key.keysym.sym); + if (keyit != keys.end()) + key = keyit->second; + else key = love::keyboard::Keyboard::KEY_UNKNOWN; - if (!love::event::Event::keys.find(key, txt)) + + if (!love::keyboard::Keyboard::getConstant(key, txt)) txt = "unknown"; arg1 = new Variant(txt, strlen(txt)); - arg2 = new Variant((double) e.key.keysym.unicode); + arg2 = new Variant(e.key.repeat != 0); msg = new Message("keypressed", arg1, arg2); arg1->release(); arg2->release(); break; case SDL_KEYUP: - if (!keys.find(e.key.keysym.sym, key)) + keyit = keys.find(e.key.keysym.sym); + if (keyit != keys.end()) + key = keyit->second; + else key = love::keyboard::Keyboard::KEY_UNKNOWN; - if (!love::event::Event::keys.find(key, txt)) + + if (!love::keyboard::Keyboard::getConstant(key, txt)) txt = "unknown"; arg1 = new Variant(txt, strlen(txt)); msg = new Message("keyreleased", arg1); arg1->release(); break; + case SDL_TEXTINPUT: + txt = e.text.text; + arg1 = new Variant(txt, strlen(txt)); + msg = new Message("textinput", arg1); + arg1->release(); + break; + case SDL_TEXTEDITING: + txt = e.edit.text; + arg1 = new Variant(txt, strlen(txt)); + arg2 = new Variant((double) e.edit.start); + arg3 = new Variant((double) e.edit.length); + msg = new Message("textedit", arg1, arg2, arg3); + arg1->release(); + arg2->release(); + arg3->release(); + break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: - if (buttons.find(e.button.button, button) && love::event::Event::buttons.find(button, txt)) + if (buttons.find(e.button.button, button) && mouse::Mouse::getConstant(button, txt)) { arg1 = new Variant((double) e.button.x); arg2 = new Variant((double) e.button.y); @@ -125,9 +173,77 @@ Message *Event::convert(SDL_Event &e) arg3->release(); } break; + case SDL_MOUSEWHEEL: + if (e.wheel.y != 0) + { + button = (e.wheel.y > 0) ? mouse::Mouse::BUTTON_WHEELUP : mouse::Mouse::BUTTON_WHEELDOWN; + if (!love::mouse::Mouse::getConstant(button, txt)) + break; + + int mx, my; + SDL_GetMouseState(&mx, &my); + + arg1 = new Variant((double) mx); + arg2 = new Variant((double) my); + arg3 = new Variant(txt, strlen(txt)); + msg = new Message("mousepressed", arg1, arg2, arg3); + arg1->release(); + arg2->release(); + arg3->release(); + } + break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: - arg1 = new Variant((double)(e.jbutton.which+1)); + case SDL_JOYAXISMOTION: + case SDL_JOYBALLMOTION: + case SDL_JOYHATMOTION: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + case SDL_CONTROLLERAXISMOTION: + msg = convertJoystickEvent(e); + break; + case SDL_WINDOWEVENT: + msg = convertWindowEvent(e); + break; + case SDL_DROPFILE: + SDL_free(e.drop.file); + break; + case SDL_QUIT: + msg = new Message("quit"); + break; + default: + break; + } + + return msg; +} + +Message *Event::convertJoystickEvent(const SDL_Event &e) const +{ + joystick::JoystickModule *joymodule = (joystick::JoystickModule *) Module::findInstance("love.joystick."); + if (!joymodule) + return 0; + + Message *msg = 0; + Proxy proxy; + love::joystick::Joystick::Hat hat; + love::joystick::Joystick::GamepadButton padbutton; + love::joystick::Joystick::GamepadAxis padaxis; + Variant *arg1, *arg2, *arg3; + const char *txt; + + switch (e.type) + { + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + proxy.flags = JOYSTICK_JOYSTICK_T; + proxy.data = joymodule->getJoystickFromID(e.jbutton.which); + if (!proxy.data) + break; + + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); arg2 = new Variant((double)(e.jbutton.button+1)); msg = new Message((e.type == SDL_JOYBUTTONDOWN) ? "joystickpressed" : "joystickreleased", @@ -135,18 +251,165 @@ Message *Event::convert(SDL_Event &e) arg1->release(); arg2->release(); break; - case SDL_ACTIVEEVENT: - arg1 = new Variant(e.active.gain != 0); - if (e.active.state & SDL_APPINPUTFOCUS) - msg = new Message("focus", arg1); + case SDL_JOYAXISMOTION: + { + proxy.flags = JOYSTICK_JOYSTICK_T; + proxy.data = joymodule->getJoystickFromID(e.jaxis.which); + if (!proxy.data) + break; + + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); + arg2 = new Variant((double)(e.jaxis.axis+1)); + float value = e.jaxis.value / 32768.0f; + if (fabsf(value) < 0.001f) value = 0.0f; + if (value < -0.99f) value = -1.0f; + if (value > 0.99f) value = 1.0f; + arg3 = new Variant((double) value); + msg = new Message("joystickaxis", arg1, arg2, arg3); + arg1->release(); + arg2->release(); + arg3->release(); + } + break; + case SDL_JOYHATMOTION: + if (!joystick::sdl::Joystick::getConstant(e.jhat.value, hat) || !joystick::Joystick::getConstant(hat, txt)) + break; + + proxy.flags = JOYSTICK_JOYSTICK_T; + proxy.data = joymodule->getJoystickFromID(e.jhat.which); + if (!proxy.data) + break; + + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); + arg2 = new Variant((double)(e.jhat.hat+1)); + arg3 = new Variant(txt, strlen(txt)); + msg = new Message("joystickhat", arg1, arg2, arg3); + arg1->release(); + arg2->release(); + arg3->release(); + break; + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + if (!joystick::sdl::Joystick::getConstant((SDL_GameControllerButton) e.cbutton.button, padbutton)) + break; + + if (!joystick::Joystick::getConstant(padbutton, txt)) + break; + + proxy.flags = JOYSTICK_JOYSTICK_T; + proxy.data = joymodule->getJoystickFromID(e.cbutton.which); + if (!proxy.data) + break; + + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); + arg2 = new Variant(txt, strlen(txt)); + msg = new Message(e.type == SDL_CONTROLLERBUTTONDOWN ? + "gamepadpressed" : "gamepadreleased", arg1, arg2); + arg1->release(); + arg2->release(); + break; + case SDL_CONTROLLERAXISMOTION: + if (joystick::sdl::Joystick::getConstant((SDL_GameControllerAxis) e.caxis.axis, padaxis)) + { + if (!joystick::Joystick::getConstant(padaxis, txt)) + break; + + proxy.flags = JOYSTICK_JOYSTICK_T; + proxy.data = joymodule->getJoystickFromID(e.caxis.which); + if (!proxy.data) + break; + + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); + + arg2 = new Variant(txt, strlen(txt)); + float value = e.jaxis.value / 32768.0f; + if (fabsf(value) < 0.001f) value = 0.0f; + if (value < -0.99f) value = -1.0f; + if (value > 0.99f) value = 1.0f; + arg3 = new Variant((double) value); + msg = new Message("gamepadaxis", arg1, arg2, arg3); + arg1->release(); + arg2->release(); + arg3->release(); + } + break; + case SDL_JOYDEVICEADDED: + // jdevice.which is the joystick device index. + proxy.data = joymodule->addJoystick(e.jdevice.which); + proxy.flags = JOYSTICK_JOYSTICK_T; + if (proxy.data) + { + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); + msg = new Message("joystickadded", arg1); + arg1->release(); + } + break; + case SDL_JOYDEVICEREMOVED: + // jdevice.which is the joystick instance ID now. + proxy.data = joymodule->getJoystickFromID(e.jdevice.which); + proxy.flags = JOYSTICK_JOYSTICK_T; + if (proxy.data) + { + joymodule->removeJoystick((joystick::Joystick *) proxy.data); + arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy); + msg = new Message("joystickremoved", arg1); + arg1->release(); + } + break; + default: + break; + } + + return msg; +} + +Message *Event::convertWindowEvent(const SDL_Event &e) const +{ + Message *msg = 0; + Variant *arg1, *arg2; + window::Window *win = 0; + + if (e.type != SDL_WINDOWEVENT) + return 0; + + switch (e.window.event) + { + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + // Users won't expect the screensaver to activate if a game is in + // focus. Also, joystick input may not delay the screensaver timer. + if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) + SDL_DisableScreenSaver(); + else + SDL_EnableScreenSaver(); + arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); + msg = new Message("focus", arg1); arg1->release(); break; - case SDL_QUIT: - msg = new Message("quit"); + case SDL_WINDOWEVENT_ENTER: + case SDL_WINDOWEVENT_LEAVE: + arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_ENTER); + msg = new Message("mousefocus", arg1); + arg1->release(); break; - case SDL_VIDEORESIZE: - arg1 = new Variant((double) e.resize.w); - arg2 = new Variant((double) e.resize.h); + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_HIDDEN: + arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_SHOWN); + msg = new Message("visible", arg1); + arg1->release(); + break; + case SDL_WINDOWEVENT_RESIZED: + win = (window::Window *) Module::findInstance("love.window."); + if (win) + { + win->onWindowResize(e.window.data1, e.window.data2); + + graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics."); + if (gfx) + gfx->setViewportSize(e.window.data1, e.window.data2); + } + arg1 = new Variant((double) e.window.data1); + arg2 = new Variant((double) e.window.data2); msg = new Message("resize", arg1, arg2); arg1->release(); arg2->release(); @@ -156,162 +419,215 @@ Message *Event::convert(SDL_Event &e) return msg; } -EnumMap::Entry Event::keyEntries[] = +std::map Event::createKeyMap() { - { love::keyboard::Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE}, - { love::keyboard::Keyboard::KEY_TAB, SDLK_TAB}, - { love::keyboard::Keyboard::KEY_CLEAR, SDLK_CLEAR}, - { love::keyboard::Keyboard::KEY_RETURN, SDLK_RETURN}, - { love::keyboard::Keyboard::KEY_PAUSE, SDLK_PAUSE}, - { love::keyboard::Keyboard::KEY_ESCAPE, SDLK_ESCAPE }, - { love::keyboard::Keyboard::KEY_SPACE, SDLK_SPACE }, - { love::keyboard::Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM }, - { love::keyboard::Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL }, - { love::keyboard::Keyboard::KEY_HASH, SDLK_HASH }, - { love::keyboard::Keyboard::KEY_DOLLAR, SDLK_DOLLAR }, - { love::keyboard::Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND }, - { love::keyboard::Keyboard::KEY_QUOTE, SDLK_QUOTE }, - { love::keyboard::Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN }, - { love::keyboard::Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN }, - { love::keyboard::Keyboard::KEY_ASTERISK, SDLK_ASTERISK }, - { love::keyboard::Keyboard::KEY_PLUS, SDLK_PLUS }, - { love::keyboard::Keyboard::KEY_COMMA, SDLK_COMMA }, - { love::keyboard::Keyboard::KEY_MINUS, SDLK_MINUS }, - { love::keyboard::Keyboard::KEY_PERIOD, SDLK_PERIOD }, - { love::keyboard::Keyboard::KEY_SLASH, SDLK_SLASH }, - { love::keyboard::Keyboard::KEY_0, SDLK_0 }, - { love::keyboard::Keyboard::KEY_1, SDLK_1 }, - { love::keyboard::Keyboard::KEY_2, SDLK_2 }, - { love::keyboard::Keyboard::KEY_3, SDLK_3 }, - { love::keyboard::Keyboard::KEY_4, SDLK_4 }, - { love::keyboard::Keyboard::KEY_5, SDLK_5 }, - { love::keyboard::Keyboard::KEY_6, SDLK_6 }, - { love::keyboard::Keyboard::KEY_7, SDLK_7 }, - { love::keyboard::Keyboard::KEY_8, SDLK_8 }, - { love::keyboard::Keyboard::KEY_9, SDLK_9 }, - { love::keyboard::Keyboard::KEY_COLON, SDLK_COLON }, - { love::keyboard::Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON }, - { love::keyboard::Keyboard::KEY_LESS, SDLK_LESS }, - { love::keyboard::Keyboard::KEY_EQUALS, SDLK_EQUALS }, - { love::keyboard::Keyboard::KEY_GREATER, SDLK_GREATER }, - { love::keyboard::Keyboard::KEY_QUESTION, SDLK_QUESTION }, - { love::keyboard::Keyboard::KEY_AT, SDLK_AT }, + using love::keyboard::Keyboard; - { love::keyboard::Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET }, - { love::keyboard::Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH }, - { love::keyboard::Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET }, - { love::keyboard::Keyboard::KEY_CARET, SDLK_CARET }, - { love::keyboard::Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE }, - { love::keyboard::Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE }, - { love::keyboard::Keyboard::KEY_A, SDLK_a }, - { love::keyboard::Keyboard::KEY_B, SDLK_b }, - { love::keyboard::Keyboard::KEY_C, SDLK_c }, - { love::keyboard::Keyboard::KEY_D, SDLK_d }, - { love::keyboard::Keyboard::KEY_E, SDLK_e }, - { love::keyboard::Keyboard::KEY_F, SDLK_f }, - { love::keyboard::Keyboard::KEY_G, SDLK_g }, - { love::keyboard::Keyboard::KEY_H, SDLK_h }, - { love::keyboard::Keyboard::KEY_I, SDLK_i }, - { love::keyboard::Keyboard::KEY_J, SDLK_j }, - { love::keyboard::Keyboard::KEY_K, SDLK_k }, - { love::keyboard::Keyboard::KEY_L, SDLK_l }, - { love::keyboard::Keyboard::KEY_M, SDLK_m }, - { love::keyboard::Keyboard::KEY_N, SDLK_n }, - { love::keyboard::Keyboard::KEY_O, SDLK_o }, - { love::keyboard::Keyboard::KEY_P, SDLK_p }, - { love::keyboard::Keyboard::KEY_Q, SDLK_q }, - { love::keyboard::Keyboard::KEY_R, SDLK_r }, - { love::keyboard::Keyboard::KEY_S, SDLK_s }, - { love::keyboard::Keyboard::KEY_T, SDLK_t }, - { love::keyboard::Keyboard::KEY_U, SDLK_u }, - { love::keyboard::Keyboard::KEY_V, SDLK_v }, - { love::keyboard::Keyboard::KEY_W, SDLK_w }, - { love::keyboard::Keyboard::KEY_X, SDLK_x }, - { love::keyboard::Keyboard::KEY_Y, SDLK_y }, - { love::keyboard::Keyboard::KEY_Z, SDLK_z }, - { love::keyboard::Keyboard::KEY_DELETE, SDLK_DELETE }, + std::map k; - { love::keyboard::Keyboard::KEY_KP0, SDLK_KP0 }, - { love::keyboard::Keyboard::KEY_KP1, SDLK_KP1 }, - { love::keyboard::Keyboard::KEY_KP2, SDLK_KP2 }, - { love::keyboard::Keyboard::KEY_KP3, SDLK_KP3 }, - { love::keyboard::Keyboard::KEY_KP4, SDLK_KP4 }, - { love::keyboard::Keyboard::KEY_KP5, SDLK_KP5 }, - { love::keyboard::Keyboard::KEY_KP6, SDLK_KP6 }, - { love::keyboard::Keyboard::KEY_KP7, SDLK_KP7 }, - { love::keyboard::Keyboard::KEY_KP8, SDLK_KP8 }, - { love::keyboard::Keyboard::KEY_KP9, SDLK_KP9 }, - { love::keyboard::Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD }, - { love::keyboard::Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE }, - { love::keyboard::Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY}, - { love::keyboard::Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS }, - { love::keyboard::Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS }, - { love::keyboard::Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER }, - { love::keyboard::Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS }, + k[SDLK_UNKNOWN] = Keyboard::KEY_UNKNOWN; - { love::keyboard::Keyboard::KEY_UP, SDLK_UP }, - { love::keyboard::Keyboard::KEY_DOWN, SDLK_DOWN }, - { love::keyboard::Keyboard::KEY_RIGHT, SDLK_RIGHT }, - { love::keyboard::Keyboard::KEY_LEFT, SDLK_LEFT }, - { love::keyboard::Keyboard::KEY_INSERT, SDLK_INSERT }, - { love::keyboard::Keyboard::KEY_HOME, SDLK_HOME }, - { love::keyboard::Keyboard::KEY_END, SDLK_END }, - { love::keyboard::Keyboard::KEY_PAGEUP, SDLK_PAGEUP }, - { love::keyboard::Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN }, + k[SDLK_RETURN] = Keyboard::KEY_RETURN; + k[SDLK_ESCAPE] = Keyboard::KEY_ESCAPE; + k[SDLK_BACKSPACE] = Keyboard::KEY_BACKSPACE; + k[SDLK_TAB] = Keyboard::KEY_TAB; + k[SDLK_SPACE] = Keyboard::KEY_SPACE; + k[SDLK_EXCLAIM] = Keyboard::KEY_EXCLAIM; + k[SDLK_QUOTEDBL] = Keyboard::KEY_QUOTEDBL; + k[SDLK_HASH] = Keyboard::KEY_HASH; + k[SDLK_DOLLAR] = Keyboard::KEY_DOLLAR; + k[SDLK_AMPERSAND] = Keyboard::KEY_AMPERSAND; + k[SDLK_QUOTE] = Keyboard::KEY_QUOTE; + k[SDLK_LEFTPAREN] = Keyboard::KEY_LEFTPAREN; + k[SDLK_RIGHTPAREN] = Keyboard::KEY_RIGHTPAREN; + k[SDLK_ASTERISK] = Keyboard::KEY_ASTERISK; + k[SDLK_PLUS] = Keyboard::KEY_PLUS; + k[SDLK_COMMA] = Keyboard::KEY_COMMA; + k[SDLK_MINUS] = Keyboard::KEY_MINUS; + k[SDLK_PERIOD] = Keyboard::KEY_PERIOD; + k[SDLK_SLASH] = Keyboard::KEY_SLASH; + k[SDLK_0] = Keyboard::KEY_0; + k[SDLK_1] = Keyboard::KEY_1; + k[SDLK_2] = Keyboard::KEY_2; + k[SDLK_3] = Keyboard::KEY_3; + k[SDLK_4] = Keyboard::KEY_4; + k[SDLK_5] = Keyboard::KEY_5; + k[SDLK_6] = Keyboard::KEY_6; + k[SDLK_7] = Keyboard::KEY_7; + k[SDLK_8] = Keyboard::KEY_8; + k[SDLK_9] = Keyboard::KEY_9; + k[SDLK_COLON] = Keyboard::KEY_COLON; + k[SDLK_SEMICOLON] = Keyboard::KEY_SEMICOLON; + k[SDLK_LESS] = Keyboard::KEY_LESS; + k[SDLK_EQUALS] = Keyboard::KEY_EQUALS; + k[SDLK_GREATER] = Keyboard::KEY_GREATER; + k[SDLK_QUESTION] = Keyboard::KEY_QUESTION; + k[SDLK_AT] = Keyboard::KEY_AT; - { love::keyboard::Keyboard::KEY_F1, SDLK_F1 }, - { love::keyboard::Keyboard::KEY_F2, SDLK_F2 }, - { love::keyboard::Keyboard::KEY_F3, SDLK_F3 }, - { love::keyboard::Keyboard::KEY_F4, SDLK_F4 }, - { love::keyboard::Keyboard::KEY_F5, SDLK_F5 }, - { love::keyboard::Keyboard::KEY_F6, SDLK_F6 }, - { love::keyboard::Keyboard::KEY_F7, SDLK_F7 }, - { love::keyboard::Keyboard::KEY_F8, SDLK_F8 }, - { love::keyboard::Keyboard::KEY_F9, SDLK_F9 }, - { love::keyboard::Keyboard::KEY_F10, SDLK_F10 }, - { love::keyboard::Keyboard::KEY_F11, SDLK_F11 }, - { love::keyboard::Keyboard::KEY_F12, SDLK_F12 }, - { love::keyboard::Keyboard::KEY_F13, SDLK_F13 }, - { love::keyboard::Keyboard::KEY_F14, SDLK_F14 }, - { love::keyboard::Keyboard::KEY_F15, SDLK_F15 }, + k[SDLK_LEFTBRACKET] = Keyboard::KEY_LEFTBRACKET; + k[SDLK_BACKSLASH] = Keyboard::KEY_BACKSLASH; + k[SDLK_RIGHTBRACKET] = Keyboard::KEY_RIGHTBRACKET; + k[SDLK_CARET] = Keyboard::KEY_CARET; + k[SDLK_UNDERSCORE] = Keyboard::KEY_UNDERSCORE; + k[SDLK_BACKQUOTE] = Keyboard::KEY_BACKQUOTE; + k[SDLK_a] = Keyboard::KEY_A; + k[SDLK_b] = Keyboard::KEY_B; + k[SDLK_c] = Keyboard::KEY_C; + k[SDLK_d] = Keyboard::KEY_D; + k[SDLK_e] = Keyboard::KEY_E; + k[SDLK_f] = Keyboard::KEY_F; + k[SDLK_g] = Keyboard::KEY_G; + k[SDLK_h] = Keyboard::KEY_H; + k[SDLK_i] = Keyboard::KEY_I; + k[SDLK_j] = Keyboard::KEY_J; + k[SDLK_k] = Keyboard::KEY_K; + k[SDLK_l] = Keyboard::KEY_L; + k[SDLK_m] = Keyboard::KEY_M; + k[SDLK_n] = Keyboard::KEY_N; + k[SDLK_o] = Keyboard::KEY_O; + k[SDLK_p] = Keyboard::KEY_P; + k[SDLK_q] = Keyboard::KEY_Q; + k[SDLK_r] = Keyboard::KEY_R; + k[SDLK_s] = Keyboard::KEY_S; + k[SDLK_t] = Keyboard::KEY_T; + k[SDLK_u] = Keyboard::KEY_U; + k[SDLK_v] = Keyboard::KEY_V; + k[SDLK_w] = Keyboard::KEY_W; + k[SDLK_x] = Keyboard::KEY_X; + k[SDLK_y] = Keyboard::KEY_Y; + k[SDLK_z] = Keyboard::KEY_Z; - { love::keyboard::Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK }, - { love::keyboard::Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK }, - { love::keyboard::Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK }, - { love::keyboard::Keyboard::KEY_RSHIFT, SDLK_RSHIFT }, - { love::keyboard::Keyboard::KEY_LSHIFT, SDLK_LSHIFT }, - { love::keyboard::Keyboard::KEY_RCTRL, SDLK_RCTRL }, - { love::keyboard::Keyboard::KEY_LCTRL, SDLK_LCTRL }, - { love::keyboard::Keyboard::KEY_RALT, SDLK_RALT }, - { love::keyboard::Keyboard::KEY_LALT, SDLK_LALT }, - { love::keyboard::Keyboard::KEY_RMETA, SDLK_RMETA }, - { love::keyboard::Keyboard::KEY_LMETA, SDLK_LMETA }, - { love::keyboard::Keyboard::KEY_LSUPER, SDLK_LSUPER }, - { love::keyboard::Keyboard::KEY_RSUPER, SDLK_RSUPER }, - { love::keyboard::Keyboard::KEY_MODE, SDLK_MODE }, - { love::keyboard::Keyboard::KEY_COMPOSE, SDLK_COMPOSE }, + k[SDLK_CAPSLOCK] = Keyboard::KEY_CAPSLOCK; - { love::keyboard::Keyboard::KEY_HELP, SDLK_HELP }, - { love::keyboard::Keyboard::KEY_PRINT, SDLK_PRINT }, - { love::keyboard::Keyboard::KEY_SYSREQ, SDLK_SYSREQ }, - { love::keyboard::Keyboard::KEY_BREAK, SDLK_BREAK }, - { love::keyboard::Keyboard::KEY_MENU, SDLK_MENU }, - { love::keyboard::Keyboard::KEY_POWER, SDLK_POWER }, - { love::keyboard::Keyboard::KEY_EURO, SDLK_EURO }, - { love::keyboard::Keyboard::KEY_UNDO, SDLK_UNDO }, + k[SDLK_F1] = Keyboard::KEY_F1; + k[SDLK_F2] = Keyboard::KEY_F2; + k[SDLK_F3] = Keyboard::KEY_F3; + k[SDLK_F4] = Keyboard::KEY_F4; + k[SDLK_F5] = Keyboard::KEY_F5; + k[SDLK_F6] = Keyboard::KEY_F6; + k[SDLK_F7] = Keyboard::KEY_F7; + k[SDLK_F8] = Keyboard::KEY_F8; + k[SDLK_F9] = Keyboard::KEY_F9; + k[SDLK_F10] = Keyboard::KEY_F10; + k[SDLK_F11] = Keyboard::KEY_F11; + k[SDLK_F12] = Keyboard::KEY_F12; - { love::keyboard::Keyboard::KEY_UNKNOWN, SDLK_UNKNOWN }, -}; + k[SDLK_PRINTSCREEN] = Keyboard::KEY_PRINTSCREEN; + k[SDLK_SCROLLLOCK] = Keyboard::KEY_SCROLLLOCK; + k[SDLK_PAUSE] = Keyboard::KEY_PAUSE; + k[SDLK_INSERT] = Keyboard::KEY_INSERT; + k[SDLK_HOME] = Keyboard::KEY_HOME; + k[SDLK_PAGEUP] = Keyboard::KEY_PAGEUP; + k[SDLK_DELETE] = Keyboard::KEY_DELETE; + k[SDLK_END] = Keyboard::KEY_END; + k[SDLK_PAGEDOWN] = Keyboard::KEY_PAGEDOWN; + k[SDLK_RIGHT] = Keyboard::KEY_RIGHT; + k[SDLK_LEFT] = Keyboard::KEY_LEFT; + k[SDLK_DOWN] = Keyboard::KEY_DOWN; + k[SDLK_UP] = Keyboard::KEY_UP; -EnumMap Event::keys(Event::keyEntries, sizeof(Event::keyEntries)); + k[SDLK_NUMLOCKCLEAR] = Keyboard::KEY_NUMLOCKCLEAR; + k[SDLK_KP_DIVIDE] = Keyboard::KEY_KP_DIVIDE; + k[SDLK_KP_MULTIPLY] = Keyboard::KEY_KP_MULTIPLY; + k[SDLK_KP_MINUS] = Keyboard::KEY_KP_MINUS; + k[SDLK_KP_PLUS] = Keyboard::KEY_KP_PLUS; + k[SDLK_KP_ENTER] = Keyboard::KEY_KP_ENTER; + k[SDLK_KP_0] = Keyboard::KEY_KP_0; + k[SDLK_KP_1] = Keyboard::KEY_KP_1; + k[SDLK_KP_2] = Keyboard::KEY_KP_2; + k[SDLK_KP_3] = Keyboard::KEY_KP_3; + k[SDLK_KP_4] = Keyboard::KEY_KP_4; + k[SDLK_KP_5] = Keyboard::KEY_KP_5; + k[SDLK_KP_6] = Keyboard::KEY_KP_6; + k[SDLK_KP_7] = Keyboard::KEY_KP_7; + k[SDLK_KP_8] = Keyboard::KEY_KP_8; + k[SDLK_KP_9] = Keyboard::KEY_KP_9; + k[SDLK_KP_PERIOD] = Keyboard::KEY_KP_PERIOD; + k[SDLK_KP_COMMA] = Keyboard::KEY_KP_COMMA; + k[SDLK_KP_EQUALS] = Keyboard::KEY_KP_EQUALS; + + k[SDLK_APPLICATION] = Keyboard::KEY_APPLICATION; + k[SDLK_POWER] = Keyboard::KEY_POWER; + k[SDLK_F13] = Keyboard::KEY_F13; + k[SDLK_F14] = Keyboard::KEY_F14; + k[SDLK_F15] = Keyboard::KEY_F15; + k[SDLK_F16] = Keyboard::KEY_F16; + k[SDLK_F17] = Keyboard::KEY_F17; + k[SDLK_F18] = Keyboard::KEY_F18; + k[SDLK_F19] = Keyboard::KEY_F19; + k[SDLK_F20] = Keyboard::KEY_F20; + k[SDLK_F21] = Keyboard::KEY_F21; + k[SDLK_F22] = Keyboard::KEY_F22; + k[SDLK_F23] = Keyboard::KEY_F23; + k[SDLK_F24] = Keyboard::KEY_F24; + k[SDLK_EXECUTE] = Keyboard::KEY_EXECUTE; + k[SDLK_HELP] = Keyboard::KEY_HELP; + k[SDLK_MENU] = Keyboard::KEY_MENU; + k[SDLK_SELECT] = Keyboard::KEY_SELECT; + k[SDLK_STOP] = Keyboard::KEY_STOP; + k[SDLK_AGAIN] = Keyboard::KEY_AGAIN; + k[SDLK_UNDO] = Keyboard::KEY_UNDO; + k[SDLK_CUT] = Keyboard::KEY_CUT; + k[SDLK_COPY] = Keyboard::KEY_COPY; + k[SDLK_PASTE] = Keyboard::KEY_PASTE; + k[SDLK_FIND] = Keyboard::KEY_FIND; + k[SDLK_MUTE] = Keyboard::KEY_MUTE; + k[SDLK_VOLUMEUP] = Keyboard::KEY_VOLUMEUP; + k[SDLK_VOLUMEDOWN] = Keyboard::KEY_VOLUMEDOWN; + + k[SDLK_ALTERASE] = Keyboard::KEY_ALTERASE; + k[SDLK_SYSREQ] = Keyboard::KEY_SYSREQ; + k[SDLK_CANCEL] = Keyboard::KEY_CANCEL; + k[SDLK_CLEAR] = Keyboard::KEY_CLEAR; + k[SDLK_PRIOR] = Keyboard::KEY_PRIOR; + k[SDLK_RETURN2] = Keyboard::KEY_RETURN2; + k[SDLK_SEPARATOR] = Keyboard::KEY_SEPARATOR; + k[SDLK_OUT] = Keyboard::KEY_OUT; + k[SDLK_OPER] = Keyboard::KEY_OPER; + k[SDLK_CLEARAGAIN] = Keyboard::KEY_CLEARAGAIN; + + k[SDLK_THOUSANDSSEPARATOR] = Keyboard::KEY_THOUSANDSSEPARATOR; + k[SDLK_DECIMALSEPARATOR] = Keyboard::KEY_DECIMALSEPARATOR; + k[SDLK_CURRENCYUNIT] = Keyboard::KEY_CURRENCYUNIT; + k[SDLK_CURRENCYSUBUNIT] = Keyboard::KEY_CURRENCYSUBUNIT; + + k[SDLK_LCTRL] = Keyboard::KEY_LCTRL; + k[SDLK_LSHIFT] = Keyboard::KEY_LSHIFT; + k[SDLK_LALT] = Keyboard::KEY_LALT; + k[SDLK_LGUI] = Keyboard::KEY_LGUI; + k[SDLK_RCTRL] = Keyboard::KEY_RCTRL; + k[SDLK_RSHIFT] = Keyboard::KEY_RSHIFT; + k[SDLK_RALT] = Keyboard::KEY_RALT; + k[SDLK_RGUI] = Keyboard::KEY_RGUI; + + k[SDLK_MODE] = Keyboard::KEY_MODE; + + k[SDLK_AUDIONEXT] = Keyboard::KEY_AUDIONEXT; + k[SDLK_AUDIOPREV] = Keyboard::KEY_AUDIOPREV; + k[SDLK_AUDIOSTOP] = Keyboard::KEY_AUDIOSTOP; + k[SDLK_AUDIOPLAY] = Keyboard::KEY_AUDIOPLAY; + k[SDLK_AUDIOMUTE] = Keyboard::KEY_AUDIOMUTE; + k[SDLK_MEDIASELECT] = Keyboard::KEY_MEDIASELECT; + + k[SDLK_BRIGHTNESSDOWN] = Keyboard::KEY_BRIGHTNESSDOWN; + k[SDLK_BRIGHTNESSUP] = Keyboard::KEY_BRIGHTNESSUP; + k[SDLK_DISPLAYSWITCH] = Keyboard::KEY_DISPLAYSWITCH; + k[SDLK_KBDILLUMTOGGLE] = Keyboard::KEY_KBDILLUMTOGGLE; + k[SDLK_KBDILLUMDOWN] = Keyboard::KEY_KBDILLUMDOWN; + k[SDLK_KBDILLUMUP] = Keyboard::KEY_KBDILLUMUP; + k[SDLK_EJECT] = Keyboard::KEY_EJECT; + k[SDLK_SLEEP] = Keyboard::KEY_SLEEP; + + return k; +} + +std::map Event::keys = Event::createKeyMap(); EnumMap::Entry Event::buttonEntries[] = { { love::mouse::Mouse::BUTTON_LEFT, SDL_BUTTON_LEFT}, { love::mouse::Mouse::BUTTON_MIDDLE, SDL_BUTTON_MIDDLE}, { love::mouse::Mouse::BUTTON_RIGHT, SDL_BUTTON_RIGHT}, - { love::mouse::Mouse::BUTTON_WHEELUP, SDL_BUTTON_WHEELUP}, - { love::mouse::Mouse::BUTTON_WHEELDOWN, SDL_BUTTON_WHEELDOWN}, { love::mouse::Mouse::BUTTON_X1, SDL_BUTTON_X1}, { love::mouse::Mouse::BUTTON_X2, SDL_BUTTON_X2}, }; diff --git a/src/modules/event/sdl/Event.h b/src/modules/event/sdl/Event.h index 177ba6271..7b8df4ac4 100644 --- a/src/modules/event/sdl/Event.h +++ b/src/modules/event/sdl/Event.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,6 +29,9 @@ // SDL #include +// STL +#include + namespace love { namespace event @@ -44,6 +47,7 @@ public: const char *getName() const; Event(); + virtual ~Event(); /** * Pumps the event queue. This function gathers all the pending input information @@ -66,10 +70,13 @@ public: private: - Message *convert(SDL_Event &e); + Message *convert(const SDL_Event &e) const; + Message *convertJoystickEvent(const SDL_Event &e) const; + Message *convertWindowEvent(const SDL_Event &e) const; + + static std::map createKeyMap(); + static std::map keys; - static EnumMap::Entry keyEntries[]; - static EnumMap keys; static EnumMap::Entry buttonEntries[]; static EnumMap buttons; diff --git a/src/modules/event/sdl/wrap_Event.cpp b/src/modules/event/sdl/wrap_Event.cpp index 5a516f397..f33bd6619 100644 --- a/src/modules/event/sdl/wrap_Event.cpp +++ b/src/modules/event/sdl/wrap_Event.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -64,7 +64,7 @@ int w_poll(lua_State *L) int w_wait(lua_State *L) { - static Message *m; + Message *m; if ((m = instance->wait())) { @@ -78,7 +78,7 @@ int w_wait(lua_State *L) int w_push(lua_State *L) { - static Message *m; + Message *m; bool success = (m = Message::fromLua(L, 1)) != NULL; luax_pushboolean(L, success); @@ -123,14 +123,7 @@ extern "C" int luaopen_love_event(lua_State *L) { if (instance == 0) { - try - { - instance = new Event(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new Event();) } else instance->retain(); diff --git a/src/modules/event/sdl/wrap_Event.h b/src/modules/event/sdl/wrap_Event.h index 66de0e2b8..b689335a3 100644 --- a/src/modules/event/sdl/wrap_Event.h +++ b/src/modules/event/sdl/wrap_Event.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/filesystem/File.cpp b/src/modules/filesystem/File.cpp index 806cbd6d8..ef20621d7 100644 --- a/src/modules/filesystem/File.cpp +++ b/src/modules/filesystem/File.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -34,11 +34,21 @@ bool File::getConstant(const char *in, Mode &out) return modes.find(in, out); } -bool File::getConstant(Mode in, const char *&out) +bool File::getConstant(Mode in, const char *&out) { return modes.find(in, out); } +bool File::getConstant(const char *in, BufferMode &out) +{ + return bufferModes.find(in, out); +} + +bool File::getConstant(BufferMode in, const char *&out) +{ + return bufferModes.find(in, out); +} + StringMap::Entry File::modeEntries[] = { {"c", File::CLOSED}, @@ -49,5 +59,14 @@ StringMap::Entry File::modeEntries[] = StringMap File::modes(File::modeEntries, sizeof(File::modeEntries)); +StringMap::Entry File::bufferModeEntries[] = +{ + {"none", File::BUFFER_NONE}, + {"line", File::BUFFER_LINE}, + {"full", File::BUFFER_FULL}, +}; + +StringMap File::bufferModes(File::bufferModeEntries, sizeof(File::bufferModeEntries)); + } // filesystem } // love diff --git a/src/modules/filesystem/File.h b/src/modules/filesystem/File.h index 1c4d66d2a..e0be859e4 100644 --- a/src/modules/filesystem/File.h +++ b/src/modules/filesystem/File.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -56,6 +56,14 @@ public: MODE_MAX_ENUM }; + enum BufferMode + { + BUFFER_NONE, + BUFFER_LINE, + BUFFER_FULL, + BUFFER_MAX_ENUM + }; + /** * Used to indicate ALL data in a file. **/ @@ -81,6 +89,11 @@ public: **/ virtual bool close() = 0; + /** + * Gets whether the file is open. + **/ + virtual bool isOpen() const = 0; + /** * Gets the size of the file. * @@ -123,6 +136,12 @@ public: **/ virtual bool write(const Data *data, int64 size = ALL) = 0; + /** + * Flushes the currently buffered file data to disk. Only applicable in + * write mode. + **/ + virtual bool flush() = 0; + /** * Checks whether we are currently at end-of-file. * @@ -145,11 +164,29 @@ public: **/ virtual bool seek(uint64 pos) = 0; + /** + * Sets the buffering mode for the file. When buffering is enabled, the file + * will not write to disk (or will pre-load data if in read mode) until the + * buffer's capacity is reached. + * In the BUFFER_LINE mode, the file will also write to disk if a newline is + * written. + * + * @param bufmode The buffer mode. + * @param size The size in bytes of the buffer. + **/ + virtual bool setBuffer(BufferMode bufmode, int64 size) = 0; + + /** + * @param[out] size The size in bytes of the buffer. + * @return The current buffer mode. + **/ + virtual BufferMode getBuffer(int64 &size) const = 0; + /** * Gets the current mode of the File. * @return The current mode of the File; CLOSED, READ, WRITE or APPEND. **/ - virtual Mode getMode() = 0; + virtual Mode getMode() const = 0; /** * Gets the filename for this File, or empty string if none. @@ -164,13 +201,19 @@ public: virtual std::string getExtension() const = 0; static bool getConstant(const char *in, Mode &out); - static bool getConstant(Mode in, const char *&out); + static bool getConstant(Mode in, const char *&out); + + static bool getConstant(const char *in, BufferMode &out); + static bool getConstant(BufferMode in, const char *&out); private: static StringMap::Entry modeEntries[]; static StringMap modes; + static StringMap::Entry bufferModeEntries[]; + static StringMap bufferModes; + }; // File } // filesystem diff --git a/src/modules/filesystem/FileData.cpp b/src/modules/filesystem/FileData.cpp index dc3fab5f1..dd59c73e9 100644 --- a/src/modules/filesystem/FileData.cpp +++ b/src/modules/filesystem/FileData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/filesystem/FileData.h b/src/modules/filesystem/FileData.h index 8712e597b..e74866be5 100644 --- a/src/modules/filesystem/FileData.h +++ b/src/modules/filesystem/FileData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/filesystem/physfs/File.cpp b/src/modules/filesystem/physfs/File.cpp index 5ceb97680..ce2ac50eb 100644 --- a/src/modules/filesystem/physfs/File.cpp +++ b/src/modules/filesystem/physfs/File.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,10 +36,12 @@ namespace physfs extern bool hack_setupWriteDirectory(); -File::File(std::string filename) +File::File(const std::string &filename) : filename(filename) , file(0) - , mode(filesystem::File::CLOSED) + , mode(CLOSED) + , bufferMode(BUFFER_NONE) + , bufferSize(0) { } @@ -83,6 +85,13 @@ bool File::open(Mode mode) break; } + if (file != 0 && !setBuffer(bufferMode, bufferSize)) + { + // Revert to buffer defaults if we don't successfully set the buffer. + bufferMode = BUFFER_NONE; + bufferSize = 0; + } + return (file != 0); } @@ -95,6 +104,11 @@ bool File::close() return true; } +bool File::isOpen() const +{ + return mode != CLOSED && file != 0; +} + int64 File::getSize() { // If the file is closed, open it to @@ -122,6 +136,9 @@ FileData *File::read(int64 size) int64 cur = tell(); size = (size == ALL) ? max : size; + if (size < 0) + throw love::Exception("Invalid read size."); + // Clamping because the file offset may be in a weird position. if (cur < 0) cur = 0; @@ -155,10 +172,8 @@ FileData *File::read(int64 size) int64 File::read(void *dst, int64 size) { - bool isOpen = (file != 0); - - if (!isOpen) - open(READ); + if (!file || mode != READ) + throw love::Exception("File is not opened for reading."); int64 max = (int64)PHYSFS_fileLength(file); size = (size == ALL) ? max : size; @@ -166,29 +181,39 @@ int64 File::read(void *dst, int64 size) // Sadly, we'll have to clamp to 32 bits here size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; - int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size); + if (size < 0) + throw love::Exception("Invalid read size."); - if (!isOpen) - close(); + int64 read = (int64)PHYSFS_read(file, dst, 1, (PHYSFS_uint32) size); return read; } bool File::write(const void *data, int64 size) { - if (file == 0) - throw love::Exception("Could not write to file. File not open."); + if (!file || (mode != WRITE && mode != APPEND)) + throw love::Exception("File is not opened for writing."); // Another clamp, for the time being. size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; + if (size < 0) + throw love::Exception("Invalid write size."); + // Try to write. - int64 written = static_cast(PHYSFS_write(file, data, 1, (int) size)); + int64 written = static_cast(PHYSFS_write(file, data, 1, (PHYSFS_uint32) size)); // Check that correct amount of data was written. if (written != size) return false; + // Manually flush the buffer in BUFFER_LINE mode if we find a newline. + if (bufferMode == BUFFER_LINE && bufferSize > size) + { + if (memchr(data, '\n', (size_t) size) != NULL) + flush(); + } + return true; } @@ -197,6 +222,14 @@ bool File::write(const Data *data, int64 size) return write(data->getData(), (size == ALL) ? data->getSize() : size); } +bool File::flush() +{ + if (!file || (mode != WRITE && mode != APPEND)) + throw love::Exception("File is not opened for writing."); + + return PHYSFS_flush(file) != 0; +} + #ifdef LOVE_WINDOWS // MSVC doesn't like the 'this' keyword // well, we'll use 'that'. @@ -226,7 +259,7 @@ int64 File::tell() if (file == 0) return -1; - return (int64)PHYSFS_tell(file); + return (int64) PHYSFS_tell(file); } bool File::seek(uint64 pos) @@ -234,11 +267,56 @@ bool File::seek(uint64 pos) if (file == 0) return false; - if (!PHYSFS_seek(file, (PHYSFS_uint64)pos)) + if (!PHYSFS_seek(file, (PHYSFS_uint64) pos)) return false; return true; } +bool File::setBuffer(BufferMode bufmode, int64 size) +{ + // No negativity allowed! + if (size < 0) + return false; + + // If the file isn't open, we'll make sure the buffer values are set in + // File::open. + if (file == 0 || mode == CLOSED) + { + bufferMode = bufmode; + bufferSize = size; + return true; + } + + int ret = 1; + + switch (bufmode) + { + case BUFFER_NONE: + default: + ret = PHYSFS_setBuffer(file, 0); + size = 0; + break; + case BUFFER_LINE: + case BUFFER_FULL: + ret = PHYSFS_setBuffer(file, size); + break; + } + + if (ret == 0) + return false; + + bufferMode = bufmode; + bufferSize = size; + + return true; +} + +File::BufferMode File::getBuffer(int64 &size) const +{ + size = bufferSize; + return bufferMode; +} + std::string File::getFilename() const { return filename; @@ -254,7 +332,7 @@ std::string File::getExtension() const return std::string(); } -filesystem::File::Mode File::getMode() +filesystem::File::Mode File::getMode() const { return mode; } diff --git a/src/modules/filesystem/physfs/File.h b/src/modules/filesystem/physfs/File.h index 29ea243c2..a3fe33792 100644 --- a/src/modules/filesystem/physfs/File.h +++ b/src/modules/filesystem/physfs/File.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -25,7 +25,7 @@ #include "filesystem/File.h" // PhysFS -#ifdef LOVE_MACOSX // wacky Mac behavior means different #include syntax! +#ifdef LOVE_MACOSX_USE_FRAMEWORKS #include #else #include @@ -43,43 +43,49 @@ namespace physfs class File : public love::filesystem::File { -private: - - // filename - std::string filename; - - // PHYSFS File handle. - PHYSFS_file *file; - - // The current mode of the file. - Mode mode; - public: /** - * Constructs an File with the given source and filename. - * @param source The source from which to load the file. (Archive or directory) - * @param filename The relative filepath of the file to load from the source. + * Constructs an File with the given ilename. + * @param filename The relative filepath of the file to load. **/ - File(std::string filename); + File(const std::string &filename); virtual ~File(); // Implements love::filesystem::File. bool open(Mode mode); bool close(); + bool isOpen() const; int64 getSize(); FileData *read(int64 size = ALL); int64 read(void *dst, int64 size); bool write(const void *data, int64 size); bool write(const Data *data, int64 size = ALL); + bool flush(); bool eof(); int64 tell(); bool seek(uint64 pos); - Mode getMode(); + bool setBuffer(BufferMode bufmode, int64 size); + BufferMode getBuffer(int64 &size) const; + Mode getMode() const; std::string getFilename() const; std::string getExtension() const; +private: + + // filename + std::string filename; + + // PHYSFS File handle. + PHYSFS_File *file; + + // The current mode of the file. + Mode mode; + + BufferMode bufferMode; + int64 bufferSize; + }; // File } // physfs diff --git a/src/modules/filesystem/physfs/Filesystem.cpp b/src/modules/filesystem/physfs/Filesystem.cpp index e9f63d236..25e4efbc9 100644 --- a/src/modules/filesystem/physfs/Filesystem.cpp +++ b/src/modules/filesystem/physfs/Filesystem.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -27,6 +27,28 @@ #include "Filesystem.h" +namespace +{ + size_t getDriveDelim(const std::string &input) + { + for (size_t i = 0; i < input.size(); ++i) + if (input[i] == '/' || input[i] == '\\') + return i; + // Something's horribly wrong + return 0; + } + + std::string getDriveRoot(const std::string &input) + { + return input.substr(0, getDriveDelim(input)+1); + } + + std::string skipDriveRoot(const std::string &input) + { + return input.substr(getDriveDelim(input)+1); + } +} + namespace love { namespace filesystem @@ -35,21 +57,16 @@ namespace physfs { Filesystem::Filesystem() - : open_count(0) - , buffer(0) - , isInited(false) - , release(false) - , releaseSet(false) + : initialized(false) + , fused(false) + , fusedSet(false) { } Filesystem::~Filesystem() { - if (isInited) - { - isInited = false; + if (initialized) PHYSFS_deinit(); - } } const char *Filesystem::getName() const @@ -61,29 +78,31 @@ void Filesystem::init(const char *arg0) { if (!PHYSFS_init(arg0)) throw Exception(PHYSFS_getLastError()); - isInited = true; + initialized = true; } -void Filesystem::setRelease(bool release) +void Filesystem::setFused(bool fused) { - if (releaseSet) + if (fusedSet) return; - this->release = release; - releaseSet = true; + this->fused = fused; + fusedSet = true; } -bool Filesystem::isRelease() const +bool Filesystem::isFused() const { - if (!releaseSet) + if (!fusedSet) return false; - return release; + return fused; } -bool Filesystem::setIdentity(const char *ident) +bool Filesystem::setIdentity(const char *ident, bool appendToPath) { - if (!isInited) + if (!initialized) return false; + std::string old_save_path = save_path_full; + // Store the save directory. save_identity = std::string(ident); @@ -92,7 +111,7 @@ bool Filesystem::setIdentity(const char *ident) // Generate the full path to the game save folder. save_path_full = std::string(getAppdataDirectory()) + std::string(LOVE_PATH_SEPARATOR); - if (release) + if (fused) save_path_full += std::string(LOVE_APPDATA_PREFIX) + save_identity; else save_path_full += save_path_relative; @@ -102,9 +121,14 @@ bool Filesystem::setIdentity(const char *ident) // save_path_relative: ./LOVE/game // save_path_full: C:\Documents and Settings\user\Application Data/LOVE/game + // We don't want old read-only save paths to accumulate when we set a new + // identity. + if (!old_save_path.empty()) + PHYSFS_removeFromSearchPath(old_save_path.c_str()); + // Try to add the save directory to the search path. // (No error on fail, it means that the path doesn't exist). - PHYSFS_addToSearchPath(save_path_full.c_str(), 0); + PHYSFS_addToSearchPath(save_path_full.c_str(), appendToPath); return true; } @@ -116,7 +140,7 @@ const char *Filesystem::getIdentity() const bool Filesystem::setSource(const char *source) { - if (!isInited) + if (!initialized) return false; // Check whether directory is already set. @@ -133,9 +157,14 @@ bool Filesystem::setSource(const char *source) return true; } +const char *Filesystem::getSource() const +{ + return game_source.c_str(); +} + bool Filesystem::setupWriteDirectory() { - if (!isInited) + if (!initialized) return false; // These must all be set. @@ -144,19 +173,14 @@ bool Filesystem::setupWriteDirectory() // Set the appdata folder as writable directory. // (We must create the save folder before mounting it). - if (!PHYSFS_setWriteDir(getAppdataDirectory())) + if (!PHYSFS_setWriteDir(getDriveRoot(save_path_full).c_str())) return false; // Create the save folder. (We're now "at" %APPDATA%). - bool success = false; - if (release) - success = mkdir(save_identity.c_str()); - else - success = mkdir(save_path_relative.c_str()); - - if (!success) + if (!createDirectory(skipDriveRoot(save_path_full).c_str())) { - PHYSFS_setWriteDir(0); // Clear the write directory in case of error. + // Clear the write directory in case of error. + PHYSFS_setWriteDir(0); return false; } @@ -174,12 +198,89 @@ bool Filesystem::setupWriteDirectory() return true; } -File *Filesystem::newFile(const char *filename) +bool Filesystem::mount(const char *archive, const char *mountpoint, bool appendToPath) +{ + if (!initialized || !archive) + return false; + + std::string realPath; + std::string sourceBase = getSourceBaseDirectory(); + + if (isFused() && sourceBase.compare(archive) == 0) + { + // Special case: if the game is fused and the archive is the source's + // base directory, mount it even though it's outside of the save dir. + realPath = sourceBase; + } + else + { + // Not allowed for safety reasons. + if (strlen(archive) == 0 || strstr(archive, "..") || strcmp(archive, "/") == 0) + return false; + + const char *realDir = PHYSFS_getRealDir(archive); + if (!realDir) + return false; + + realPath = realDir; + + // Always disallow mounting of files inside the game source, since it + // won't work anyway if the game source is a zipped .love file. + if (realPath.find(game_source) == 0) + return false; + + realPath += LOVE_PATH_SEPARATOR; + realPath += archive; + } + + if (realPath.length() == 0) + return false; + + return PHYSFS_mount(realPath.c_str(), mountpoint, appendToPath); +} + +bool Filesystem::unmount(const char *archive) +{ + if (!initialized || !archive) + return false; + + std::string realPath; + std::string sourceBase = getSourceBaseDirectory(); + + if (isFused() && sourceBase.compare(archive) == 0) + { + // Special case: if the game is fused and the archive is the source's + // base directory, unmount it even though it's outside of the save dir. + realPath = sourceBase; + } + else + { + // Not allowed for safety reasons. + if (strlen(archive) == 0 || strstr(archive, "..") || strcmp(archive, "/") == 0) + return false; + + const char *realDir = PHYSFS_getRealDir(archive); + if (!realDir) + return false; + + realPath = realDir; + realPath += LOVE_PATH_SEPARATOR; + realPath += archive; + } + + const char *mountPoint = PHYSFS_getMountPoint(realPath.c_str()); + if (!mountPoint) + return false; + + return PHYSFS_removeFromSearchPath(realPath.c_str()); +} + +File *Filesystem::newFile(const char *filename) const { return new File(filename); } -FileData *Filesystem::newFileData(void *data, unsigned int size, const char *filename) +FileData *Filesystem::newFileData(void *data, unsigned int size, const char *filename) const { FileData *fd = new FileData(size, std::string(filename)); @@ -189,7 +290,7 @@ FileData *Filesystem::newFileData(void *data, unsigned int size, const char *fil return fd; } -FileData *Filesystem::newFileData(const char *b64, const char *filename) +FileData *Filesystem::newFileData(const char *b64, const char *filename) const { int size = strlen(b64); int outsize = 0; @@ -270,31 +371,53 @@ const char *Filesystem::getSaveDirectory() return save_path_full.c_str(); } -bool Filesystem::exists(const char *file) +std::string Filesystem::getSourceBaseDirectory() const { - if (PHYSFS_exists(file)) - return true; - return false; + size_t source_len = game_source.length(); + + if (source_len == 0) + return ""; + + // FIXME: This doesn't take into account parent and current directory + // symbols (i.e. '..' and '.') +#ifdef LOVE_WINDOWS + // In windows, delimiters can be either '/' or '\'. + size_t base_end_pos = game_source.find_last_of("/\\", source_len - 2); +#else + size_t base_end_pos = game_source.find_last_of('/', source_len - 2); +#endif + + if (base_end_pos == std::string::npos) + return ""; + + // If the source is in the unix root (aka '/'), we want to keep the '/'. + if (base_end_pos == 0) + base_end_pos = 1; + + return game_source.substr(0, base_end_pos); } -bool Filesystem::isDirectory(const char *file) +bool Filesystem::exists(const char *file) const { - if (PHYSFS_isDirectory(file)) - return true; - return false; + return PHYSFS_exists(file); } -bool Filesystem::isFile(const char *file) +bool Filesystem::isDirectory(const char *file) const +{ + return PHYSFS_isDirectory(file); +} + +bool Filesystem::isFile(const char *file) const { return exists(file) && !isDirectory(file); } -bool Filesystem::mkdir(const char *file) +bool Filesystem::createDirectory(const char *dir) { if (PHYSFS_getWriteDir() == 0 && !setupWriteDirectory()) return false; - if (!PHYSFS_mkdir(file)) + if (!PHYSFS_mkdir(dir)) return false; return true; } @@ -309,144 +432,51 @@ bool Filesystem::remove(const char *file) return true; } -int Filesystem::read(lua_State *L) +Data *Filesystem::read(const char *filename, int64 size) const { - // The file to read from. The file must either be created - // on-the-fly, or passed as a parameter. - File *file; + File file(filename); - if (lua_isstring(L, 1)) - { - // Create the file. - file = newFile(lua_tostring(L, 1)); - } - else - return luaL_error(L, "Expected filename."); + file.open(File::READ); - // Optionally, the caller can specify whether to read - // the whole file, or just a part of it. - int count = luaL_optint(L, 2, (lua_Integer)file->getSize()); // FIXME - - // Read the data. - Data *data = file->read(count); - - // Error check. - if (data == 0) - return luaL_error(L, "File could not be read."); - - // Close and delete the file, if we created it. - // (I.e. if the first parameter is a string). - if (lua_isstring(L, 1)) - file->release(); - - // Push the string. - lua_pushlstring(L, (char *)data->getData(), data->getSize()); - - // Push the size. - lua_pushinteger(L, data->getSize()); - - // Lua has a copy now, so we can free it. - data->release(); - - return 2; + // close() is called in the File destructor. + return file.read(size); } -int Filesystem::write(lua_State *L) +void Filesystem::write(const char *filename, const void *data, int64 size) const { - // The file to write to. The file must either be created - // on-the-fly, or passed as a parameter. - File *file; + File file(filename); - // We know for sure that we need a second parameter, so - // let's check that first. - if (lua_isnoneornil(L, 2)) - return luaL_error(L, "Second argument needed."); + file.open(File::WRITE); - if (lua_isstring(L, 1)) - { - // Create the file. - file = newFile(lua_tostring(L, 1)); - } - else - return luaL_error(L, "Expected filename."); - - // Get the current mode of the file. - File::Mode mode = file->getMode(); - - if (mode == File::CLOSED) - { - // It should be possible to use append mode, but - // normal File::Mode::Write is the default. - int mode = luaL_optint(L, 4, File::WRITE); - - // Open the file. - if (!file->open((File::Mode)mode)) - return luaL_error(L, "Could not open file."); - } - - size_t length = 0; - const char *input; - if (lua_isstring(L, 2)) - { - input = lua_tolstring(L, 2, &length); - } - else if (luax_istype(L, 2, DATA_T)) - { - love::Data *data = luax_totype(L, 2, "Data", DATA_T); - length = data->getSize(); - input = (char *)data->getData(); - } - else - { - return luaL_error(L, "Expected string or data for argument #2."); - } - - // Get how much we should write. Length of string default. - length = luaL_optint(L, 3, length); - - // Write the data. - bool success = file->write(input, length); - - // Close and delete the file, if we created - // it in this function. - if (lua_isstring(L, 1)) - { - // Kill the file if "we" created it. - file->close(); - file->release(); - } - - if (!success) - return luaL_error(L, "Data could not be written."); - - lua_pushboolean(L, success); - return 1; + // close() is called in the File destructor. + if (!file.write(data, size)) + throw love::Exception("Data could not be written."); } -int Filesystem::enumerate(lua_State *L) +void Filesystem::append(const char *filename, const void *data, int64 size) const { - int n = lua_gettop(L); + File file(filename); - if (n != 1) - return luaL_error(L, "Function requires a single parameter."); + file.open(File::APPEND); - int type = lua_type(L, 1); + // close() is called in the File destructor. + if (!file.write(data, size)) + throw love::Exception("Data could not be written."); +} - if (type != LUA_TSTRING) - return luaL_error(L, "Function requires parameter of type string."); +int Filesystem::getDirectoryItems(lua_State *L) +{ + const char *dir = luaL_checkstring(L, 1); - const char *dir = lua_tostring(L, 1); char **rc = PHYSFS_enumerateFiles(dir); - char **i; int index = 1; lua_newtable(L); - for (i = rc; *i != 0; i++) + for (char **i = rc; *i != 0; i++) { - lua_pushinteger(L, index); lua_pushstring(L, *i); - lua_settable(L, -3); + lua_rawseti(L, -2, index); index++; } @@ -511,15 +541,19 @@ int Filesystem::lines_i(lua_State *L) } else { - char *str; + char *str = 0; try { str = new char[linesize + 1]; } catch(std::bad_alloc &) { - return luaL_error(L, "Out of memory"); + // Can't lua_error (longjmp) in exception handlers. } + + if (!str) + return luaL_error(L, "Out of memory."); + file->seek(pos); // Read the \n anyway and save us a call to seek. @@ -553,56 +587,21 @@ int Filesystem::lines_i(lua_State *L) return 0; } -int Filesystem::load(lua_State *L) +int64 Filesystem::getLastModified(const char *filename) const { - // Need only one arg. - luax_assert_argc(L, 1, 1); + PHYSFS_sint64 time = PHYSFS_getLastModTime(filename); - // Must be string. - if (!lua_isstring(L, -1)) - return luaL_error(L, "The argument must be a string."); + if (time == -1) + throw love::Exception("Could not determine file modification date."); - std::string filename = lua_tostring(L, -1); - - // The file must exist. - if (!exists(filename.c_str())) - return luaL_error(L, "File %s does not exist.", filename.c_str()); - - // Create the file. - File *file = newFile(filename.c_str()); - - // Get the data from the file. - Data *data = file->read(); - - int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str()); - - data->release(); - file->release(); - - // Load the chunk, but don't run it. - switch (status) - { - case LUA_ERRMEM: - return luaL_error(L, "Memory allocation error: %s\n", lua_tostring(L, -1)); - case LUA_ERRSYNTAX: - return luaL_error(L, "Syntax error: %s\n", lua_tostring(L, -1)); - default: // success - return 1; - } + return time; } -int Filesystem::getLastModified(lua_State *L) +int64 Filesystem::getSize(const char *filename) const { - const char *filename = luaL_checkstring(L, 1); - PHYSFS_sint64 time = PHYSFS_getLastModTime(filename); - if (time == -1) - { - lua_pushnil(L); - lua_pushstring(L, "Could not determine file modification date."); - return 2; - } - lua_pushnumber(L, static_cast(time)); - return 1; + File file(filename); + int64 size = file.getSize(); + return size; } } // physfs diff --git a/src/modules/filesystem/physfs/Filesystem.h b/src/modules/filesystem/physfs/Filesystem.h index 1296a0739..a6ef9af5a 100644 --- a/src/modules/filesystem/physfs/Filesystem.h +++ b/src/modules/filesystem/physfs/Filesystem.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -31,6 +31,7 @@ #include "common/Module.h" #include "common/config.h" #include "common/int.h" +#include "common/runtime.h" #include "filesystem/FileData.h" #include "File.h" @@ -71,56 +72,20 @@ namespace filesystem { namespace physfs { + class Filesystem : public Module { -private: - - // Counts open files. - int open_count; - - // Pointer used for file reads. - char *buffer; - - // Contains the current working directory (UTF8). - std::string cwd; - - // %APPDATA% on Windows. - std::string appdata; - - // This name will be used to create the folder - // in the appdata/userdata folder. - std::string save_identity; - - // Full and relative paths of the game save folder. - // (Relative to the %APPDATA% folder, meaning that the - // relative string will look something like: ./LOVE/game) - std::string save_path_relative, save_path_full; - - // The full path to the source of the game. - std::string game_source; - - // Workaround for machines without PhysFS 2.0 - bool isInited; - - // Allow saving outside of the LOVE_APPDATA_FOLDER - // for release 'builds' - bool release; - bool releaseSet; - -protected: - public: Filesystem(); - - ~Filesystem(); + virtual ~Filesystem(); const char *getName() const; void init(const char *arg0); - void setRelease(bool release); - bool isRelease() const; + void setFused(bool fused); + bool isFused() const; /** * This sets up the save directory. If the @@ -134,7 +99,7 @@ public: * @param ident The name of the game. Will be used to * to create the folder in the LOVE data folder. **/ - bool setIdentity(const char *ident); + bool setIdentity(const char *ident, bool appendToPath = false); const char *getIdentity() const; /** @@ -144,10 +109,19 @@ public: **/ bool setSource(const char *source); + /** + * Gets the path to the game source. + * Returns a 0-length string if the source has not been set. + **/ + const char *getSource() const; + + bool mount(const char *archive, const char *mountpoint, bool appendToPath = false); + bool unmount(const char *archive); + /** * Creates a new file. **/ - File *newFile(const char *filename); + File *newFile(const char *filename) const; /** * Creates a new FileData object. Data will be copied. @@ -155,13 +129,13 @@ public: * @param size The size of the data. * @param filename The full filename used to file type identification. **/ - FileData *newFileData(void *data, unsigned int size, const char *filename); + FileData *newFileData(void *data, unsigned int size, const char *filename) const; /** * Creates a new FileData object from base64 data. * @param b64 The base64 data. **/ - FileData *newFileData(const char *b64, const char *filename); + FileData *newFileData(const char *b64, const char *filename) const; /** * Gets the current working directory. @@ -185,31 +159,38 @@ public: **/ const char *getSaveDirectory(); + /** + * Gets the full path to the directory containing the game source. + * For example if the game source is C:\Games\mygame.love, this will return + * C:\Games. + **/ + std::string getSourceBaseDirectory() const; + /** * Checks whether a file exists in the current search path * or not. * @param file The filename to check. **/ - bool exists(const char *file); + bool exists(const char *file) const; /** * Checks if an existing file really is a directory. * @param file The filename to check. **/ - bool isDirectory(const char *file); + bool isDirectory(const char *file) const; /** * Checks if an existing file really is a file, * and not a directory. * @param file The filename to check. **/ - bool isFile(const char *file); + bool isFile(const char *file) const; /** * Creates a directory. Write dir must be set. - * @param file The directory to create. + * @param dir The directory to create. **/ - bool mkdir(const char *file); + bool createDirectory(const char *dir); /** * Removes a file (or directory). @@ -218,68 +199,46 @@ public: bool remove(const char *file); /** - * Opens a file for reading or writing. (Depends - * on the mode chosen at the time of creation). - * @param file The file to open. - * @param mode The mode to open the file in. + * Reads data from a file. + * @param filename The name of the file to read from. + * @param size The size in bytes of the data to read. **/ - bool open(File *file, File::Mode mode); + Data *read(const char *filename, int64 size = File::ALL) const; /** - * Closes a file. - * @param file The file to close. + * Write data to a file. + * @param filename The name of the file to write to. + * @param data The data to write. + * @param size The size in bytes of the data to write. **/ - bool close(File *file); + void write(const char *filename, const void *data, int64 size) const; /** - * Reads count bytes from an open file. - * The first parameter is either a File or - * a string. An optional second parameter specified the - * max number of bytes to read. + * Append data to a file, creating it if it doesn't exist. + * @param filename The name of the file to write to. + * @param data The data to append. + * @param size The size in bytes of the data to append. **/ - int read(lua_State *L); - - /** - * Write the bytes in data to the file. File - * must be opened for write. - * The first parameter is either a File or - * a string. - **/ - int write(lua_State *L); - - /** - * Check if end-of-file is reached. - * @return True if EOF, false otherwise. - **/ - bool eof(File *file); - - /** - * Gets the current position in a file. - * @param file An open File. - **/ - int tell(File *file); - - /** - * Seek to a position within a file. - * @param pos The position to seek to. - **/ - bool seek(File *file, uint64 pos); + void append(const char *filename, const void *data, int64 size) const; /** * This "native" method returns a table of all * files in a given directory. **/ - int enumerate(lua_State *L); + int getDirectoryItems(lua_State *L); /** - * Loads a file without running it. The loaded - * chunk is returned as a function. - * @param filename The filename of the file to load. - * @return A function. + * Gets the last modification time of a file, in seconds + * since the Unix epoch. + * @param filename The name of the file. **/ - int load(lua_State *L); + int64 getLastModified(const char *filename) const; - int getLastModified(lua_State *L); + /** + * Gets the size of a file in bytes. + * @param filename The name of the file. + **/ + int64 getSize(const char *filename) const; /** * Text file line-reading iterator function used and @@ -288,6 +247,34 @@ public: **/ static int lines_i(lua_State *L); +private: + + // Contains the current working directory (UTF8). + std::string cwd; + + // %APPDATA% on Windows. + std::string appdata; + + // This name will be used to create the folder + // in the appdata/userdata folder. + std::string save_identity; + + // Full and relative paths of the game save folder. + // (Relative to the %APPDATA% folder, meaning that the + // relative string will look something like: ./LOVE/game) + std::string save_path_relative, save_path_full; + + // The full path to the source of the game. + std::string game_source; + + // Workaround for machines without PhysFS 2.0 + bool initialized; + + // Allow saving outside of the LOVE_APPDATA_FOLDER + // for release 'builds' + bool fused; + bool fusedSet; + }; // Filesystem } // physfs diff --git a/src/modules/filesystem/physfs/wrap_File.cpp b/src/modules/filesystem/physfs/wrap_File.cpp index 5327a8a61..d136e4b4d 100644 --- a/src/modules/filesystem/physfs/wrap_File.cpp +++ b/src/modules/filesystem/physfs/wrap_File.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -31,6 +31,18 @@ namespace filesystem namespace physfs { +int luax_ioError(lua_State *L, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + lua_pushnil(L); + lua_pushvfstring(L, fmt, args); + + va_end(args); + return 2; +} + File *luax_checkfile(lua_State *L, int idx) { return luax_checktype(L, idx, "File", FILESYSTEM_FILE_T); @@ -39,32 +51,43 @@ File *luax_checkfile(lua_State *L, int idx) int w_File_getSize(lua_State *L) { File *t = luax_checkfile(L, 1); - int64 size = t->getSize(); + + int64 size = -1; + try + { + size = t->getSize(); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } // Push nil on failure or if size does not fit into a double precision floating-point number. - if (size == -1 || size >= 0x20000000000000LL) - lua_pushnil(L); - else - lua_pushnumber(L, (lua_Number)size); + if (size == -1) + return luax_ioError(L, "Could not determine file size."); + else if (size >= 0x20000000000000LL) + return luax_ioError(L, "Size is too large."); + lua_pushnumber(L, (lua_Number) size); return 1; } int w_File_open(lua_State *L) { File *file = luax_checkfile(L, 1); + const char *str = luaL_checkstring(L, 2); File::Mode mode; - if (!File::getConstant(luaL_checkstring(L, 2), mode)) - return luaL_error(L, "Incorrect file open mode: %s", luaL_checkstring(L, 2)); + if (!File::getConstant(str, mode)) + return luaL_error(L, "Incorrect file open mode: %s", str); try { - lua_pushboolean(L, file->open(mode) ? 1 : 0); + luax_pushboolean(L, file->open(mode)); } - catch(Exception e) + catch (love::Exception &e) { - return luaL_error(L, e.what()); + return luax_ioError(L, "%s", e.what()); } return 1; @@ -73,7 +96,14 @@ int w_File_open(lua_State *L) int w_File_close(lua_State *L) { File *file = luax_checkfile(L, 1); - lua_pushboolean(L, file->close() ? 1 : 0); + luax_pushboolean(L, file->close()); + return 1; +} + +int w_File_isOpen(lua_State *L) +{ + File *file = luax_checkfile(L, 1); + luax_pushboolean(L, file->isOpen()); return 1; } @@ -82,15 +112,15 @@ int w_File_read(lua_State *L) File *file = luax_checkfile(L, 1); Data *d = 0; - int64 size = (int64)luaL_optnumber(L, 2, (lua_Number) file->getSize()); + int64 size = (int64)luaL_optnumber(L, 2, File::ALL); try { d = file->read(size); } - catch(Exception e) + catch (love::Exception &e) { - return luaL_error(L, e.what()); + return luax_ioError(L, "%s", e.what()); } lua_pushlstring(L, (const char *) d->getData(), d->getSize()); @@ -102,38 +132,59 @@ int w_File_read(lua_State *L) int w_File_write(lua_State *L) { File *file = luax_checkfile(L, 1); - bool result; - if (file->getMode() == File::CLOSED) - return luaL_error(L, "File is not open."); + bool result = false; + if (lua_isstring(L, 2)) { try { - result = file->write(lua_tostring(L, 2), luaL_optint(L, 3, lua_objlen(L, 2))); - } - catch(Exception e) - { - return luaL_error(L, e.what()); - } + size_t datasize = 0; + const char *data = lua_tolstring(L, 2, &datasize); + if (!lua_isnoneornil(L, 3)) + datasize = luaL_checkinteger(L, 3); + + result = file->write(data, datasize); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } } else if (luax_istype(L, 2, DATA_T)) { try { love::Data *data = luax_totype(L, 2, "Data", DATA_T); - result = file->write(data, luaL_optint(L, 3, data->getSize())); + result = file->write(data, luaL_optinteger(L, 3, data->getSize())); } - catch(Exception e) + catch (love::Exception &e) { - return luaL_error(L, e.what()); + return luax_ioError(L, "%s", e.what()); } } else { - return luaL_error(L, "String or data expected."); + return luaL_argerror(L, 2, "string or data expected"); } - lua_pushboolean(L, result); + + luax_pushboolean(L, result); + return 1; +} + +int w_File_flush(lua_State *L) +{ + File *file = luax_checkfile(L, 1); + bool success = false; + try + { + success = file->flush(); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } + luax_pushboolean(L, success); return 1; } @@ -149,8 +200,10 @@ int w_File_tell(lua_State *L) File *file = luax_checkfile(L, 1); int64 pos = file->tell(); // Push nil on failure or if pos does not fit into a double precision floating-point number. - if (pos == -1 || pos >= 0x20000000000000LL) - lua_pushnil(L); + if (pos == -1) + return luax_ioError(L, "Invalid position."); + else if (pos >= 0x20000000000000LL) + return luax_ioError(L, "Number is too large."); else lua_pushnumber(L, (lua_Number)pos); return 1; @@ -172,48 +225,96 @@ int w_File_seek(lua_State *L) int w_File_lines(lua_State *L) { - File *file; + File *file = luax_checkfile(L, 1); - if (luax_istype(L, 1, FILESYSTEM_FILE_T)) - { - file = luax_checktype(L, 1, "File", FILESYSTEM_FILE_T); - lua_pushnumber(L, 0); // File position. - luax_pushboolean(L, file->getMode() != File::CLOSED); // Save current file mode. - } - else - return luaL_error(L, "Expected File."); + lua_pushnumber(L, 0); // File position. + luax_pushboolean(L, file->getMode() != File::CLOSED); // Save current file mode. if (file->getMode() != File::READ) { if (file->getMode() != File::CLOSED) file->close(); - try - { - if (!file->open(File::READ)) - return luaL_error(L, "Could not open file."); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } + bool success = false; + EXCEPT_GUARD(success = file->open(File::READ);) + + if (!success) + return luaL_error(L, "Could not open file."); } lua_pushcclosure(L, Filesystem::lines_i, 3); return 1; } +int w_File_setBuffer(lua_State *L) +{ + File *file = luax_checkfile(L, 1); + const char *str = luaL_checkstring(L, 2); + int64 size = (int64) luaL_optnumber(L, 3, 0.0); + + File::BufferMode bufmode; + if (!File::getConstant(str, bufmode)) + return luaL_error(L, "Incorrect file buffer mode: %s", str); + + bool success = false; + try + { + success = file->setBuffer(bufmode, size); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } + + luax_pushboolean(L, success); + return 1; +} + +int w_File_getBuffer(lua_State *L) +{ + File *file = luax_checkfile(L, 1); + int64 size = 0; + File::BufferMode bufmode = file->getBuffer(size); + const char *str = 0; + + if (!File::getConstant(bufmode, str)) + return luax_ioError(L, "Unknown file buffer mode."); + + lua_pushstring(L, str); + lua_pushnumber(L, (lua_Number) size); + return 2; +} + +int w_File_getMode(lua_State *L) +{ + File *file = luax_checkfile(L, 1); + + File::Mode mode = file->getMode(); + const char *str = 0; + + if (!File::getConstant(mode, str)) + return luax_ioError(L, "Unknown file mode."); + + lua_pushstring(L, str); + return 1; +} + static const luaL_Reg functions[] = { { "getSize", w_File_getSize }, { "open", w_File_open }, { "close", w_File_close }, + { "isOpen", w_File_isOpen }, { "read", w_File_read }, { "write", w_File_write }, + { "flush", w_File_flush }, { "eof", w_File_eof }, { "tell", w_File_tell }, { "seek", w_File_seek }, { "lines", w_File_lines }, + { "setBuffer", w_File_setBuffer }, + { "getBuffer", w_File_getBuffer }, + { "getMode", w_File_getMode }, { 0, 0 } }; diff --git a/src/modules/filesystem/physfs/wrap_File.h b/src/modules/filesystem/physfs/wrap_File.h index 5a79c46ec..a3d0b964d 100644 --- a/src/modules/filesystem/physfs/wrap_File.h +++ b/src/modules/filesystem/physfs/wrap_File.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,16 +33,24 @@ namespace filesystem namespace physfs { +// Does not use lua_error, so it's safe to call in exception handling code. +int luax_ioError(lua_State *L, const char *fmt, ...); + File *luax_checkfile(lua_State *L, int idx); int w_File_getSize(lua_State *L); int w_File_open(lua_State *L); int w_File_close(lua_State *L); +int w_File_isOpen(lua_State *L); int w_File_read(lua_State *L); int w_File_write(lua_State *L); +int w_File_flush(lua_State *L); int w_File_eof(lua_State *L); int w_File_tell(lua_State *L); int w_File_seek(lua_State *L); int w_File_lines(lua_State *L); +int w_File_setBuffer(lua_State *L); +int w_File_getBuffer(lua_State *L); +int w_File_getMode(lua_State *L); extern "C" int luaopen_file(lua_State *L); } // physfs diff --git a/src/modules/filesystem/physfs/wrap_FileData.cpp b/src/modules/filesystem/physfs/wrap_FileData.cpp index 4e8961f9f..b50c8123b 100644 --- a/src/modules/filesystem/physfs/wrap_FileData.cpp +++ b/src/modules/filesystem/physfs/wrap_FileData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -50,8 +50,8 @@ int w_FileData_getExtension(lua_State *L) static const luaL_Reg w_FileData_functions[] = { - // Data + { "getString", w_Data_getString }, { "getPointer", w_Data_getPointer }, { "getSize", w_Data_getSize }, diff --git a/src/modules/filesystem/physfs/wrap_FileData.h b/src/modules/filesystem/physfs/wrap_FileData.h index e862cf3a3..2d46165fb 100644 --- a/src/modules/filesystem/physfs/wrap_FileData.h +++ b/src/modules/filesystem/physfs/wrap_FileData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/filesystem/physfs/wrap_Filesystem.cpp b/src/modules/filesystem/physfs/wrap_Filesystem.cpp index 7dae878b2..6e76cbb52 100644 --- a/src/modules/filesystem/physfs/wrap_Filesystem.cpp +++ b/src/modules/filesystem/physfs/wrap_Filesystem.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,6 +21,9 @@ // LOVE #include "wrap_Filesystem.h" +// SDL +#include + namespace love { namespace filesystem @@ -40,32 +43,30 @@ bool hack_setupWriteDirectory() int w_init(lua_State *L) { const char *arg0 = luaL_checkstring(L, 1); - - try - { - instance->init(arg0); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } - + EXCEPT_GUARD(instance->init(arg0);) return 0; } -int w_setRelease(lua_State *L) +int w_setFused(lua_State *L) { // no error checking needed, everything, even nothing // can be converted to a boolean - instance->setRelease(luax_toboolean(L, 1)); + instance->setFused(luax_toboolean(L, 1)); return 0; } +int w_isFused(lua_State *L) +{ + luax_pushboolean(L, instance->isFused()); + return 1; +} + int w_setIdentity(lua_State *L) { const char *arg = luaL_checkstring(L, 1); + bool append = luax_optboolean(L, 2, false); - if (!instance->setIdentity(arg)) + if (!instance->setIdentity(arg, append)) return luaL_error(L, "Could not set write directory."); return 0; @@ -87,38 +88,102 @@ int w_setSource(lua_State *L) return 0; } +int w_getSource(lua_State *L) +{ + lua_pushstring(L, instance->getSource()); + return 1; +} + +int w_mount(lua_State *L) +{ + const char *archive = luaL_checkstring(L, 1); + const char *mountpoint = luaL_checkstring(L, 2); + bool append = luax_optboolean(L, 3, false); + + luax_pushboolean(L, instance->mount(archive, mountpoint, append)); + return 1; +} + +int w_unmount(lua_State *L) +{ + const char *archive = luaL_checkstring(L, 1); + + luax_pushboolean(L, instance->unmount(archive)); + return 1; +} + int w_newFile(lua_State *L) { const char *filename = luaL_checkstring(L, 1); - File *t; - try + + const char *str = 0; + File::Mode mode = File::CLOSED; + + if (lua_isstring(L, 2)) { - t = instance->newFile(filename); + str = luaL_checkstring(L, 2); + if (!File::getConstant(str, mode)) + return luaL_error(L, "Incorrect file open mode: %s", str); } - catch(Exception e) + + File *t = instance->newFile(filename); + + if (mode != File::CLOSED) { - return luaL_error(L, e.what()); + try + { + if (!t->open(mode)) + throw love::Exception("Could not open file."); + } + catch (love::Exception &e) + { + t->release(); + return luax_ioError(L, "%s", e.what()); + } } - luax_newtype(L, "File", FILESYSTEM_FILE_T, (void *)t); + + luax_pushtype(L, "File", FILESYSTEM_FILE_T, t); return 1; } int w_newFileData(lua_State *L) { - if (!lua_isstring(L, 1)) - return luaL_error(L, "String expected."); - if (!lua_isstring(L, 2)) - return luaL_error(L, "String expected."); + // Single argument: treat as filepath or File. + if (lua_gettop(L) == 1) + { + if (lua_isstring(L, 1)) + luax_convobj(L, 1, "filesystem", "newFile"); + + // Get FileData from the File. + if (luax_istype(L, 1, FILESYSTEM_FILE_T)) + { + File *file = luax_checktype(L, 1, "File", FILESYSTEM_FILE_T); + + FileData *data = 0; + try + { + data = file->read(); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } + luax_pushtype(L, "FileData", FILESYSTEM_FILE_DATA_T, data); + return 1; + } + else + return luaL_argerror(L, 1, "string or File expected"); + } size_t length = 0; - const char *str = lua_tolstring(L, 1, &length); - const char *filename = lua_tostring(L, 2); + const char *str = luaL_checklstring(L, 1, &length); + const char *filename = luaL_checkstring(L, 2); const char *decstr = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0; FileData::Decoder decoder = FileData::FILE; - if (decstr) - FileData::getConstant(decstr, decoder); + if (decstr && !FileData::getConstant(decstr, decoder)) + return luaL_error(L, "Invalid FileData decoder: %s", decstr); FileData *t = 0; @@ -131,10 +196,10 @@ int w_newFileData(lua_State *L) t = instance->newFileData(str, filename); break; default: - return luaL_error(L, "Unrecognized FileData decoder: %s", decstr); + return luaL_error(L, "Invalid FileData decoder: %s", decstr); } - luax_newtype(L, "FileData", FILESYSTEM_FILE_DATA_T, (void *)t); + luax_pushtype(L, "FileData", FILESYSTEM_FILE_DATA_T, t); return 1; } @@ -162,68 +227,127 @@ int w_getSaveDirectory(lua_State *L) return 1; } +int w_getSourceBaseDirectory(lua_State *L) +{ + luax_pushstring(L, instance->getSourceBaseDirectory()); + return 1; +} + int w_exists(lua_State *L) { const char *arg = luaL_checkstring(L, 1); - lua_pushboolean(L, instance->exists(arg) ? 1 : 0); + luax_pushboolean(L, instance->exists(arg)); return 1; } int w_isDirectory(lua_State *L) { const char *arg = luaL_checkstring(L, 1); - lua_pushboolean(L, instance->isDirectory(arg) ? 1 : 0); + luax_pushboolean(L, instance->isDirectory(arg)); return 1; } int w_isFile(lua_State *L) { const char *arg = luaL_checkstring(L, 1); - lua_pushboolean(L, instance->isFile(arg) ? 1 : 0); + luax_pushboolean(L, instance->isFile(arg)); return 1; } -int w_mkdir(lua_State *L) +int w_createDirectory(lua_State *L) { const char *arg = luaL_checkstring(L, 1); - lua_pushboolean(L, instance->mkdir(arg) ? 1 : 0); + luax_pushboolean(L, instance->createDirectory(arg)); return 1; } int w_remove(lua_State *L) { const char *arg = luaL_checkstring(L, 1); - lua_pushboolean(L, instance->remove(arg) ? 1 : 0); + luax_pushboolean(L, instance->remove(arg)); return 1; } int w_read(lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + int64 len = (int64) luaL_optinteger(L, 2, File::ALL); + + Data *data = 0; try { - return instance->read(L); + data = instance->read(filename, len); } - catch(Exception e) + catch (love::Exception &e) { - return luaL_error(L, e.what()); + return luax_ioError(L, "%s", e.what()); } + + if (data == 0) + return luax_ioError(L, "File could not be read."); + + // Push the string. + lua_pushlstring(L, (const char *) data->getData(), data->getSize()); + + // Push the size. + lua_pushinteger(L, data->getSize()); + + // Lua has a copy now, so we can free it. + data->release(); + + return 2; +} + +static int w_write_or_append(lua_State *L, File::Mode mode) +{ + const char *filename = luaL_checkstring(L, 1); + + const char *input = 0; + size_t len = 0; + + if (luax_istype(L, 2, DATA_T)) + { + love::Data *data = luax_totype(L, 2, "Data", DATA_T); + input = (const char *) data->getData(); + len = data->getSize(); + } + else if (lua_isstring(L, 2)) + input = lua_tolstring(L, 2, &len); + else + return luaL_argerror(L, 2, "string or Data expected"); + + // Get how much we should write. Length of string default. + len = luaL_optinteger(L, 3, len); + + try + { + if (mode == File::APPEND) + instance->append(filename, (const void *) input, len); + else + instance->write(filename, (const void *) input, len); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } + + luax_pushboolean(L, true); + return 1; } int w_write(lua_State *L) { - try - { - return instance->write(L); - } - catch(Exception e) - { - return luaL_error(L, e.what()); - } + return w_write_or_append(L, File::WRITE); } -int w_enumerate(lua_State *L) +int w_append(lua_State *L) { - return instance->enumerate(L); + return w_write_or_append(L, File::APPEND); +} + +int w_getDirectoryItems(lua_State *L) +{ + return instance->getDirectoryItems(L); } int w_lines(lua_State *L) @@ -233,19 +357,17 @@ int w_lines(lua_State *L) if (lua_isstring(L, 1)) { file = instance->newFile(lua_tostring(L, 1)); - try - { - if (!file->open(File::READ)) - return luaL_error(L, "Could not open file."); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - luax_newtype(L, "File", FILESYSTEM_FILE_T, file); + bool success = false; + + EXCEPT_GUARD(success = file->open(File::READ);) + + if (!success) + return luaL_error(L, "Could not open file."); + + luax_pushtype(L, "File", FILESYSTEM_FILE_T, file); } else - return luaL_error(L, "Expected filename."); + return luaL_argerror(L, 1, "expected filename."); lua_pushcclosure(L, Filesystem::lines_i, 1); return 1; @@ -253,19 +375,74 @@ int w_lines(lua_State *L) int w_load(lua_State *L) { + std::string filename = std::string(luaL_checkstring(L, 1)); + + Data *data = 0; try { - return instance->load(L); + data = instance->read(filename.c_str()); } - catch(love::Exception &e) + catch (love::Exception &e) { - return luaL_error(L, e.what()); + return luax_ioError(L, "%s", e.what()); + } + + int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str()); + + data->release(); + + // Load the chunk, but don't run it. + switch (status) + { + case LUA_ERRMEM: + return luaL_error(L, "Memory allocation error: %s\n", lua_tostring(L, -1)); + case LUA_ERRSYNTAX: + return luaL_error(L, "Syntax error: %s\n", lua_tostring(L, -1)); + default: // success + return 1; } } int w_getLastModified(lua_State *L) { - return instance->getLastModified(L); + const char *filename = luaL_checkstring(L, 1); + + int64 time = 0; + try + { + time = instance->getLastModified(filename); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } + + lua_pushnumber(L, static_cast(time)); + return 1; +} + +int w_getSize(lua_State *L) +{ + const char *filename = luaL_checkstring(L, 1); + + int64 size = -1; + try + { + size = instance->getSize(filename); + } + catch (love::Exception &e) + { + return luax_ioError(L, "%s", e.what()); + } + + // Error on failure or if size does not fit into a double precision floating-point number. + if (size == -1) + return luax_ioError(L, "Could not determine file size."); + else if (size >= 0x20000000000000LL) + return luax_ioError(L, "Size too large to fit into a Lua number!"); + + lua_pushnumber(L, (lua_Number) size); + return 1; } int loader(lua_State *L) @@ -291,7 +468,7 @@ int loader(lua_State *L) lua_pop(L, 1); lua_pushstring(L, tmp.c_str()); // Ok, load it. - return instance->load(L); + return w_load(L); } tmp = filename; @@ -312,11 +489,14 @@ int loader(lua_State *L) lua_pop(L, 1); lua_pushstring(L, tmp.c_str()); // Ok, load it. - return instance->load(L); + return w_load(L); } } - lua_pushfstring(L, "\n\tno file \"%s\" in LOVE game directories.\n", (tmp + ".lua").c_str()); + std::string errstr = "\n\tno file '%s' in LOVE game directories."; + errstr += errstr; + + lua_pushfstring(L, errstr.c_str(), (tmp + ".lua").c_str(), (tmp + "/init.lua").c_str()); return 1; } @@ -347,12 +527,12 @@ int extloader(lua_State *L) tokenized_name += library_extension(); void *handle = SDL_LoadObject((std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name).c_str()); - if (!handle && instance->isRelease()) + if (!handle && instance->isFused()) handle = SDL_LoadObject((std::string(instance->getSaveDirectory()) + LOVE_PATH_SEPARATOR + tokenized_name).c_str()); if (!handle) { - lua_pushfstring(L, "\n\tno extension \"%s\" in LOVE paths.\n", filename); + lua_pushfstring(L, "\n\tno file '%s' in LOVE paths.", tokenized_name.c_str()); return 1; } @@ -363,7 +543,7 @@ int extloader(lua_State *L) if (!func) { SDL_UnloadObject(handle); - lua_pushfstring(L, "\n\textension \"%s\" is incompatible.\n", filename); + lua_pushfstring(L, "\n\tC library '%s' is incompatible.", tokenized_name.c_str()); return 1; } @@ -375,26 +555,33 @@ int extloader(lua_State *L) static const luaL_Reg functions[] = { { "init", w_init }, - { "setRelease", w_setRelease }, + { "setFused", w_setFused }, + { "isFused", w_isFused }, { "setIdentity", w_setIdentity }, { "getIdentity", w_getIdentity }, { "setSource", w_setSource }, + { "getSource", w_getSource }, + { "mount", w_mount }, + { "unmount", w_unmount }, { "newFile", w_newFile }, { "getWorkingDirectory", w_getWorkingDirectory }, { "getUserDirectory", w_getUserDirectory }, { "getAppdataDirectory", w_getAppdataDirectory }, { "getSaveDirectory", w_getSaveDirectory }, + { "getSourceBaseDirectory", w_getSourceBaseDirectory }, { "exists", w_exists }, { "isDirectory", w_isDirectory }, { "isFile", w_isFile }, - { "mkdir", w_mkdir }, + { "createDirectory", w_createDirectory }, { "remove", w_remove }, { "read", w_read }, { "write", w_write }, - { "enumerate", w_enumerate }, + { "append", w_append }, + { "getDirectoryItems", w_getDirectoryItems }, { "lines", w_lines }, { "load", w_load }, { "getLastModified", w_getLastModified }, + { "getSize", w_getSize }, { "newFileData", w_newFileData }, { 0, 0 } }; @@ -410,23 +597,14 @@ extern "C" int luaopen_love_filesystem(lua_State *L) { if (instance == 0) { - try - { - instance = new Filesystem(); - love::luax_register_searcher(L, loader, 1); - love::luax_register_searcher(L, extloader, 2); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new Filesystem();) } else - { instance->retain(); - love::luax_register_searcher(L, loader, 1); - love::luax_register_searcher(L, extloader, 2); - } + + // The love loaders should be tried after package.preload. + love::luax_register_searcher(L, loader, 2); + love::luax_register_searcher(L, extloader, 3); WrappedModule w; w.module = instance; diff --git a/src/modules/filesystem/physfs/wrap_Filesystem.h b/src/modules/filesystem/physfs/wrap_Filesystem.h index 59f9abd67..711c5eb55 100644 --- a/src/modules/filesystem/physfs/wrap_Filesystem.h +++ b/src/modules/filesystem/physfs/wrap_Filesystem.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,9 +26,6 @@ #include "wrap_File.h" #include "wrap_FileData.h" -// SDL -#include - namespace love { namespace filesystem @@ -38,32 +35,36 @@ namespace physfs bool hack_setupWriteDirectory(); int w_init(lua_State *L); -int w_setRelease(lua_State *L); +int w_setFused(lua_State *L); +int w_isFused(lua_State *L); int w_setIdentity(lua_State *L); int w_getIdentity(lua_State *L); int w_setSource(lua_State *L); +int w_getSource(lua_State *L); +int w_mount(lua_State *L); +int w_unmount(lua_State *L); int w_newFile(lua_State *L); int w_newFileData(lua_State *L); int w_getWorkingDirectory(lua_State *L); int w_getUserDirectory(lua_State *L); int w_getAppdataDirectory(lua_State *L); int w_getSaveDirectory(lua_State *L); +int w_getSourceBaseDirectory(lua_State *L); int w_exists(lua_State *L); int w_isDirectory(lua_State *L); int w_isFile(lua_State *L); -int w_mkdir(lua_State *L); +int w_createDirectory(lua_State *L); int w_remove(lua_State *L); int w_open(lua_State *L); int w_close(lua_State *L); int w_read(lua_State *L); int w_write(lua_State *L); -int w_eof(lua_State *L); -int w_tell(lua_State *L); -int w_seek(lua_State *L); -int w_enumerate(lua_State *L); +int w_append(lua_State *L); +int w_getDirectoryItems(lua_State *L); int w_lines(lua_State *L); int w_load(lua_State *L); int w_getLastModified(lua_State *L); +int w_getSize(lua_State *L); int loader(lua_State *L); int extloader(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_filesystem(lua_State *L); diff --git a/src/modules/font/Font.h b/src/modules/font/Font.h index 827a81746..dacde0348 100644 --- a/src/modules/font/Font.h +++ b/src/modules/font/Font.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -25,6 +25,7 @@ #include "Rasterizer.h" #include "image/ImageData.h" #include "common/Module.h" +#include "common/int.h" // STD #include @@ -41,8 +42,9 @@ public: virtual Rasterizer *newRasterizer(Data *data, int size) = 0; virtual Rasterizer *newRasterizer(love::image::ImageData *data, const std::string &glyphs) = 0; - virtual Rasterizer *newRasterizer(love::image::ImageData *data, unsigned int *glyphs, int length) = 0; - virtual GlyphData *newGlyphData(Rasterizer *r, unsigned int glyph) = 0; + virtual Rasterizer *newRasterizer(love::image::ImageData *data, uint32 *glyphs, int length) = 0; + virtual GlyphData *newGlyphData(Rasterizer *r, const std::string &glyph) = 0; + virtual GlyphData *newGlyphData(Rasterizer *r, uint32 glyph) = 0; // Implement Module virtual const char *getName() const = 0; diff --git a/src/modules/font/GlyphData.cpp b/src/modules/font/GlyphData.cpp index 8054d7c6e..27cf32af8 100644 --- a/src/modules/font/GlyphData.cpp +++ b/src/modules/font/GlyphData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,22 +18,28 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "GlyphData.h" +// UTF-8 +#include "libraries/utf8/utf8.h" + +// stdlib #include +#include namespace love { namespace font { -GlyphData::GlyphData(unsigned int glyph, GlyphMetrics glyphMetrics, GlyphData::Format f) +GlyphData::GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, GlyphData::Format f) : glyph(glyph) , metrics(glyphMetrics) - , data(0) + , data(nullptr) , format(f) { - if (metrics.width && metrics.height) + if (metrics.width > 0 && metrics.height > 0) { switch (f) { @@ -83,11 +89,33 @@ int GlyphData::getWidth() const return metrics.width; } -unsigned int GlyphData::getGlyph() const +uint32 GlyphData::getGlyph() const { return glyph; } +std::string GlyphData::getGlyphString() const +{ + char u[5] = {0, 0, 0, 0, 0}; + ptrdiff_t length = 0; + + try + { + char *end = utf8::append(glyph, u); + length = end - u; + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + // Just in case... + if (length < 0) + return ""; + + return std::string(u, length); +} + int GlyphData::getAdvance() const { return metrics.advance; @@ -128,5 +156,23 @@ GlyphData::Format GlyphData::getFormat() const return format; } +bool GlyphData::getConstant(const char *in, GlyphData::Format &out) +{ + return formats.find(in, out); +} + +bool GlyphData::getConstant(GlyphData::Format in, const char *&out) +{ + return formats.find(in, out); +} + +StringMap::Entry GlyphData::formatEntries[] = +{ + {"luminance alpha", GlyphData::FORMAT_LUMINANCE_ALPHA}, + {"rgba", GlyphData::FORMAT_RGBA}, +}; + +StringMap GlyphData::formats(GlyphData::formatEntries, sizeof(GlyphData::formatEntries)); + } // font } // love diff --git a/src/modules/font/GlyphData.h b/src/modules/font/GlyphData.h index acfd6a5b8..59aa1200b 100644 --- a/src/modules/font/GlyphData.h +++ b/src/modules/font/GlyphData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,6 +24,12 @@ // LOVE #include "common/config.h" #include "common/Data.h" +#include "common/Exception.h" +#include "common/StringMap.h" +#include "common/int.h" + +// stdlib +#include namespace love { @@ -48,15 +54,16 @@ struct GlyphMetrics **/ class GlyphData : public Data { - public: + enum Format { FORMAT_LUMINANCE_ALPHA, - FORMAT_RGBA + FORMAT_RGBA, + FORMAT_MAX_ENUM }; - GlyphData(unsigned int glyph, GlyphMetrics glyphMetrics, Format f); + GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, Format f); virtual ~GlyphData(); // Implements Data. @@ -74,9 +81,14 @@ public: virtual int getWidth() const; /** - * Gets the glyph itself. + * Gets the glyph codepoint itself. **/ - unsigned int getGlyph() const; + uint32 getGlyph() const; + + /** + * Gets the glyph as a UTF-8 string (instead of a UTF-8 code point.) + **/ + std::string getGlyphString() const; /** * Gets the advance (the space the glyph takes up) of the glyph. @@ -118,19 +130,26 @@ public: **/ Format getFormat() const; -private: - // The glyph itself - unsigned int glyph; + static bool getConstant(const char *in, Format &out); + static bool getConstant(Format in, const char *&out); - // Glyph metrics +private: + + // The glyph codepoint itself. + uint32 glyph; + + // Glyph metrics. GlyphMetrics metrics; - // Glyph texture data + // Glyph texture data. unsigned char *data; - // The format the data's in + // The format the data's in. Format format; + static StringMap::Entry formatEntries[]; + static StringMap formats; + }; // GlyphData } // font diff --git a/src/modules/font/ImageRasterizer.cpp b/src/modules/font/ImageRasterizer.cpp index 007b4984c..fd0ec21b2 100644 --- a/src/modules/font/ImageRasterizer.cpp +++ b/src/modules/font/ImageRasterizer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -34,7 +34,7 @@ inline bool equal(const love::image::pixel &a, const love::image::pixel &b) return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a); } -ImageRasterizer::ImageRasterizer(love::image::ImageData *data, unsigned int *glyphs, int numglyphs) +ImageRasterizer::ImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs) : imageData(data) , glyphs(glyphs) , numglyphs(numglyphs) @@ -53,13 +53,13 @@ int ImageRasterizer::getLineHeight() const return getHeight(); } -GlyphData *ImageRasterizer::getGlyphData(unsigned int glyph) const +GlyphData *ImageRasterizer::getGlyphData(uint32 glyph) const { GlyphMetrics gm; memset(&gm, 0, sizeof(GlyphMetrics)); // Set relevant glyph metrics if the glyph is in this ImageFont - std::map::const_iterator it = imageGlyphs.find(glyph); + std::map::const_iterator it = imageGlyphs.find(glyph); if (it != imageGlyphs.end()) { gm.width = it->second.width; @@ -73,13 +73,16 @@ GlyphData *ImageRasterizer::getGlyphData(unsigned int glyph) const if (gm.width == 0) return g; + // We don't want another thread modifying our ImageData mid-copy. + love::thread::Lock lock(imageData->getMutex()); + love::image::pixel *gdpixels = (love::image::pixel *) g->getData(); love::image::pixel *imagepixels = (love::image::pixel *) imageData->getData(); // copy glyph pixels from imagedata to glyphdata for (int i = 0; i < g->getWidth() * g->getHeight(); i++) { - love::image::pixel p = imagepixels[ it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width)) ]; + love::image::pixel p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))]; // Use transparency instead of the spacer color if (equal(p, spacer)) @@ -95,8 +98,11 @@ void ImageRasterizer::load() { love::image::pixel *pixels = (love::image::pixel *) imageData->getData(); - unsigned int imgw = (unsigned int) imageData->getWidth(); - unsigned int imgh = (unsigned int) imageData->getHeight(); + int imgw = imageData->getWidth(); + int imgh = imageData->getHeight(); + + // We don't want another thread modifying our ImageData mid-parse. + love::thread::Lock lock(imageData->getMutex()); // Set the only metric that matters metrics.height = imgh; @@ -104,10 +110,10 @@ void ImageRasterizer::load() // Reading texture data begins spacer = pixels[0]; - unsigned int start = 0; - unsigned int end = 0; + int start = 0; + int end = 0; - for (unsigned int i = 0; i < numglyphs; ++i) + for (int i = 0; i < numglyphs; ++i) { start = end; @@ -146,10 +152,15 @@ void ImageRasterizer::load() } } -int ImageRasterizer::getNumGlyphs() const +int ImageRasterizer::getGlyphCount() const { return numglyphs; } +bool ImageRasterizer::hasGlyph(uint32 glyph) const +{ + return imageGlyphs.find(glyph) != imageGlyphs.end(); +} + } // font } // love diff --git a/src/modules/font/ImageRasterizer.h b/src/modules/font/ImageRasterizer.h index c4b4ff438..5c7e9e8f6 100644 --- a/src/modules/font/ImageRasterizer.h +++ b/src/modules/font/ImageRasterizer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,13 +39,14 @@ namespace font class ImageRasterizer : public Rasterizer { public: - ImageRasterizer(love::image::ImageData *imageData, unsigned int *glyphs, int numglyphs); + ImageRasterizer(love::image::ImageData *imageData, uint32 *glyphs, int numglyphs); virtual ~ImageRasterizer(); // Implement Rasterizer virtual int getLineHeight() const; - virtual GlyphData *getGlyphData(unsigned int glyph) const; - virtual int getNumGlyphs() const; + virtual GlyphData *getGlyphData(uint32 glyph) const; + virtual int getGlyphCount() const; + virtual bool hasGlyph(uint32 glyph) const; private: // Load all the glyph positions into memory @@ -55,20 +56,20 @@ private: love::image::ImageData *imageData; // The glyphs in the font - unsigned int *glyphs; + uint32 *glyphs; // Number of glyphs in the font - unsigned int numglyphs; + int numglyphs; // Information about a glyph in the ImageData struct ImageGlyphData { - unsigned int x; - unsigned int width; - unsigned int spacing; + int x; + int width; + int spacing; }; - std::map imageGlyphs; + std::map imageGlyphs; // Color used to identify glyph separation in the source ImageData love::image::pixel spacer; diff --git a/src/modules/font/Rasterizer.cpp b/src/modules/font/Rasterizer.cpp index 03f05a441..1454f2557 100644 --- a/src/modules/font/Rasterizer.cpp +++ b/src/modules/font/Rasterizer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,6 +21,9 @@ // LOVE #include "Rasterizer.h" +// UTF-8 +#include "libraries/utf8/utf8.h" + namespace love { namespace font @@ -50,5 +53,47 @@ int Rasterizer::getDescent() const return metrics.descent; } +GlyphData *Rasterizer::getGlyphData(const std::string &text) const +{ + uint32 codepoint = 0; + + try + { + codepoint = utf8::peek_next(text.begin(), text.end()); + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + return getGlyphData(codepoint); +} + +bool Rasterizer::hasGlyphs(const std::string &text) const +{ + if (text.size() == 0) + return false; + + try + { + utf8::iterator i(text.begin(), text.begin(), text.end()); + utf8::iterator end(text.end(), text.begin(), text.end()); + + while (i != end) + { + uint32 codepoint = *i++; + + if (!hasGlyph(codepoint)) + return false; + } + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + return true; +} + } // font } // love \ No newline at end of file diff --git a/src/modules/font/Rasterizer.h b/src/modules/font/Rasterizer.h index 5853ccd48..a4cd6e5c9 100644 --- a/src/modules/font/Rasterizer.h +++ b/src/modules/font/Rasterizer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,6 +23,7 @@ // LOVE #include "common/Object.h" +#include "common/int.h" #include "GlyphData.h" namespace love @@ -46,9 +47,6 @@ struct FontMetrics **/ class Rasterizer : public Object { -protected: - FontMetrics metrics; - public: virtual ~Rasterizer(); @@ -80,15 +78,36 @@ public: /** * Gets a specific glyph. - * @param glyph The (UNICODE) glyph to get data for + * @param glyph The (UNICODE) glyph codepoint to get data for. **/ - virtual GlyphData *getGlyphData(unsigned int glyph) const = 0; + virtual GlyphData *getGlyphData(uint32 glyph) const = 0; + + /** + * Gets a specific glyph. + * @param text The (UNICODE) glyph character to get the data for. + **/ + virtual GlyphData *getGlyphData(const std::string &text) const; /** * Gets the number of glyphs the rasterizer has data for. **/ - virtual int getNumGlyphs() const = 0; + virtual int getGlyphCount() const = 0; + /** + * Gets whether this Rasterizer has a specific glyph. + * @param glyph The (UNICODE) glyph codepoint. + **/ + virtual bool hasGlyph(uint32 glyph) const = 0; + + /** + * Gets whether this Rasterizer has all the glyphs in a string. + * @param text The (UTF-8) string. + **/ + virtual bool hasGlyphs(const std::string &text) const; + +protected: + + FontMetrics metrics; }; // Rasterizer diff --git a/src/modules/font/freetype/Font.cpp b/src/modules/font/freetype/Font.cpp index 6aa3b243d..ece8e8ddb 100644 --- a/src/modules/font/freetype/Font.cpp +++ b/src/modules/font/freetype/Font.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -52,8 +52,8 @@ Rasterizer *Font::newRasterizer(love::image::ImageData *data, const std::string { size_t strlen = text.size(); size_t numglyphs = 0; - - unsigned int *glyphs = new unsigned int[strlen]; + + uint32 *glyphs = new uint32[strlen]; try { @@ -66,21 +66,37 @@ Rasterizer *Font::newRasterizer(love::image::ImageData *data, const std::string catch (utf8::exception &e) { delete [] glyphs; - throw love::Exception("%s", e.what()); + throw love::Exception("Decoding error: %s", e.what()); } - + Rasterizer *r = newRasterizer(data, glyphs, numglyphs); delete [] glyphs; - + return r; } -Rasterizer *Font::newRasterizer(love::image::ImageData *data, unsigned int *glyphs, int numglyphs) +Rasterizer *Font::newRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs) { return new ImageRasterizer(data, glyphs, numglyphs); } -GlyphData *Font::newGlyphData(Rasterizer *r, unsigned int glyph) +GlyphData *Font::newGlyphData(Rasterizer *r, const std::string &text) +{ + uint32 codepoint = 0; + + try + { + codepoint = utf8::peek_next(text.begin(), text.end()); + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + return r->getGlyphData(codepoint); +} + +GlyphData *Font::newGlyphData(Rasterizer *r, uint32 glyph) { return r->getGlyphData(glyph); } diff --git a/src/modules/font/freetype/Font.h b/src/modules/font/freetype/Font.h index b58d66589..814ee63b9 100644 --- a/src/modules/font/freetype/Font.h +++ b/src/modules/font/freetype/Font.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -25,15 +25,13 @@ #include "font/Font.h" // FreeType2 -#ifdef LOVE_MACOSX +#ifdef LOVE_MACOSX_USE_FRAMEWORKS #include #else #include #endif -#include -#include -#include -#include +#include FT_FREETYPE_H +#include FT_GLYPH_H namespace love { @@ -56,8 +54,9 @@ public: // Implements Font Rasterizer *newRasterizer(Data *data, int size); Rasterizer *newRasterizer(love::image::ImageData *data, const std::string &text); - Rasterizer *newRasterizer(love::image::ImageData *data, unsigned int *glyphs, int numglyphs); - GlyphData *newGlyphData(Rasterizer *r, unsigned int glyph); + Rasterizer *newRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs); + GlyphData *newGlyphData(Rasterizer *r, const std::string &glyph); + GlyphData *newGlyphData(Rasterizer *r, uint32 glyph); // Implement Module const char *getName() const; @@ -72,4 +71,4 @@ private: } // font } // love -#endif // LOVE_FONT_FREETYPE_FONT_H \ No newline at end of file +#endif // LOVE_FONT_FREETYPE_FONT_H diff --git a/src/modules/font/freetype/TrueTypeRasterizer.cpp b/src/modules/font/freetype/TrueTypeRasterizer.cpp index 3c8ec3740..847793687 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.cpp +++ b/src/modules/font/freetype/TrueTypeRasterizer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -34,11 +34,11 @@ TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, Data *data, int size) : data(data) { if (FT_New_Memory_Face(library, - (const FT_Byte *)data->getData(), /* first byte in memory */ - data->getSize(), /* size in bytes */ - 0, /* face_index */ - &face)) - throw love::Exception("TrueTypeFont Loading error: FT_New_Face failed (there is probably a problem with your font file)\n"); + (const FT_Byte *)data->getData(), /* first byte in memory */ + data->getSize(), /* size in bytes */ + 0, /* face_index */ + &face)) + throw love::Exception("TrueTypeFont Loading error: FT_New_Face failed (there is probably a problem with your font file)"); FT_Set_Pixel_Sizes(face, size, size); @@ -63,54 +63,87 @@ int TrueTypeRasterizer::getLineHeight() const return (int)(getHeight() * 1.25); } -GlyphData *TrueTypeRasterizer::getGlyphData(unsigned int glyph) const +GlyphData *TrueTypeRasterizer::getGlyphData(uint32 glyph) const { - love::font::GlyphMetrics glyphMetrics; + love::font::GlyphMetrics glyphMetrics = {}; FT_Glyph ftglyph; // Initialize if (FT_Load_Glyph(face, FT_Get_Char_Index(face, glyph), FT_LOAD_DEFAULT)) - throw love::Exception("TrueTypeFont Loading vm->error: FT_Load_Glyph failed\n"); + throw love::Exception("TrueTypeFont Loading error: FT_Load_Glyph failed"); if (FT_Get_Glyph(face->glyph, &ftglyph)) - throw love::Exception("TrueTypeFont Loading vm->error: FT_Get_Glyph failed\n"); + throw love::Exception("TrueTypeFont Loading error: FT_Get_Glyph failed"); FT_Glyph_To_Bitmap(&ftglyph, FT_RENDER_MODE_NORMAL, 0, 1); + FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph) ftglyph; FT_Bitmap &bitmap = bitmap_glyph->bitmap; //just to make things easier // Get metrics - glyphMetrics.bearingX = face->glyph->metrics.horiBearingX >> 6; - glyphMetrics.bearingY = face->glyph->metrics.horiBearingY >> 6; + glyphMetrics.bearingX = bitmap_glyph->left; + glyphMetrics.bearingY = bitmap_glyph->top; glyphMetrics.height = bitmap.rows; glyphMetrics.width = bitmap.width; - glyphMetrics.advance = face->glyph->metrics.horiAdvance >> 6; + glyphMetrics.advance = ftglyph->advance.x >> 16; GlyphData *glyphData = new GlyphData(glyph, glyphMetrics, GlyphData::FORMAT_LUMINANCE_ALPHA); - int size = bitmap.rows * bitmap.width; - unsigned char *dst = (unsigned char *) glyphData->getData(); + const uint8 *pixels = bitmap.buffer; + uint8 *dest = (uint8 *) glyphData->getData(); - // Note that bitmap.buffer contains only luminosity. We copy that single value to - // our luminosity-alpha format. - for (int i = 0; i < size; i++) + // We treat the luminance of the FreeType bitmap as alpha in the GlyphData. + if (bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - dst[2*i] = 255; - dst[2*i+1] = bitmap.buffer[i]; + for (int y = 0; y < bitmap.rows; y++) + { + for (int x = 0; x < bitmap.width; x++) + { + // Extract the 1-bit value and convert it to uint8. + uint8 v = ((pixels[x / 8]) & (1 << (7 - (x % 8)))) ? 255 : 0; + dest[2 * (y * bitmap.width + x) + 0] = 255; + dest[2 * (y * bitmap.width + x) + 1] = v; + } + + pixels += bitmap.pitch; + } + } + else if (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) + { + for (int y = 0; y < bitmap.rows; y++) + { + for (int x = 0; x < bitmap.width; x++) + { + dest[2 * (y * bitmap.width + x) + 0] = 255; + dest[2 * (y * bitmap.width + x) + 1] = pixels[x]; + } + + pixels += bitmap.pitch; + } + } + else + { + delete glyphData; + FT_Done_Glyph(ftglyph); + throw love::Exception("Unknown TrueType glyph pixel mode."); } - // Having copied the data over, we can destroy the glyph + // Having copied the data over, we can destroy the glyph. FT_Done_Glyph(ftglyph); - // Return data return glyphData; } -int TrueTypeRasterizer::getNumGlyphs() const +int TrueTypeRasterizer::getGlyphCount() const { return face->num_glyphs; } +bool TrueTypeRasterizer::hasGlyph(uint32 glyph) const +{ + return FT_Get_Char_Index(face, glyph) != 0; +} + } // freetype } // font } // love \ No newline at end of file diff --git a/src/modules/font/freetype/TrueTypeRasterizer.h b/src/modules/font/freetype/TrueTypeRasterizer.h index 848bb4321..5600f324c 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.h +++ b/src/modules/font/freetype/TrueTypeRasterizer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -27,10 +27,8 @@ // TrueType2 #include -#include -#include -#include -#include +#include FT_FREETYPE_H +#include FT_GLYPH_H namespace love { @@ -50,8 +48,9 @@ public: // Implement Rasterizer virtual int getLineHeight() const; - virtual GlyphData *getGlyphData(unsigned int glyph) const; - virtual int getNumGlyphs() const; + virtual GlyphData *getGlyphData(uint32 glyph) const; + virtual int getGlyphCount() const; + virtual bool hasGlyph(uint32 glyph) const; private: @@ -66,4 +65,4 @@ private: } // font } // love -#endif // LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H \ No newline at end of file +#endif // LOVE_FONT_FREETYPE_TRUE_TYPE_RASTERIZER_H diff --git a/src/modules/font/freetype/wrap_Font.cpp b/src/modules/font/freetype/wrap_Font.cpp index 27830fe33..935df7d1c 100644 --- a/src/modules/font/freetype/wrap_Font.cpp +++ b/src/modules/font/freetype/wrap_Font.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -38,9 +38,13 @@ static Font *instance = 0; int w_newRasterizer(lua_State *L) { - Rasterizer *t = NULL; - try - { + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); + + Rasterizer *t = 0; + + EXCEPT_GUARD( if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T)) { love::image::ImageData *d = luax_checktype(L, 1, "ImageData", IMAGE_IMAGE_DATA_T); @@ -54,23 +58,31 @@ int w_newRasterizer(lua_State *L) int size = luaL_checkint(L, 2); t = instance->newRasterizer(d, size); } - } - catch (love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } + ) - luax_newtype(L, "Rasterizer", FONT_RASTERIZER_T, t); + luax_pushtype(L, "Rasterizer", FONT_RASTERIZER_T, t); return 1; } int w_newGlyphData(lua_State *L) { Rasterizer *r = luax_checkrasterizer(L, 1); - unsigned int g = (unsigned int)luaL_checknumber(L, 2); + GlyphData *t = 0; - GlyphData *t = instance->newGlyphData(r, g); - luax_newtype(L, "GlyphData", FONT_GLYPH_DATA_T, t); + // newGlyphData accepts a unicode character or a codepoint number. + if (lua_type(L, 2) == LUA_TSTRING) + { + std::string glyph = luax_checkstring(L, 2); + + EXCEPT_GUARD(t = instance->newGlyphData(r, glyph);) + } + else + { + uint32 g = (uint32) luaL_checknumber(L, 2); + t = instance->newGlyphData(r, g); + } + + luax_pushtype(L, "GlyphData", FONT_GLYPH_DATA_T, t); return 1; } @@ -93,14 +105,7 @@ extern "C" int luaopen_love_font(lua_State *L) { if (instance == 0) { - try - { - instance = new Font(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new Font();) } else instance->retain(); diff --git a/src/modules/font/freetype/wrap_Font.h b/src/modules/font/freetype/wrap_Font.h index 7a8a74b01..6cf7b7b0b 100644 --- a/src/modules/font/freetype/wrap_Font.h +++ b/src/modules/font/freetype/wrap_Font.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/font/wrap_GlyphData.cpp b/src/modules/font/wrap_GlyphData.cpp index b09ce2c36..c71dcb844 100644 --- a/src/modules/font/wrap_GlyphData.cpp +++ b/src/modules/font/wrap_GlyphData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -30,10 +30,107 @@ GlyphData *luax_checkglyphdata(lua_State *L, int idx) return luax_checktype(L, idx, "GlyphData", FONT_GLYPH_DATA_T); } +int w_GlyphData_getWidth(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getWidth()); + return 1; +} + +int w_GlyphData_getHeight(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getHeight()); + return 1; +} + +int w_GlyphData_getDimensions(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getWidth()); + lua_pushinteger(L, t->getHeight()); + return 2; +} + +int w_GlyphData_getGlyph(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + uint32 glyph = t->getGlyph(); + lua_pushnumber(L, (lua_Number) glyph); + return 1; +} + +int w_GlyphData_getGlyphString(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + + EXCEPT_GUARD(luax_pushstring(L, t->getGlyphString());) + return 1; +} + +int w_GlyphData_getAdvance(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getAdvance()); + return 1; +} + +int w_GlyphData_getBearing(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getBearingX()); + lua_pushinteger(L, t->getBearingY()); + return 2; +} + +int w_GlyphData_getBoundingBox(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + + int minX = t->getMinX(); + int minY = t->getMinY(); + int maxX = t->getMaxX(); + int maxY = t->getMaxY(); + + int width = maxX - minX; + int height = maxY - minY; + + lua_pushinteger(L, minX); + lua_pushinteger(L, minY); + lua_pushinteger(L, width); + lua_pushinteger(L, height); + + return 4; +} + +int w_GlyphData_getFormat(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + + const char *str; + if (!GlyphData::getConstant(t->getFormat(), str)) + return luaL_error(L, "unknown GlyphData format."); + + lua_pushstring(L, str); + return 1; +} + static const luaL_Reg functions[] = { + // Data + { "getString", w_Data_getString }, { "getPointer", w_Data_getPointer }, { "getSize", w_Data_getSize }, + + { "getWidth", w_GlyphData_getWidth }, + { "getHeight", w_GlyphData_getHeight }, + { "getDimensions", w_GlyphData_getDimensions }, + { "getGlyph", w_GlyphData_getGlyph }, + { "getGlyphString", w_GlyphData_getGlyphString }, + { "getAdvance", w_GlyphData_getAdvance }, + { "getBearing", w_GlyphData_getBearing }, + { "getBoundingBox", w_GlyphData_getBoundingBox }, + { "getFormat", w_GlyphData_getFormat }, { 0, 0 } }; diff --git a/src/modules/font/wrap_GlyphData.h b/src/modules/font/wrap_GlyphData.h index 40b963b73..72ed79bb0 100644 --- a/src/modules/font/wrap_GlyphData.h +++ b/src/modules/font/wrap_GlyphData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,6 +33,15 @@ namespace font { GlyphData *luax_checkglyphdata(lua_State *L, int idx); +int w_GlyphData_getWidth(lua_State *L); +int w_GlyphData_getHeight(lua_State *L); +int w_GlyphData_getDimensions(lua_State *L); +int w_GlyphData_getGlyph(lua_State *L); +int w_GlyphData_getGlyphString(lua_State *L); +int w_GlyphData_getAdvance(lua_State *L); +int w_GlyphData_getBearing(lua_State *L); +int w_GlyphData_getBoundingBox(lua_State *L); +int w_GlyphData_getFormat(lua_State *L); extern "C" int luaopen_glyphdata(lua_State *L); } // font diff --git a/src/modules/font/wrap_Rasterizer.cpp b/src/modules/font/wrap_Rasterizer.cpp index 169daad7e..0f483a7d9 100644 --- a/src/modules/font/wrap_Rasterizer.cpp +++ b/src/modules/font/wrap_Rasterizer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -32,8 +32,107 @@ Rasterizer *luax_checkrasterizer(lua_State *L, int idx) return luax_checktype(L, idx, "Rasterizer", FONT_RASTERIZER_T); } +int w_Rasterizer_getHeight(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getHeight()); + return 1; +} + +int w_Rasterizer_getAdvance(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getAdvance()); + return 1; +} + +int w_Rasterizer_getAscent(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getAscent()); + return 1; +} + +int w_Rasterizer_getDescent(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getDescent()); + return 1; +} + +int w_Rasterizer_getLineHeight(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getLineHeight()); + return 1; +} + +int w_Rasterizer_getGlyphData(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + GlyphData *g = 0; + + EXCEPT_GUARD( + // getGlyphData accepts a unicode character or a codepoint number. + if (lua_type(L, 2) == LUA_TSTRING) + { + std::string glyph = luax_checkstring(L, 2); + g = t->getGlyphData(glyph); + } + else + { + uint32 glyph = (uint32) luaL_checknumber(L, 2); + g = t->getGlyphData(glyph); + } + ) + + luax_pushtype(L, "GlyphData", FONT_GLYPH_DATA_T, g); + return 1; +} + +int w_Rasterizer_getGlyphCount(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getGlyphCount()); + return 1; +} + +int w_Rasterizer_hasGlyphs(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + + bool hasglyph = false; + + int count = lua_gettop(L) - 1; + count = count < 1 ? 1 : count; + + EXCEPT_GUARD( + for (int i = 2; i < count + 2; i++) + { + if (lua_type(L, i) == LUA_TSTRING) + hasglyph = t->hasGlyphs(luax_checkstring(L, i)); + else + hasglyph = t->hasGlyph((uint32) luaL_checknumber(L, i)); + + if (!hasglyph) + break; + } + ) + + luax_pushboolean(L, hasglyph); + return 1; +} + static const luaL_Reg functions[] = { + { "getHeight", w_Rasterizer_getHeight }, + { "getAdvance", w_Rasterizer_getAdvance }, + { "getAscent", w_Rasterizer_getAscent }, + { "getDescent", w_Rasterizer_getDescent }, + { "getLineHeight", w_Rasterizer_getLineHeight }, + { "getGlyphData", w_Rasterizer_getGlyphData }, + { "getGlyphCount", w_Rasterizer_getGlyphCount }, + { "hasGlyphs", w_Rasterizer_hasGlyphs }, { 0, 0 } }; diff --git a/src/modules/font/wrap_Rasterizer.h b/src/modules/font/wrap_Rasterizer.h index eabb6cdb3..e2b895eed 100644 --- a/src/modules/font/wrap_Rasterizer.h +++ b/src/modules/font/wrap_Rasterizer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -31,6 +31,14 @@ namespace font { Rasterizer *luax_checkrasterizer(lua_State *L, int idx); +int w_Rasterizer_getHeight(lua_State *L); +int w_Rasterizer_getAdvance(lua_State *L); +int w_Rasterizer_getAscent(lua_State *L); +int w_Rasterizer_getDescent(lua_State *L); +int w_Rasterizer_getLineHeight(lua_State *L); +int w_Rasterizer_getGlyphData(lua_State *L); +int w_Rasterizer_getGlyphCount(lua_State *L); +int w_Rasterizer_hasGlyphs(lua_State *L); extern "C" int luaopen_rasterizer(lua_State *L); } // font diff --git a/src/modules/graphics/DrawQable.h b/src/modules/graphics/DrawQable.h deleted file mode 100644 index e6fcec14a..000000000 --- a/src/modules/graphics/DrawQable.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2006-2013 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. - **/ - -#ifndef LOVE_GRAPHICS_DRAWQABLE_H -#define LOVE_GRAPHICS_DRAWQABLE_H - -// LOVE -#include "Drawable.h" -#include "Quad.h" - -namespace love -{ -namespace graphics -{ - -/** - * A DrawQable is anything that be drawn in part with a Quad. - **/ -class DrawQable : public Drawable -{ -public: - - /** - * Destructor. - **/ - virtual ~DrawQable(); - - /** - * Draws the object with the specified transformation. - * - * @param quad The Quad to use to draw the object. - * @param x The position of the object along the x-axis. - * @param y The position of the object along the y-axis. - * @param angle The angle of the object (in radians). - * @param sx The scale factor along the x-axis. - * @param sy The scale factor along the y-axis. - * @param ox The origin offset along the x-axis. - * @param oy The origin offset along the y-axis. - * @param kx Shear along the x-axis. - * @param ky Shear along the y-axis. - **/ - virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0; -}; - -} // graphics -} // love - -#endif // LOVE_GRAPHICS_DRAWQABLE_H diff --git a/src/modules/graphics/Drawable.h b/src/modules/graphics/Drawable.h index d399a0855..aea03b340 100644 --- a/src/modules/graphics/Drawable.h +++ b/src/modules/graphics/Drawable.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -40,7 +40,7 @@ public: /** * Destructor. **/ - virtual ~Drawable(); + virtual ~Drawable() {} /** * Draws the object with the specified transformation. diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 8ac3c26fd..93a13bef7 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -59,16 +59,6 @@ bool Graphics::getConstant(BlendMode in, const char *&out) return blendModes.find(in, out); } -bool Graphics::getConstant(const char *in, ColorMode &out) -{ - return colorModes.find(in, out); -} - -bool Graphics::getConstant(ColorMode in, const char *&out) -{ - return colorModes.find(in, out); -} - bool Graphics::getConstant(const char *in, LineStyle &out) { return lineStyles.find(in, out); @@ -79,6 +69,16 @@ bool Graphics::getConstant(LineStyle in, const char *&out) return lineStyles.find(in, out); } +bool Graphics::getConstant(const char *in, LineJoin &out) +{ + return lineJoins.find(in, out); +} + +bool Graphics::getConstant(LineJoin in, const char *&out) +{ + return lineJoins.find(in, out); +} + bool Graphics::getConstant(const char *in, PointStyle &out) { return pointStyles.find(in, out); @@ -99,6 +99,16 @@ bool Graphics::getConstant(Support in, const char *&out) return support.find(in, out); } +bool Graphics::getConstant(const char *in, RendererInfo &out) +{ + return rendererInfo.find(in, out); +} + +bool Graphics::getConstant(RendererInfo in, const char *&out) +{ + return rendererInfo.find(in, out); +} + StringMap::Entry Graphics::drawModeEntries[] = { { "line", Graphics::DRAW_LINE }, @@ -124,20 +134,11 @@ StringMap::Entry Graphics::blendM { "subtractive", Graphics::BLEND_SUBTRACTIVE }, { "multiplicative", Graphics::BLEND_MULTIPLICATIVE }, { "premultiplied", Graphics::BLEND_PREMULTIPLIED }, - { "none", Graphics::BLEND_NONE }, + { "replace", Graphics::BLEND_REPLACE }, }; StringMap Graphics::blendModes(Graphics::blendModeEntries, sizeof(Graphics::blendModeEntries)); -StringMap::Entry Graphics::colorModeEntries[] = -{ - { "replace", Graphics::COLOR_REPLACE }, - { "modulate", Graphics::COLOR_MODULATE }, - { "combine", Graphics::COLOR_COMBINE }, -}; - -StringMap Graphics::colorModes(Graphics::colorModeEntries, sizeof(Graphics::colorModeEntries)); - StringMap::Entry Graphics::lineStyleEntries[] = { { "smooth", Graphics::LINE_SMOOTH }, @@ -146,6 +147,15 @@ StringMap::Entry Graphics::lineSty StringMap Graphics::lineStyles(Graphics::lineStyleEntries, sizeof(Graphics::lineStyleEntries)); +StringMap::Entry Graphics::lineJoinEntries[] = +{ + { "none", Graphics::LINE_JOIN_NONE }, + { "miter", Graphics::LINE_JOIN_MITER }, + { "bevel", Graphics::LINE_JOIN_BEVEL } +}; + +StringMap Graphics::lineJoins(Graphics::lineJoinEntries, sizeof(Graphics::lineJoinEntries)); + StringMap::Entry Graphics::pointStyleEntries[] = { { "smooth", Graphics::POINT_SMOOTH }, @@ -158,14 +168,26 @@ StringMap::Entry Graphics::suppor { { "canvas", Graphics::SUPPORT_CANVAS }, { "hdrcanvas", Graphics::SUPPORT_HDR_CANVAS }, + { "multicanvas", Graphics::SUPPORT_MULTI_CANVAS }, { "shader", Graphics::SUPPORT_SHADER }, - { "pixeleffect", Graphics::SUPPORT_SHADER }, // for compatibility { "npot", Graphics::SUPPORT_NPOT }, { "subtractive", Graphics::SUPPORT_SUBTRACTIVE }, { "mipmap", Graphics::SUPPORT_MIPMAP }, + { "dxt", Graphics::SUPPORT_DXT }, + { "bc5", Graphics::SUPPORT_BC5 }, }; StringMap Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries)); +StringMap::Entry Graphics::rendererInfoEntries[] = +{ + { "name", Graphics::RENDERER_INFO_NAME }, + { "version", Graphics::RENDERER_INFO_VERSION }, + { "vendor", Graphics::RENDERER_INFO_VENDOR }, + { "device", Graphics::RENDERER_INFO_DEVICE }, +}; + +StringMap Graphics::rendererInfo(Graphics::rendererInfoEntries, sizeof(Graphics::rendererInfoEntries)); + } // graphics } // love diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index bd645c1e7..994e2bed3 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -57,18 +57,10 @@ public: BLEND_SUBTRACTIVE, BLEND_MULTIPLICATIVE, BLEND_PREMULTIPLIED, - BLEND_NONE, + BLEND_REPLACE, BLEND_MAX_ENUM }; - enum ColorMode - { - COLOR_MODULATE = 1, - COLOR_REPLACE, - COLOR_COMBINE, - COLOR_MAX_ENUM - }; - enum LineStyle { LINE_ROUGH = 1, @@ -76,6 +68,14 @@ public: LINE_MAX_ENUM }; + enum LineJoin + { + LINE_JOIN_NONE = 1, + LINE_JOIN_MITER, + LINE_JOIN_BEVEL, + LINE_JOIN_MAX_ENUM + }; + enum PointStyle { POINT_ROUGH = 1, @@ -87,15 +87,45 @@ public: { SUPPORT_CANVAS = 1, SUPPORT_HDR_CANVAS, + SUPPORT_MULTI_CANVAS, SUPPORT_SHADER, SUPPORT_NPOT, SUPPORT_SUBTRACTIVE, SUPPORT_MIPMAP, + SUPPORT_DXT, + SUPPORT_BC5, SUPPORT_MAX_ENUM }; + enum RendererInfo + { + RENDERER_INFO_NAME = 1, + RENDERER_INFO_VERSION, + RENDERER_INFO_VENDOR, + RENDERER_INFO_DEVICE, + RENDERER_INFO_MAX_ENUM + }; + virtual ~Graphics(); + /** + * Sets the current graphics display viewport dimensions. + **/ + virtual void setViewportSize(int width, int height) = 0; + + /** + * Sets the current graphics display viewport and initializes the renderer. + * @param width The viewport width. + * @param height The viewport height. + **/ + virtual bool setMode(int width, int height) = 0; + + /** + * Un-sets the current graphics display mode (uninitializing objects if + * necessary.) + **/ + virtual void unSetMode() = 0; + static bool getConstant(const char *in, DrawMode &out); static bool getConstant(DrawMode in, const char *&out); @@ -105,18 +135,21 @@ public: static bool getConstant(const char *in, BlendMode &out); static bool getConstant(BlendMode in, const char *&out); - static bool getConstant(const char *in, ColorMode &out); - static bool getConstant(ColorMode in, const char *&out); - static bool getConstant(const char *in, LineStyle &out); static bool getConstant(LineStyle in, const char *&out); + static bool getConstant(const char *in, LineJoin &out); + static bool getConstant(LineJoin in, const char *&out); + static bool getConstant(const char *in, PointStyle &out); static bool getConstant(PointStyle in, const char *&out); static bool getConstant(const char *in, Support &out); static bool getConstant(Support in, const char *&out); + static bool getConstant(const char *in, RendererInfo &out); + static bool getConstant(RendererInfo in, const char *&out); + private: static StringMap::Entry drawModeEntries[]; @@ -128,18 +161,21 @@ private: static StringMap::Entry blendModeEntries[]; static StringMap blendModes; - static StringMap::Entry colorModeEntries[]; - static StringMap colorModes; - static StringMap::Entry lineStyleEntries[]; static StringMap lineStyles; + static StringMap::Entry lineJoinEntries[]; + static StringMap lineJoins; + static StringMap::Entry pointStyleEntries[]; static StringMap pointStyles; static StringMap::Entry supportEntries[]; static StringMap support; + static StringMap::Entry rendererInfoEntries[]; + static StringMap rendererInfo; + }; // Graphics } // graphics diff --git a/src/modules/graphics/Image.cpp b/src/modules/graphics/Image.cpp deleted file mode 100644 index 52c37a180..000000000 --- a/src/modules/graphics/Image.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright (c) 2006-2013 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. - **/ - -#include "Image.h" - -namespace love -{ -namespace graphics -{ - -Image::Filter Image::defaultFilter; - -Image::Filter::Filter() - : min(FILTER_LINEAR) - , mag(FILTER_LINEAR) - , mipmap(FILTER_NONE) -{ -} - -Image::Wrap::Wrap() - : s(WRAP_CLAMP) - , t(WRAP_CLAMP) -{ -} - -Image::~Image() -{ -} - -void Image::setDefaultFilter(const Filter &f) -{ - defaultFilter = f; -} - -const Image::Filter &Image::getDefaultFilter() -{ - return defaultFilter; -} - -bool Image::getConstant(const char *in, FilterMode &out) -{ - return filterModes.find(in, out); -} - -bool Image::getConstant(FilterMode in, const char *&out) -{ - return filterModes.find(in, out); -} - -bool Image::getConstant(const char *in, WrapMode &out) -{ - return wrapModes.find(in, out); -} - -bool Image::getConstant(WrapMode in, const char *&out) -{ - return wrapModes.find(in, out); -} - -StringMap::Entry Image::filterModeEntries[] = -{ - { "linear", Image::FILTER_LINEAR }, - { "nearest", Image::FILTER_NEAREST }, -}; - -StringMap Image::filterModes(Image::filterModeEntries, sizeof(Image::filterModeEntries)); - -StringMap::Entry Image::wrapModeEntries[] = -{ - { "clamp", Image::WRAP_CLAMP }, - { "repeat", Image::WRAP_REPEAT }, -}; - -StringMap Image::wrapModes(Image::wrapModeEntries, sizeof(Image::wrapModeEntries)); - - -} // graphics -} // love diff --git a/src/modules/graphics/Quad.cpp b/src/modules/graphics/Quad.cpp index 8394db60a..4f0ba472c 100644 --- a/src/modules/graphics/Quad.cpp +++ b/src/modules/graphics/Quad.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,20 +18,66 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "Quad.h" +// C +#include // For memcpy + namespace love { namespace graphics { -Quad::Quad() +Quad::Quad(const Quad::Viewport &v, float sw, float sh) + : sw(sw) + , sh(sh) { + memset(vertices, 255, sizeof(Vertex) * NUM_VERTICES); + refresh(v, sw, sh); } Quad::~Quad() { } +void Quad::refresh(const Quad::Viewport &v, float sw, float sh) +{ + viewport = v; + + vertices[0].x = 0; + vertices[0].y = 0; + vertices[1].x = 0; + vertices[1].y = v.h; + vertices[2].x = v.w; + vertices[2].y = v.h; + vertices[3].x = v.w; + vertices[3].y = 0; + + vertices[0].s = v.x/sw; + vertices[0].t = v.y/sh; + vertices[1].s = v.x/sw; + vertices[1].t = (v.y+v.h)/sh; + vertices[2].s = (v.x+v.w)/sw; + vertices[2].t = (v.y+v.h)/sh; + vertices[3].s = (v.x+v.w)/sw; + vertices[3].t = v.y/sh; +} + +void Quad::setViewport(const Quad::Viewport &v) +{ + refresh(v, sw, sh); +} + +Quad::Viewport Quad::getViewport() const +{ + return viewport; +} + +const Vertex *Quad::getVertices() const +{ + return vertices; +} + } // graphics } // love diff --git a/src/modules/graphics/Quad.h b/src/modules/graphics/Quad.h index ef7e7477b..d8c5ca884 100644 --- a/src/modules/graphics/Quad.h +++ b/src/modules/graphics/Quad.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,25 +36,31 @@ public: struct Viewport { - float x, y, w, h; + float x, y; + float w, h; }; - Quad(); + static const size_t NUM_VERTICES = 4; + Quad(const Viewport &v, float sw, float sh); virtual ~Quad(); - virtual void refresh(const Viewport &v, float sw, float sh) = 0; + void refresh(const Viewport &v, float sw, float sh); + void setViewport(const Viewport &v); + Viewport getViewport() const; - virtual void setViewport(const Viewport &v) = 0; - virtual Viewport getViewport() const = 0; + const Vertex *getVertices() const; - virtual void flip(bool x, bool y) = 0; +private: + + Vertex vertices[NUM_VERTICES]; + + Viewport viewport; + float sw; + float sh; + +}; // Quad - /** - * Gets a pointer to the vertices. - **/ - virtual const vertex *getVertices() const = 0; -}; } // graphics } // love diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp new file mode 100644 index 000000000..25034a3d0 --- /dev/null +++ b/src/modules/graphics/Texture.cpp @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "Texture.h" + +namespace love +{ +namespace graphics +{ + +Texture::Filter Texture::defaultFilter; + +Texture::Filter::Filter() + : min(FILTER_LINEAR) + , mag(FILTER_LINEAR) + , mipmap(FILTER_NONE) + , anisotropy(1.0f) +{ +} + +Texture::Wrap::Wrap() + : s(WRAP_CLAMP) + , t(WRAP_CLAMP) +{ +} + +Texture::Texture() + : width(0) + , height(0) + , filter(getDefaultFilter()) + , wrap() + , vertices() +{ +} + +Texture::~Texture() +{ +} + +int Texture::getWidth() const +{ + return width; +} + +int Texture::getHeight() const +{ + return height; +} + +const Texture::Filter &Texture::getFilter() const +{ + return filter; +} + +const Texture::Wrap &Texture::getWrap() const +{ + return wrap; +} + +const Vertex *Texture::getVertices() const +{ + return vertices; +} + +void Texture::setDefaultFilter(const Filter &f) +{ + defaultFilter = f; +} + +const Texture::Filter &Texture::getDefaultFilter() +{ + return defaultFilter; +} + +bool Texture::getConstant(const char *in, FilterMode &out) +{ + return filterModes.find(in, out); +} + +bool Texture::getConstant(FilterMode in, const char *&out) +{ + return filterModes.find(in, out); +} + +bool Texture::getConstant(const char *in, WrapMode &out) +{ + return wrapModes.find(in, out); +} + +bool Texture::getConstant(WrapMode in, const char *&out) +{ + return wrapModes.find(in, out); +} + +StringMap::Entry Texture::filterModeEntries[] = +{ + { "linear", Texture::FILTER_LINEAR }, + { "nearest", Texture::FILTER_NEAREST }, +}; + +StringMap Texture::filterModes(Texture::filterModeEntries, sizeof(Texture::filterModeEntries)); + +StringMap::Entry Texture::wrapModeEntries[] = +{ + { "clamp", Texture::WRAP_CLAMP }, + { "repeat", Texture::WRAP_REPEAT }, +}; + +StringMap Texture::wrapModes(Texture::wrapModeEntries, sizeof(Texture::wrapModeEntries)); + + +} // graphics +} // love diff --git a/src/modules/graphics/Image.h b/src/modules/graphics/Texture.h similarity index 54% rename from src/modules/graphics/Image.h rename to src/modules/graphics/Texture.h index 2203293d7..e87c432f4 100644 --- a/src/modules/graphics/Image.h +++ b/src/modules/graphics/Texture.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,35 +18,40 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_IMAGE_H -#define LOVE_GRAPHICS_IMAGE_H +#ifndef LOVE_GRAPHICS_TEXTURE_H +#define LOVE_GRAPHICS_TEXTURE_H // LOVE -#include "graphics/Volatile.h" -#include "graphics/DrawQable.h" #include "common/StringMap.h" +#include "common/math.h" +#include "Drawable.h" +#include "Quad.h" namespace love { namespace graphics { -class Image : public DrawQable, public Volatile +/** + * Base class for 2D textures. All textures can be drawn with Quads, have a + * width and height, and have filter and wrap modes. + **/ +class Texture : public Drawable { public: enum WrapMode { - WRAP_CLAMP = 1, + WRAP_CLAMP, WRAP_REPEAT, WRAP_MAX_ENUM }; enum FilterMode { - FILTER_LINEAR = 1, - FILTER_NEAREST, FILTER_NONE, + FILTER_LINEAR, + FILTER_NEAREST, FILTER_MAX_ENUM }; @@ -56,6 +61,7 @@ public: FilterMode min; FilterMode mag; FilterMode mipmap; + float anisotropy; }; struct Wrap @@ -65,30 +71,70 @@ public: WrapMode t; }; - virtual ~Image(); - + Texture(); + virtual ~Texture(); + + /** + * Draws the texture using the specified transformation with a Quad applied. + * + * @param quad The Quad object to use to draw the object. + * @param x The position of the object along the x-axis. + * @param y The position of the object along the y-axis. + * @param angle The angle of the object (in radians). + * @param sx The scale factor along the x-axis. + * @param sy The scale factor along the y-axis. + * @param ox The origin offset along the x-axis. + * @param oy The origin offset along the y-axis. + * @param kx Shear along the x-axis. + * @param ky Shear along the y-axis. + **/ + virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0; + + virtual int getWidth() const; + virtual int getHeight() const; + + virtual void setFilter(const Filter &f) = 0; + virtual const Filter &getFilter() const; + + virtual void setWrap(const Wrap &w) = 0; + virtual const Wrap &getWrap() const; + + virtual const Vertex *getVertices() const; + // The default filter. static void setDefaultFilter(const Filter &f); static const Filter &getDefaultFilter(); static bool getConstant(const char *in, FilterMode &out); static bool getConstant(FilterMode in, const char *&out); + static bool getConstant(const char *in, WrapMode &out); static bool getConstant(WrapMode in, const char *&out); +protected: + + int width; + int height; + + Filter filter; + Wrap wrap; + + Vertex vertices[4]; + private: - // The default image filter + // The default texture filter. static Filter defaultFilter; static StringMap::Entry filterModeEntries[]; static StringMap filterModes; + static StringMap::Entry wrapModeEntries[]; static StringMap wrapModes; -}; // Image +}; // Texture } // graphics } // love -#endif // LOVE_GRAPHICS_IMAGE_H +#endif // LOVE_GRAPHICS_TEXTURE_H diff --git a/src/modules/graphics/Volatile.cpp b/src/modules/graphics/Volatile.cpp index fa505e7d6..920d8668d 100644 --- a/src/modules/graphics/Volatile.cpp +++ b/src/modules/graphics/Volatile.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/graphics/Volatile.h b/src/modules/graphics/Volatile.h index 34b2f8be6..8fa1e412e 100644 --- a/src/modules/graphics/Volatile.h +++ b/src/modules/graphics/Volatile.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 27de68d70..855830dd1 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,10 +19,13 @@ **/ #include "Canvas.h" +#include "Image.h" #include "Graphics.h" #include "common/Matrix.h" +#include "common/config.h" #include // For memcpy +#include namespace love { @@ -35,33 +38,52 @@ namespace opengl // none, opengl >= 3.0, extensions struct FramebufferStrategy { - /// create a new framebuffer, depth_stencil and texture + virtual ~FramebufferStrategy() {} + + /// create a new framebuffer and texture /** - * @param[out] framebuffer Framebuffer name - * @param[out] depth_stencil Name for packed depth and stencil buffer - * @param[out] img Texture name - * @param[in] width Width of framebuffer - * @param[in] height Height of framebuffer - * @param[in] texture_type Type of the canvas texture. + * @param[out] framebuffer Framebuffer name + * @param[in] texture Texture name * @return Creation status */ - virtual GLenum createFBO(GLuint &, GLuint &, GLuint &, int, int, Canvas::TextureType) + virtual GLenum createFBO(GLuint &, GLuint) { return GL_FRAMEBUFFER_UNSUPPORTED; } + + /// Create a stencil buffer and attach it to the active framebuffer object + /** + * @param[in] width Width of the stencil buffer + * @param[in] height Height of the stencil buffer + * @param[out] stencil Name for stencil buffer + * @return Whether the stencil buffer was successfully created + **/ + virtual bool createStencil(int, int, GLuint &) + { + return false; + } + /// remove objects /** * @param[in] framebuffer Framebuffer name * @param[in] depth_stencil Name for packed depth and stencil buffer - * @param[in] img Texture name */ - virtual void deleteFBO(GLuint, GLuint, GLuint) {} + virtual void deleteFBO(GLuint, GLuint) {} virtual void bindFBO(GLuint) {} + + /// attach additional canvases to the active framebuffer for rendering + /** + * @param[in] canvases List of canvases to attach + **/ + virtual void setAttachments(const std::vector &) {} + + /// stop using all additional attached canvases + virtual void setAttachments() {} }; struct FramebufferStrategyGL3 : 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 texture) { // get currently bound fbo to reset to it later GLint current_fbo; @@ -71,65 +93,83 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - // create stencil buffer - glGenRenderbuffers(1, &depth_stencil); - glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, depth_stencil); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, depth_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); - - setTextureFilter(Image::getDefaultFilter()); - - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, - 0, GL_RGBA, format, NULL); - bindTexture(0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, img, 0); + GL_TEXTURE_2D, texture, 0); // check status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // unbind framebuffer - glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, (GLuint) current_fbo); return status; } - virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img) + + virtual bool createStencil(int width, int height, GLuint &stencil) { - deleteTexture(img); - glDeleteRenderbuffers(1, &depth_stencil); - glDeleteFramebuffers(1, &framebuffer); + // create combined depth/stencil buffer + glDeleteRenderbuffers(1, &stencil); + glGenRenderbuffers(1, &stencil); + glBindRenderbuffer(GL_RENDERBUFFER, stencil); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, stencil); + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + // check status + return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; + } + + virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil) + { + if (depth_stencil != 0) + glDeleteRenderbuffers(1, &depth_stencil); + if (framebuffer != 0) + glDeleteFramebuffers(1, &framebuffer); } virtual void bindFBO(GLuint framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); } + + virtual void setAttachments() + { + // set a single render target + glDrawBuffer(GL_COLOR_ATTACHMENT0); + } + + virtual void setAttachments(const std::vector &canvases) + { + if (canvases.size() == 0) + { + setAttachments(); + return; + } + + std::vector drawbuffers; + drawbuffers.push_back(GL_COLOR_ATTACHMENT0); + + // Attach the canvas textures to the currently bound framebuffer. + for (size_t i = 0; i < canvases.size(); i++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 + i, + GL_TEXTURE_2D, canvases[i]->getGLTexture(), 0); + drawbuffers.push_back(GL_COLOR_ATTACHMENT1 + i); + } + + // set up multiple render targets + if (GLEE_VERSION_2_0) + glDrawBuffers(drawbuffers.size(), &drawbuffers[0]); + else if (GLEE_ARB_draw_buffers) + glDrawBuffersARB(drawbuffers.size(), &drawbuffers[0]); + } }; 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 texture) { GLint current_fbo; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, ¤t_fbo); @@ -138,123 +178,104 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy glGenFramebuffersEXT(1, &framebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); - // create stencil buffer - glGenRenderbuffersEXT(1, &depth_stencil); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, - width, height); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_stencil); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_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); - - setTextureFilter(Image::getDefaultFilter()); - - 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); + GL_TEXTURE_2D, texture, 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; } - virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img) + virtual bool createStencil(int width, int height, GLuint &stencil) { - deleteTexture(img); - glDeleteRenderbuffersEXT(1, &depth_stencil); - glDeleteFramebuffersEXT(1, &framebuffer); + // create combined depth/stencil buffer + glDeleteRenderbuffers(1, &stencil); + glGenRenderbuffersEXT(1, &stencil); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, + width, height); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, stencil); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + + // check status + return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT; + } + + virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil) + { + if (depth_stencil != 0) + glDeleteRenderbuffersEXT(1, &depth_stencil); + if (framebuffer != 0) + glDeleteFramebuffersEXT(1, &framebuffer); } virtual void bindFBO(GLuint framebuffer) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); } + + virtual void setAttachments() + { + // set a single render target + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + } + + virtual void setAttachments(const std::vector &canvases) + { + if (canvases.size() == 0) + { + setAttachments(); + return; + } + + std::vector drawbuffers; + drawbuffers.push_back(GL_COLOR_ATTACHMENT0_EXT); + + // Attach the canvas textures to the currently bound framebuffer. + for (size_t i = 0; i < canvases.size(); i++) + { + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT + i, + GL_TEXTURE_2D, canvases[i]->getGLTexture(), 0); + drawbuffers.push_back(GL_COLOR_ATTACHMENT1_EXT + i); + } + + // set up multiple render targets + if (GLEE_VERSION_2_0) + glDrawBuffers(drawbuffers.size(), &drawbuffers[0]); + else if (GLEE_ARB_draw_buffers) + glDrawBuffersARB(drawbuffers.size(), &drawbuffers[0]); + } }; struct FramebufferStrategyEXT : public FramebufferStrategyPackedEXT { - virtual GLenum createFBO(GLuint &framebuffer, GLuint &stencil, GLuint &img, int width, int height, Canvas::TextureType texture_type) + virtual bool createStencil(int width, int height, GLuint &stencil) { - GLint current_fbo; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, ¤t_fbo); - - // create framebuffer - glGenFramebuffersEXT(1, &framebuffer); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); - // create stencil buffer + glDeleteRenderbuffers(1, &stencil); glGenRenderbuffersEXT(1, &stencil); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, - width, height); + width, height); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, stencil); + 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); - - setTextureFilter(Image::getDefaultFilter()); - - 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); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 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; + return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT; } bool isSupported() { - GLuint fb, stencil, img; - GLenum status = createFBO(fb, stencil, img, 2, 2, Canvas::TYPE_NORMAL); - deleteFBO(fb, stencil, img); + GLuint fb = 0, stencil = 0; + GLenum status = createFBO(fb, 0); + deleteFBO(fb, stencil); return status == GL_FRAMEBUFFER_COMPLETE; } }; @@ -270,6 +291,7 @@ FramebufferStrategyPackedEXT strategyPackedEXT; FramebufferStrategyEXT strategyEXT; Canvas *Canvas::current = NULL; +OpenGL::Viewport Canvas::systemViewport = OpenGL::Viewport(); static void getStrategy() { @@ -286,23 +308,30 @@ static void getStrategy() } } +static int maxFBOColorAttachments = 0; +static int maxDrawBuffers = 0; + Canvas::Canvas(int width, int height, TextureType texture_type) - : width(width) - , height(height) + : fbo(0) + , texture(0) + , depth_stencil(0) , texture_type(texture_type) { + this->width = width; + this->height = height; + float w = static_cast(width); float h = static_cast(height); // world coordinates vertices[0].x = 0; - vertices[0].y = h; + vertices[0].y = 0; vertices[1].x = 0; - vertices[1].y = 0; + vertices[1].y = h; vertices[2].x = w; - vertices[2].y = 0; + vertices[2].y = h; vertices[3].x = w; - vertices[3].y = h; + vertices[3].y = 0; // texture coordinates vertices[0].s = 0; @@ -314,8 +343,6 @@ Canvas::Canvas(int width, int height, TextureType texture_type) vertices[3].s = 1; vertices[3].t = 0; - settings.filter = Image::getDefaultFilter(); - getStrategy(); loadVolatile(); @@ -330,24 +357,142 @@ Canvas::~Canvas() unloadVolatile(); } -bool Canvas::isSupported() +bool Canvas::loadVolatile() { - getStrategy(); - return (strategy != &strategyNone); + fbo = depth_stencil = texture = 0; + + // glTexImage2D is guaranteed to error in this case. + if (width > gl.getMaxTextureSize() || height > gl.getMaxTextureSize()) + { + status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + return false; + } + + glGenTextures(1, &texture); + gl.bindTexture(texture); + + setFilter(filter); + setWrap(wrap); + + GLint internalformat; + GLenum textype; + switch (texture_type) + { + case TYPE_HDR: + internalformat = GL_RGBA16F; + textype = GL_FLOAT; + break; + case TYPE_NORMAL: + default: + internalformat = GL_RGBA8; + textype = GL_UNSIGNED_BYTE; + } + + while (glGetError() != GL_NO_ERROR) + /* Clear the error buffer. */; + + glTexImage2D(GL_TEXTURE_2D, + 0, + internalformat, + width, height, + 0, + GL_RGBA, + textype, + nullptr); + + if (glGetError() != GL_NO_ERROR) + { + status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + return false; + } + + status = strategy->createFBO(fbo, texture); + if (status != GL_FRAMEBUFFER_COMPLETE) + return false; + + clear(Color(0, 0, 0, 0)); + return true; } -bool Canvas::isHdrSupported() +void Canvas::unloadVolatile() { - return GLEE_VERSION_3_0 || GLEE_ARB_texture_float; + strategy->deleteFBO(fbo, depth_stencil); + + gl.deleteTexture(texture); + + fbo = depth_stencil = texture = 0; + + for (size_t i = 0; i < attachedCanvases.size(); i++) + attachedCanvases[i]->release(); + + attachedCanvases.clear(); } -void Canvas::bindDefaultCanvas() +void Canvas::drawv(const Matrix &t, const Vertex *v) const { - if (current != NULL) - current->stopGrab(); + glPushMatrix(); + + glMultMatrixf((const GLfloat *)t.getElements()); + + gl.bindTexture(texture); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s); + + gl.prepareDraw(); + glDrawArrays(GL_QUADS, 0, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glPopMatrix(); } -void Canvas::startGrab() +void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +{ + static Matrix t; + t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + + drawv(t, vertices); +} + +void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +{ + static Matrix t; + t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + + const Vertex *v = quad->getVertices(); + drawv(t, v); +} + +void Canvas::setFilter(const Texture::Filter &f) +{ + filter = f; + gl.bindTexture(texture); + gl.setTextureFilter(filter); +} + +void Canvas::setWrap(const Texture::Wrap &w) +{ + wrap = w; + gl.bindTexture(texture); + gl.setTextureWrap(wrap); +} + +GLuint Canvas::getGLTexture() const +{ + return texture; +} + +void Canvas::predraw() const +{ + gl.bindTexture(texture); +} + +void Canvas::setupGrab() { // already grabbing if (current == this) @@ -357,10 +502,10 @@ void Canvas::startGrab() if (current != NULL) current->stopGrab(); - // bind buffer and clear screen - glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT); + // bind the framebuffer object. + systemViewport = gl.getViewport(); strategy->bindFBO(fbo); - glViewport(0, 0, width, height); + gl.setViewport(OpenGL::Viewport(0, 0, width, height)); // Reset the projection matrix glMatrixMode(GL_PROJECTION); @@ -368,7 +513,7 @@ void Canvas::startGrab() glLoadIdentity(); // 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 glMatrixMode(GL_MODELVIEW); @@ -377,6 +522,68 @@ void Canvas::startGrab() current = this; } +void Canvas::startGrab(const std::vector &canvases) +{ + // Whether the new canvas list is different from the old one. + // A more thorough check is done below. + bool canvaseschanged = canvases.size() != attachedCanvases.size(); + + if (canvases.size() > 0) + { + if (!isMultiCanvasSupported()) + throw love::Exception("Multi-canvas rendering is not supported on this system."); + + if (canvases.size()+1 > size_t(maxDrawBuffers) || canvases.size()+1 > size_t(maxFBOColorAttachments)) + throw love::Exception("This system can't simultaniously render to %d canvases.", canvases.size()+1); + } + + for (size_t i = 0; i < canvases.size(); i++) + { + if (canvases[i]->getWidth() != width || canvases[i]->getHeight() != height) + throw love::Exception("All canvas arguments must have the same dimensions."); + + if (canvases[i]->getTextureType() != texture_type) + throw love::Exception("All canvas arguments must have the same texture type."); + + if (!canvaseschanged && canvases[i] != attachedCanvases[i]) + canvaseschanged = true; + } + + setupGrab(); + + // Don't attach anything if there's nothing to change. + if (!canvaseschanged) + return; + + // Attach the canvas textures to the active FBO and set up MRTs. + strategy->setAttachments(canvases); + + for (size_t i = 0; i < canvases.size(); i++) + canvases[i]->retain(); + + for (size_t i = 0; i < attachedCanvases.size(); i++) + attachedCanvases[i]->release(); + + attachedCanvases = canvases; +} + +void Canvas::startGrab() +{ + setupGrab(); + + if (attachedCanvases.size() == 0) + return; + + // make sure the FBO is only using a single canvas + strategy->setAttachments(); + + // release any previously attached canvases + for (size_t i = 0; i < attachedCanvases.size(); i++) + attachedCanvases[i]->release(); + + attachedCanvases.clear(); +} + void Canvas::stopGrab() { // i am not grabbing. leave me alone @@ -387,48 +594,82 @@ void Canvas::stopGrab() strategy->bindFBO(0); glMatrixMode(GL_PROJECTION); glPopMatrix(); - glPopAttrib(); - current = NULL; + glMatrixMode(GL_MODELVIEW); + + current = nullptr; + + gl.setViewport(systemViewport); } - -void Canvas::clear(const Color &c) +void Canvas::clear(Color c) { + if (strategy == &strategyNone) + return; + GLuint previous = 0; - if (current != NULL) - previous = current->fbo; - strategy->bindFBO(fbo); - glPushAttrib(GL_COLOR_BUFFER_BIT); - glClearColor((float)c.r/255.0f, (float)c.g/255.0f, (float)c.b/255.0f, (float)c.a/255.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glPopAttrib(); + if (current != this) + { + if (current != nullptr) + previous = current->fbo; - strategy->bindFBO(previous); + strategy->bindFBO(fbo); + } + + GLfloat glcolor[] = {c.r/255.f, c.g/255.f, c.b/255.f, c.a/255.f}; + + // We don't need to worry about multiple FBO attachments or global clear + // color state when OpenGL 3.0+ is supported. + if (GLEE_VERSION_3_0) + { + glClearBufferfv(GL_COLOR, 0, glcolor); + + if (depth_stencil != 0) + { + GLint stencilvalue = 0; + glClearBufferiv(GL_STENCIL, 0, &stencilvalue); + } + } + else + { + // glClear will clear all active draw buffers, so we need to temporarily + // detach any other canvases (when MRT is being used.) + if (attachedCanvases.size() > 0) + strategy->setAttachments(); + + // Don't use the state-shadowed gl.setClearColor because we want to save + // the previous clear color. + glClearColor(glcolor[0], glcolor[1], glcolor[2], glcolor[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + if (attachedCanvases.size() > 0) + strategy->setAttachments(attachedCanvases); + + // Restore the global clear color. + gl.setClearColor(gl.getClearColor()); + } + + if (current != this) + strategy->bindFBO(previous); } -void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +bool Canvas::checkCreateStencil() { - static Matrix t; - t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + // Do nothing if we've already created the stencil buffer. + if (depth_stencil != 0) + return true; - drawv(t, vertices); -} + if (current != this) + strategy->bindFBO(fbo); -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 -{ - const vertex *v = quad->getVertices(); + bool success = strategy->createStencil(width, height, depth_stencil); - // mirror quad on x axis - vertex w[4]; - memcpy(w, v, sizeof(vertex)*4); - for (size_t i = 0; i < 4; ++i) - w[i].t = 1. - w[i].t; + if (current && current != this) + strategy->bindFBO(current->fbo); + else if (!current) + strategy->bindFBO(0); - static Matrix t; - t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); - - drawv(t, w); + return success; } love::image::ImageData *Canvas::getImageData(love::image::Image *image) @@ -436,7 +677,6 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image) int row = 4 * width; int size = row * height; GLubyte *pixels = new GLubyte[size]; - GLubyte *flipped = new GLubyte[size]; strategy->bindFBO(fbo); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); @@ -445,103 +685,54 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image) else strategy->bindFBO(0); - GLubyte *src = pixels, *dst = flipped + size - row; - for (int i = 0; i < height; ++i, dst -= row, src += row) - { - memcpy(dst, src, row); - } - - love::image::ImageData *img = image->newImageData(width, height, (void *)flipped); - - delete[] pixels; - + // The new ImageData now owns the pixel data, so we don't delete it here. + love::image::ImageData *img = image->newImageData(width, height, (void *)pixels, true); return img; } void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y) { - strategy->bindFBO( fbo ); + if (current != this) + strategy->bindFBO(fbo); glReadPixels(x, height - y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_rgba); - if (current) - strategy->bindFBO( current->fbo ); - else - strategy->bindFBO( 0 ); + if (current && current != this) + strategy->bindFBO(current->fbo); + else if (!current) + strategy->bindFBO(0); } -void Canvas::setFilter(const Image::Filter &f) +bool Canvas::isSupported() { - bindTexture(img); - setTextureFilter(f); + getStrategy(); + return (strategy != &strategyNone); } -Image::Filter Canvas::getFilter() const +bool Canvas::isHDRSupported() { - bindTexture(img); - return getTextureFilter(); + return GLEE_VERSION_3_0 || (isSupported() && GLEE_ARB_texture_float); } -void Canvas::setWrap(const Image::Wrap &w) +bool Canvas::isMultiCanvasSupported() { - bindTexture(img); - setTextureWrap(w); -} - -Image::Wrap Canvas::getWrap() const -{ - bindTexture(img); - return getTextureWrap(); -} - -bool Canvas::loadVolatile() -{ - status = strategy->createFBO(fbo, depth_stencil, img, width, height, texture_type); - if (status != GL_FRAMEBUFFER_COMPLETE) + if (!(isSupported() && (GLEE_VERSION_2_0 || GLEE_ARB_draw_buffers))) return false; - setFilter(settings.filter); - setWrap(settings.wrap); - Color c; - c.r = c.g = c.b = c.a = 0; - clear(c); - return true; + if (maxFBOColorAttachments == 0 || maxDrawBuffers == 0) + { + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxFBOColorAttachments); + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); + } + + // system must support at least 4 simultanious active canvases + return maxFBOColorAttachments >= 4 && maxDrawBuffers >= 4; } -void Canvas::unloadVolatile() +void Canvas::bindDefaultCanvas() { - settings.filter = getFilter(); - settings.wrap = getWrap(); - strategy->deleteFBO(fbo, depth_stencil, img); -} - -int Canvas::getWidth() -{ - return width; -} - -int Canvas::getHeight() -{ - return height; -} - -void Canvas::drawv(const Matrix &t, const vertex *v) const -{ - glPushMatrix(); - - glMultMatrixf((const GLfloat *)t.getElements()); - - bindTexture(img); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].x); - glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].s); - glDrawArrays(GL_QUADS, 0, 4); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glPopMatrix(); + if (current != nullptr) + current->stopGrab(); } bool Canvas::getConstant(const char *in, Canvas::TextureType &out) diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index 81162e68e..e9e9f7ca0 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,14 +21,11 @@ #ifndef LOVE_GRAPHICS_OPENGL_CANVAS_H #define LOVE_GRAPHICS_OPENGL_CANVAS_H -#include "graphics/DrawQable.h" -#include "graphics/Volatile.h" -#include "graphics/Image.h" #include "graphics/Color.h" #include "image/Image.h" #include "image/ImageData.h" -#include "common/math.h" #include "common/Matrix.h" +#include "Texture.h" #include "OpenGL.h" namespace love @@ -38,10 +35,12 @@ namespace graphics namespace opengl { -class Canvas : public DrawQable, public Volatile +class Canvas : public Texture { public: - enum TextureType { + + enum TextureType + { TYPE_NORMAL, TYPE_HDR, TYPE_MAX_ENUM @@ -50,78 +49,81 @@ public: Canvas(int width, int height, TextureType texture_type = TYPE_NORMAL); virtual ~Canvas(); + // Implements Volatile. + virtual bool loadVolatile(); + virtual void unloadVolatile(); + + // Implements Drawable. + virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + + // Implements Texture. + virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + virtual void setFilter(const Texture::Filter &f); + virtual void setWrap(const Texture::Wrap &w); + virtual GLuint getGLTexture() const; + virtual void predraw() const; + + /** + * @param canvases A list of other canvases to temporarily attach to this one, + * to allow drawing to multiple canvases at once. + **/ + void startGrab(const std::vector &canvases); void startGrab(); void stopGrab(); - void clear(const Color &c); - - virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + void clear(Color c); /** - * @copydoc DrawQable::drawq() + * Create and attach a stencil buffer to this Canvas' framebuffer, if necessary. **/ - void drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + bool checkCreateStencil(); love::image::ImageData *getImageData(love::image::Image *image); void getPixel(unsigned char* pixel_rgba, int x, int y); - void setFilter(const Image::Filter &f); - Image::Filter getFilter() const; + inline const std::vector &getAttachedCanvases() const + { + return attachedCanvases; + } - void setWrap(const Image::Wrap &w); - Image::Wrap getWrap() const; - - int getWidth(); - int getHeight(); - - unsigned int getStatus() const + inline GLenum getStatus() const { return status; } - TextureType getTextureType() const + inline TextureType getTextureType() const { return texture_type; } - bool loadVolatile(); - void unloadVolatile(); - static bool isSupported(); - static bool isHdrSupported(); + static bool isHDRSupported(); + static bool isMultiCanvasSupported(); + static bool getConstant(const char *in, TextureType &out); static bool getConstant(TextureType in, const char *&out); static Canvas *current; static void bindDefaultCanvas(); -private: - friend class Shader; - GLuint getTextureName() const - { - return img; - } + // The viewport dimensions of the system (default) framebuffer. + static OpenGL::Viewport systemViewport; + +private: - GLsizei width; - GLsizei height; GLuint fbo; + GLuint texture; GLuint depth_stencil; - GLuint img; TextureType texture_type; - vertex vertices[4]; - GLenum status; - struct - { - Image::Filter filter; - Image::Wrap wrap; - } settings; + std::vector attachedCanvases; - void drawv(const Matrix &t, const vertex *v) const; + void setupGrab(); + void drawv(const Matrix &t, const Vertex *v) const; static StringMap::Entry textureTypeEntries[]; static StringMap textureTypes; diff --git a/src/modules/graphics/opengl/Font.cpp b/src/modules/graphics/opengl/Font.cpp index 94e8896e9..2b4bf8750 100644 --- a/src/modules/graphics/opengl/Font.cpp +++ b/src/modules/graphics/opengl/Font.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -20,8 +20,6 @@ #include "common/config.h" #include "Font.h" #include "font/GlyphData.h" -#include "Quad.h" -#include "Image.h" #include "libraries/utf8/utf8.h" @@ -42,35 +40,40 @@ namespace opengl const int Font::TEXTURE_WIDTHS[] = {128, 256, 256, 512, 512, 1024, 1024}; const int Font::TEXTURE_HEIGHTS[] = {128, 128, 256, 256, 512, 512, 1024}; -Font::Font(love::font::Rasterizer *r, const Image::Filter &filter) +Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter) : rasterizer(r) , height(r->getHeight()) , lineHeight(1) , mSpacing(1) , filter(filter) { - // try to find the best texture size match for the font size - // default to the largest texture size if no rough match is found - texture_size_index = NUM_TEXTURE_SIZES - 1; + this->filter.mipmap = Texture::FILTER_NONE; + + // Try to find the best texture size match for the font size. default to the + // largest texture size if no rough match is found. + textureSizeIndex = NUM_TEXTURE_SIZES - 1; for (int i = 0; i < NUM_TEXTURE_SIZES; i++) { - // base our chosen texture width/height on a very rough guess of the total size taken up by the font's used glyphs - // the estimate is likely larger than the actual total size taken up, which is good since texture changes are expensive + // Make a rough estimate of the total used texture size, based on glyph + // height. The estimated size is likely larger than the actual total + // size, which is good because texture switching is expensive. if ((height * 0.8) * height * 95 <= TEXTURE_WIDTHS[i] * TEXTURE_HEIGHTS[i]) { - texture_size_index = i; + textureSizeIndex = i; break; } } - texture_width = TEXTURE_WIDTHS[texture_size_index]; - texture_height = TEXTURE_HEIGHTS[texture_size_index]; + textureWidth = TEXTURE_WIDTHS[textureSizeIndex]; + textureHeight = TEXTURE_HEIGHTS[textureSizeIndex]; love::font::GlyphData *gd = 0; try { gd = r->getGlyphData(32); + type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA) ? FONT_TRUETYPE : FONT_IMAGE; + loadVolatile(); } catch (love::Exception &) @@ -79,7 +82,6 @@ Font::Font(love::font::Rasterizer *r, const Image::Filter &filter) throw; } - type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA) ? FONT_TRUETYPE : FONT_IMAGE; delete gd; rasterizer->retain(); @@ -91,7 +93,7 @@ Font::~Font() unloadVolatile(); } -bool Font::initializeTexture(GLint format) +bool Font::initializeTexture(GLenum format) { GLint internalformat = (format == GL_LUMINANCE_ALPHA) ? GL_LUMINANCE8_ALPHA8 : GL_RGBA8; @@ -101,8 +103,8 @@ bool Font::initializeTexture(GLint format) glTexImage2D(GL_TEXTURE_2D, 0, internalformat, - (GLsizei)texture_width, - (GLsizei)texture_height, + (GLsizei)textureWidth, + (GLsizei)textureHeight, 0, format, GL_UNSIGNED_BYTE, @@ -113,13 +115,13 @@ bool Font::initializeTexture(GLint format) void Font::createTexture() { - texture_x = texture_y = rowHeight = TEXTURE_PADDING; + textureX = textureY = rowHeight = TEXTURE_PADDING; GLuint t; glGenTextures(1, &t); textures.push_back(t); - bindTexture(t); + gl.bindTexture(t); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -127,40 +129,40 @@ void Font::createTexture() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - GLint format = (type == FONT_TRUETYPE ? GL_LUMINANCE_ALPHA : GL_RGBA); + GLenum format = (type == FONT_TRUETYPE ? GL_LUMINANCE_ALPHA : GL_RGBA); - // try to initialize the texture, attempting smaller sizes if initialization fails + // Initialize the texture, attempting smaller sizes if initialization fails. bool initialized = false; - while (texture_size_index >= 0) + while (textureSizeIndex >= 0) { - texture_width = TEXTURE_WIDTHS[texture_size_index]; - texture_height = TEXTURE_HEIGHTS[texture_size_index]; + textureWidth = TEXTURE_WIDTHS[textureSizeIndex]; + textureHeight = TEXTURE_HEIGHTS[textureSizeIndex]; initialized = initializeTexture(format); - if (initialized || texture_size_index <= 0) + if (initialized || textureSizeIndex <= 0) break; - --texture_size_index; + --textureSizeIndex; } if (!initialized) { - // cleanup before throwing - deleteTexture(t); - bindTexture(0); + // Clean up before throwing. + gl.deleteTexture(t); + gl.bindTexture(0); textures.pop_back(); throw love::Exception("Could not create font texture!"); } - - // Fill the texture with transparent black - std::vector emptyData(texture_width * texture_height * (type == FONT_TRUETYPE ? 2 : 4), 0); + + // Fill the texture with transparent black. + std::vector emptyData(textureWidth * textureHeight * (type == FONT_TRUETYPE ? 2 : 4), 0); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - (GLsizei)texture_width, - (GLsizei)texture_height, + (GLsizei)textureWidth, + (GLsizei)textureHeight, format, GL_UNSIGNED_BYTE, &emptyData[0]); @@ -168,20 +170,20 @@ void Font::createTexture() setFilter(filter); } -Font::Glyph *Font::addGlyph(unsigned int glyph) +Font::Glyph *Font::addGlyph(uint32 glyph) { love::font::GlyphData *gd = rasterizer->getGlyphData(glyph); int w = gd->getWidth(); int h = gd->getHeight(); - if (texture_x + w + TEXTURE_PADDING > texture_width) + if (textureX + w + TEXTURE_PADDING > textureWidth) { // out of space - new row! - texture_x = TEXTURE_PADDING; - texture_y += rowHeight; + textureX = TEXTURE_PADDING; + textureY += rowHeight; rowHeight = TEXTURE_PADDING; } - if (texture_y + h + TEXTURE_PADDING > texture_height) + if (textureY + h + TEXTURE_PADDING > textureHeight) { // totally out of space - new texture! createTexture(); @@ -192,18 +194,18 @@ Font::Glyph *Font::addGlyph(unsigned int glyph) g->texture = 0; g->spacing = gd->getAdvance(); - memset(&g->quad, 0, sizeof(GlyphQuad)); + memset(g->vertices, 0, sizeof(GlyphVertex) * 4); // don't waste space for empty glyphs. also fixes a division by zero bug with ati drivers if (w > 0 && h > 0) { const GLuint t = textures.back(); - bindTexture(t); + gl.bindTexture(t); glTexSubImage2D(GL_TEXTURE_2D, 0, - texture_x, - texture_y, + textureX, + textureY, w, h, (type == FONT_TRUETYPE ? GL_LUMINANCE_ALPHA : GL_RGBA), GL_UNSIGNED_BYTE, @@ -211,26 +213,24 @@ Font::Glyph *Font::addGlyph(unsigned int glyph) g->texture = t; - Quad::Viewport v; - v.x = (float) texture_x; - v.y = (float) texture_y; - v.w = (float) w; - v.h = (float) h; - - Quad q = Quad(v, (const float) texture_width, (const float) texture_height); - const vertex *verts = q.getVertices(); + const GlyphVertex verts[4] = { + { 0.0f, 0.0f, float(textureX)/float(textureWidth), float(textureY)/float(textureHeight)}, + { 0.0f, float(h), float(textureX)/float(textureWidth), float(textureY+h)/float(textureHeight)}, + {float(w), float(h), float(textureX+w)/float(textureWidth), float(textureY+h)/float(textureHeight)}, + {float(w), 0.0f, float(textureX+w)/float(textureWidth), float(textureY)/float(textureHeight)}, + }; // copy vertex data to the glyph and set proper bearing for (int i = 0; i < 4; i++) { - g->quad.vertices[i] = verts[i]; - g->quad.vertices[i].x += gd->getBearingX(); - g->quad.vertices[i].y -= gd->getBearingY(); + g->vertices[i] = verts[i]; + g->vertices[i].x += gd->getBearingX(); + g->vertices[i].y -= gd->getBearingY(); } } if (w > 0) - texture_x += (w + TEXTURE_PADDING); + textureX += (w + TEXTURE_PADDING); if (h > 0) rowHeight = std::max(rowHeight, h + TEXTURE_PADDING); @@ -241,13 +241,14 @@ Font::Glyph *Font::addGlyph(unsigned int glyph) return g; } -Font::Glyph *Font::findGlyph(unsigned int glyph) +Font::Glyph *Font::findGlyph(uint32 glyph) { - Glyph *g = glyphs[glyph]; - if (!g) - g = addGlyph(glyph); + auto it = glyphs.find(glyph); - return g; + if (it != glyphs.end()) + return it->second; + else + return addGlyph(glyph); } float Font::getHeight() const @@ -255,24 +256,22 @@ float Font::getHeight() const return static_cast(height); } -void Font::print(const std::string &text, float x, float y, float letter_spacing, float angle, float sx, float sy, float ox, float oy, float kx, float ky) +void Font::print(const std::string &text, float x, float y, float extra_spacing, float angle, float sx, float sy, float ox, float oy, float kx, float ky) { - float dx = 0.0f; // spacing counter for newline handling + // Spacing counter and newline handling. + float dx = 0.0f; float dy = 0.0f; - // keeps track of when we need to switch textures in our vertex array + float lineheight = getBaseline(); + + // Keeps track of when we need to switch textures in our vertex array. std::vector glyphinfolist; - std::vector glyphquads; - glyphquads.reserve(text.size()); // pre-allocate space for the maximum possible number of quads + // Pre-allocate space for the maximum possible number of vertices. + std::vector glyphverts; + glyphverts.reserve(text.length() * 4); - int quadindex = 0; - - glPushMatrix(); - - Matrix t; - t.setTransformation(ceil(x), ceil(y), angle, sx, sy, ox, oy, kx, ky); - glMultMatrixf((const GLfloat *)t.getElements()); + int vertexcount = 0; try { @@ -281,92 +280,89 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing while (i != end) { - unsigned int g = *i++; + uint32 g = *i++; if (g == '\n') { - // wrap newline, but do not print it - dy += floor(getHeight() * getLineHeight() + 0.5f); + // Wrap newline, but do not print it. + dy += floorf(getHeight() * getLineHeight() + 0.5f); dx = 0.0f; continue; } Glyph *glyph = findGlyph(g); - // we only care about the vertices of glyphs which have a texture if (glyph->texture != 0) { - // copy glyphquad (4 vertices) from original glyph to our current quad list - glyphquads.push_back(glyph->quad); - - float lineheight = getBaseline(); - - // set proper relative position - for (int i = 0; i < 4; i++) + // Copy the vertices and set their proper relative positions. + for (int j = 0; j < 4; j++) { - glyphquads[quadindex].vertices[i].x += dx; - glyphquads[quadindex].vertices[i].y += dy + lineheight; + glyphverts.push_back(glyph->vertices[j]); + glyphverts.back().x += dx; + glyphverts.back().y += dy + lineheight; } - size_t listsize = glyphinfolist.size(); - - // check if current glyph texture has changed since the previous iteration - if (listsize == 0 || glyphinfolist[listsize-1].texture != glyph->texture) + // Check if glyph texture has changed since the last iteration. + if (glyphinfolist.size() == 0 || glyphinfolist.back().texture != glyph->texture) { // keep track of each sub-section of the string whose glyphs use different textures than the previous section - GlyphArrayDrawInfo glyphdrawinfo; - glyphdrawinfo.startquad = quadindex; - glyphdrawinfo.numquads = 0; - glyphdrawinfo.texture = glyph->texture; - glyphinfolist.push_back(glyphdrawinfo); + GlyphArrayDrawInfo gdrawinfo; + gdrawinfo.startvertex = vertexcount; + gdrawinfo.vertexcount = 0; + gdrawinfo.texture = glyph->texture; + glyphinfolist.push_back(gdrawinfo); } - ++quadindex; - ++glyphinfolist[glyphinfolist.size()-1].numquads; + vertexcount += 4; + glyphinfolist.back().vertexcount += 4; } - // advance the x position for the next glyph - dx += glyph->spacing + letter_spacing; + // Advance the x position for the next glyph. + dx += glyph->spacing; + + // Account for extra spacing given to space characters. + if (g == ' ' && extra_spacing != 0.0f) + dx = floorf(dx + extra_spacing); } } - catch (love::Exception &) - { - glPopMatrix(); - throw; - } catch (utf8::exception &e) { - glPopMatrix(); - throw love::Exception("%s", e.what()); + throw love::Exception("Decoding error: %s", e.what()); } - - if (quadindex > 0 && glyphinfolist.size() > 0) + + if (vertexcount <= 0 || glyphinfolist.size() == 0) + return; + + // Sort glyph draw info list by texture first, and quad position in memory + // second (using the struct's < operator). + std::sort(glyphinfolist.begin(), glyphinfolist.end()); + + glPushMatrix(); + + Matrix t; + t.setTransformation(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky); + glMultMatrixf((const GLfloat *)t.getElements()); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(GlyphVertex), (GLvoid *)&glyphverts[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(GlyphVertex), (GLvoid *)&glyphverts[0].s); + + gl.prepareDraw(); + + // We need to draw a new vertex array for every section of the string which + // uses a different texture than the previous section. + std::vector::const_iterator it; + for (it = glyphinfolist.begin(); it != glyphinfolist.end(); ++it) { - // sort glyph draw info list by texture first, and quad position in memory second (using the struct's < operator) - std::sort(glyphinfolist.begin(), glyphinfolist.end()); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&glyphquads[0].vertices[0].x); - glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&glyphquads[0].vertices[0].s); - - // we need to draw a new vertex array for every section of the string that uses a different texture than the previous section - std::vector::const_iterator it; - for (it = glyphinfolist.begin(); it != glyphinfolist.end(); ++it) - { - bindTexture(it->texture); - - int startvertex = it->startquad * 4; - int numvertices = it->numquads * 4; - - glDrawArrays(GL_QUADS, startvertex, numvertices); - } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); + gl.bindTexture(it->texture); + glDrawArrays(GL_QUADS, it->startvertex, it->vertexcount); } + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glPopMatrix(); } @@ -388,14 +384,14 @@ int Font::getWidth(const std::string &str) utf8::iterator end(line.end(), line.begin(), line.end()); while (i != end) { - unsigned int c = *i++; + uint32 c = *i++; g = findGlyph(c); width += static_cast(g->spacing * mSpacing); } } catch(utf8::exception &e) { - throw love::Exception("%s", e.what()); + throw love::Exception("Decoding error: %s", e.what()); } if (width > max_width) @@ -405,18 +401,13 @@ int Font::getWidth(const std::string &str) return max_width; } -int Font::getWidth(const char *str) -{ - return this->getWidth(std::string(str)); -} - -int Font::getWidth(unsigned int character) +int Font::getWidth(char character) { Glyph *g = findGlyph(character); return g->spacing; } -std::vector Font::getWrap(const std::string &text, float wrap, int *max_width) +std::vector Font::getWrap(const std::string &text, float wrap, int *max_width, std::vector *wrappedlines) { using namespace std; const float width_space = static_cast(getWidth(' ')); @@ -446,7 +437,7 @@ std::vector Font::getWrap(const std::string &text, float wrap, int width += getWidth(word); // on wordwrap, push line to line buffer and clear string builder - if (width >= wrap && oldwidth > 0) + if (width > wrap && oldwidth > 0) { int realw = (int) width; @@ -458,6 +449,10 @@ std::vector Font::getWrap(const std::string &text, float wrap, int realw -= (int) width; if (realw > maxw) maxw = realw; + + // Indicate that this line was automatically wrapped. + if (wrappedlines) + wrappedlines->push_back(true); } string_builder << word << " "; width += width_space; @@ -468,6 +463,10 @@ std::vector Font::getWrap(const std::string &text, float wrap, int maxw = (int) width; string tmp = string_builder.str(); lines_to_draw.push_back(tmp.substr(0,tmp.size()-1)); + + // Indicate that this line was not automatically wrapped. + if (wrappedlines) + wrappedlines->push_back(false); } if (max_width) @@ -496,19 +495,18 @@ float Font::getSpacing() const return mSpacing; } -void Font::setFilter(const Image::Filter &f) +void Font::setFilter(const Texture::Filter &f) { filter = f; - std::vector::const_iterator it; - for (it = textures.begin(); it != textures.end(); ++it) + for (auto it = textures.begin(); it != textures.end(); ++it) { - bindTexture(*it); - setTextureFilter(f); + gl.bindTexture(*it); + gl.setTextureFilter(filter); } } -const Image::Filter &Font::getFilter() +const Texture::Filter &Font::getFilter() { return filter; } @@ -522,7 +520,7 @@ bool Font::loadVolatile() void Font::unloadVolatile() { // nuke everything from orbit - std::map::iterator it = glyphs.begin(); + std::map::iterator it = glyphs.begin(); Glyph *g; while (it != glyphs.end()) { @@ -533,7 +531,7 @@ void Font::unloadVolatile() std::vector::iterator iter = textures.begin(); while (iter != textures.end()) { - deleteTexture(*iter); + gl.deleteTexture(*iter); iter++; } textures.clear(); @@ -552,7 +550,17 @@ int Font::getDescent() const float Font::getBaseline() const { // 1.25 is magic line height for true type fonts - return (type == FONT_TRUETYPE) ? floor(getHeight() / 1.25f + 0.5f) : 0.0f; + return (type == FONT_TRUETYPE) ? floorf(getHeight() / 1.25f + 0.5f) : 0.0f; +} + +bool Font::hasGlyph(uint32 glyph) const +{ + return rasterizer->hasGlyph(glyph); +} + +bool Font::hasGlyphs(const std::string &text) const +{ + return rasterizer->hasGlyphs(text); } } // opengl diff --git a/src/modules/graphics/opengl/Font.h b/src/modules/graphics/opengl/Font.h index 9a157e551..1d92bac63 100644 --- a/src/modules/graphics/opengl/Font.h +++ b/src/modules/graphics/opengl/Font.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,7 +29,8 @@ // LOVE #include "common/Object.h" #include "font/Rasterizer.h" -#include "graphics/Image.h" +#include "graphics/Texture.h" +#include "graphics/Volatile.h" #include "OpenGL.h" @@ -44,12 +45,7 @@ class Font : public Object, public Volatile { public: - /** - * Default constructor. - * - * @param data The font data to construct from. - **/ - Font(love::font::Rasterizer *r, const Image::Filter &filter = Image::getDefaultFilter()); + Font(love::font::Rasterizer *r, const Texture::Filter &filter = Texture::getDefaultFilter()); virtual ~Font(); @@ -59,7 +55,7 @@ public: * @param text A string. * @param x The x-coordinate. * @param y The y-coordinate. - * @param letter_spacing Additional spacing between letters. + * @param extra_spacing Additional spacing added to spaces (" "). * @param angle The amount of rotation. * @param sx Scale along the x axis. * @param sy Scale along the y axis. @@ -68,7 +64,7 @@ public: * @param kx Shear along the x axis. * @param ky Shear along the y axis. **/ - void print(const std::string &text, float x, float y, float letter_spacing = 0.0f, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f, float ox = 0.0f, float oy = 0.0f, float kx = 0.0f, float ky = 0.0f); + void print(const std::string &text, float x, float y, float extra_spacing = 0.0f, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f, float ox = 0.0f, float oy = 0.0f, float kx = 0.0f, float ky = 0.0f); /** * Returns the height of the font. @@ -81,14 +77,13 @@ public: * @param str A string of text. **/ int getWidth(const std::string &str); - int getWidth(const char *str); /** * Returns the width of the passed character. * * @param character A character. **/ - int getWidth(unsigned int character); + int getWidth(char character); /** * Returns the maximal width of a wrapped string @@ -97,9 +92,11 @@ public: * @param text The input text * @param wrap The number of pixels to wrap at * @param max_width Optional output of the maximum width + * @param wrapped_lines Optional output indicating which lines were + * auto-wrapped. Indices correspond to indices of the returned value. * Returns a vector with the lines. **/ - std::vector getWrap(const std::string &text, float wrap, int *max_width = 0); + std::vector getWrap(const std::string &text, float wrap, int *max_width = 0, std::vector *wrapped_lines = 0); /** * Sets the line height (which should be a number to multiply the font size by, @@ -126,8 +123,8 @@ public: **/ float getSpacing() const; - void setFilter(const Image::Filter &f); - const Image::Filter &getFilter(); + void setFilter(const Texture::Filter &f); + const Texture::Filter &getFilter(); // Implements Volatile. bool loadVolatile(); @@ -138,6 +135,9 @@ public: int getDescent() const; float getBaseline() const; + bool hasGlyph(uint32 glyph) const; + bool hasGlyphs(const std::string &text) const; + private: enum FontType @@ -146,25 +146,26 @@ private: FONT_IMAGE, FONT_UNKNOWN }; - - // thin wrapper for an array of 4 vertices - struct GlyphQuad + + struct GlyphVertex { - vertex vertices[4]; + float x, y; + float s, t; }; struct Glyph { GLuint texture; int spacing; - GlyphQuad quad; + GlyphVertex vertices[4]; }; // used to determine when to change textures in the vertex array generated when printing text struct GlyphArrayDrawInfo { GLuint texture; - int startquad, numquads; + int startvertex; + int vertexcount; // used when sorting with std::sort // sorts by texture first (binding textures is expensive) and relative position in memory second @@ -173,24 +174,33 @@ private: if (texture != other.texture) return texture < other.texture; else - return startquad < other.startquad; + return startvertex < other.startvertex; }; }; + bool initializeTexture(GLenum format); + void createTexture(); + Glyph *addGlyph(uint32 glyph); + Glyph *findGlyph(uint32 glyph); + love::font::Rasterizer *rasterizer; int height; float lineHeight; float mSpacing; // modifies the spacing by multiplying it with this value - int texture_size_index; - int texture_width; - int texture_height; + int textureSizeIndex; + int textureWidth; + int textureHeight; + + // vector of packed textures + std::vector textures; + + // maps glyphs to glyph texture information + std::map glyphs; - std::vector textures; // vector of packed textures - std::map glyphs; // maps glyphs to quad information FontType type; - Image::Filter filter; + Texture::Filter filter; static const int NUM_TEXTURE_SIZES = 7; static const int TEXTURE_WIDTHS[NUM_TEXTURE_SIZES]; @@ -198,13 +208,9 @@ private: static const int TEXTURE_PADDING = 1; - int texture_x, texture_y; + int textureX, textureY; int rowHeight; - bool initializeTexture(GLint format); - void createTexture(); - Glyph *addGlyph(unsigned int glyph); - Glyph *findGlyph(unsigned int glyph); }; // Font } // opengl diff --git a/src/modules/graphics/opengl/GLee.c b/src/modules/graphics/opengl/GLee.c index 63c559d8c..01f6279d9 100644 --- a/src/modules/graphics/opengl/GLee.c +++ b/src/modules/graphics/opengl/GLee.c @@ -43,7 +43,12 @@ #include "GLee.h" #if defined(__APPLE__) || defined(__APPLE_CC__) - #include +#define GLEE_USE_SDL +#ifdef GLEE_USE_SDL + #include +#else + #include +#endif #endif typedef GLuint(*GLEE_LINK_FUNCTION)(void); @@ -64,6 +69,9 @@ GLEE_FUNC __GLeeGetProcAddress(const char *extname) #ifdef _WIN32 return (GLEE_FUNC)wglGetProcAddress(extname); #elif defined(__APPLE__) || defined(__APPLE_CC__) +#if defined(GLEE_USE_SDL) + return SDL_GL_GetProcAddress(extname); +#else CFBundleRef bundle; CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true); @@ -72,7 +80,13 @@ GLEE_FUNC __GLeeGetProcAddress(const char *extname) GLEE_FUNC function; bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); - assert(bundle != NULL); + + if (bundle == NULL) + { + CFRelease(bundleURL); + CFRelease(functionName); + return NULL; + } function = CFBundleGetFunctionPointerForName(bundle, functionName); @@ -81,6 +95,7 @@ GLEE_FUNC __GLeeGetProcAddress(const char *extname) CFRelease(bundle); return function; +#endif #else return (GLEE_FUNC)glXGetProcAddressARB((const GLubyte *)extname); #endif @@ -105,6 +120,7 @@ GLboolean _GLEE_VERSION_3_3 = GL_FALSE; GLboolean _GLEE_VERSION_4_0 = GL_FALSE; GLboolean _GLEE_VERSION_4_1 = GL_FALSE; GLboolean _GLEE_VERSION_4_2 = GL_FALSE; +GLboolean _GLEE_VERSION_4_3 = GL_FALSE; GLboolean _GLEE_ARB_multitexture = GL_FALSE; GLboolean _GLEE_ARB_transpose_matrix = GL_FALSE; GLboolean _GLEE_ARB_multisample = GL_FALSE; @@ -195,6 +211,7 @@ GLboolean _GLEE_ARB_shader_precision = GL_FALSE; GLboolean _GLEE_ARB_vertex_attrib_64bit = GL_FALSE; GLboolean _GLEE_ARB_viewport_array = GL_FALSE; GLboolean _GLEE_ARB_cl_event = GL_FALSE; +GLboolean _GLEE_ARB_debug_output = GL_FALSE; GLboolean _GLEE_ARB_robustness = GL_FALSE; GLboolean _GLEE_ARB_shader_stencil_export = GL_FALSE; GLboolean _GLEE_ARB_base_instance = GL_FALSE; @@ -208,6 +225,30 @@ GLboolean _GLEE_ARB_shader_atomic_counters = GL_FALSE; GLboolean _GLEE_ARB_shader_image_load_store = GL_FALSE; GLboolean _GLEE_ARB_shading_language_packing = GL_FALSE; GLboolean _GLEE_ARB_texture_storage = GL_FALSE; +GLboolean _GLEE_KHR_texture_compression_astc_ldr = GL_FALSE; +GLboolean _GLEE_KHR_debug = GL_FALSE; +GLboolean _GLEE_ARB_arrays_of_arrays = GL_FALSE; +GLboolean _GLEE_ARB_clear_buffer_object = GL_FALSE; +GLboolean _GLEE_ARB_compute_shader = GL_FALSE; +GLboolean _GLEE_ARB_copy_image = GL_FALSE; +GLboolean _GLEE_ARB_texture_view = GL_FALSE; +GLboolean _GLEE_ARB_vertex_attrib_binding = GL_FALSE; +GLboolean _GLEE_ARB_robustness_isolation = GL_FALSE; +GLboolean _GLEE_ARB_ES3_compatibility = GL_FALSE; +GLboolean _GLEE_ARB_explicit_uniform_location = GL_FALSE; +GLboolean _GLEE_ARB_fragment_layer_viewport = GL_FALSE; +GLboolean _GLEE_ARB_framebuffer_no_attachments = GL_FALSE; +GLboolean _GLEE_ARB_internalformat_query2 = GL_FALSE; +GLboolean _GLEE_ARB_invalidate_subdata = GL_FALSE; +GLboolean _GLEE_ARB_multi_draw_indirect = GL_FALSE; +GLboolean _GLEE_ARB_program_interface_query = GL_FALSE; +GLboolean _GLEE_ARB_robust_buffer_access_behavior = GL_FALSE; +GLboolean _GLEE_ARB_shader_image_size = GL_FALSE; +GLboolean _GLEE_ARB_shader_storage_buffer_object = GL_FALSE; +GLboolean _GLEE_ARB_stencil_texturing = GL_FALSE; +GLboolean _GLEE_ARB_texture_buffer_range = GL_FALSE; +GLboolean _GLEE_ARB_texture_query_levels = GL_FALSE; +GLboolean _GLEE_ARB_texture_storage_multisample = GL_FALSE; GLboolean _GLEE_EXT_abgr = GL_FALSE; GLboolean _GLEE_EXT_blend_color = GL_FALSE; GLboolean _GLEE_EXT_polygon_offset = GL_FALSE; @@ -411,7 +452,12 @@ GLboolean _GLEE_NV_vertex_program2 = GL_FALSE; GLboolean _GLEE_ATI_map_object_buffer = GL_FALSE; GLboolean _GLEE_ATI_separate_stencil = GL_FALSE; GLboolean _GLEE_ATI_vertex_attrib_array_object = GL_FALSE; +GLboolean _GLEE_OES_byte_coordinates = GL_FALSE; +GLboolean _GLEE_OES_fixed_point = GL_FALSE; +GLboolean _GLEE_OES_single_precision = GL_FALSE; +GLboolean _GLEE_OES_compressed_paletted_texture = GL_FALSE; GLboolean _GLEE_OES_read_format = GL_FALSE; +GLboolean _GLEE_OES_query_matrix = GL_FALSE; GLboolean _GLEE_EXT_depth_bounds_test = GL_FALSE; GLboolean _GLEE_EXT_texture_mirror_clamp = GL_FALSE; GLboolean _GLEE_EXT_blend_equation_separate = GL_FALSE; @@ -492,6 +538,7 @@ GLboolean _GLEE_NV_tessellation_program5 = GL_FALSE; GLboolean _GLEE_NV_vertex_attrib_integer_64bit = GL_FALSE; GLboolean _GLEE_NV_multisample_coverage = GL_FALSE; GLboolean _GLEE_AMD_name_gen_delete = GL_FALSE; +GLboolean _GLEE_AMD_debug_output = GL_FALSE; GLboolean _GLEE_AMD_transform_feedback3_lines_triangles = GL_FALSE; GLboolean _GLEE_AMD_depth_clamp_separate = GL_FALSE; GLboolean _GLEE_EXT_texture_sRGB_decode = GL_FALSE; @@ -501,30 +548,31 @@ GLboolean _GLEE_AMD_sample_positions = GL_FALSE; GLboolean _GLEE_EXT_x11_sync_object = GL_FALSE; GLboolean _GLEE_AMD_multi_draw_indirect = GL_FALSE; GLboolean _GLEE_EXT_framebuffer_multisample_blit_scaled = GL_FALSE; +GLboolean _GLEE_NV_path_rendering = GL_FALSE; +GLboolean _GLEE_AMD_pinned_memory = GL_FALSE; +GLboolean _GLEE_AMD_stencil_operation_extended = GL_FALSE; +GLboolean _GLEE_AMD_vertex_shader_viewport_index = GL_FALSE; +GLboolean _GLEE_AMD_vertex_shader_layer = GL_FALSE; +GLboolean _GLEE_NV_bindless_texture = GL_FALSE; +GLboolean _GLEE_NV_shader_atomic_float = GL_FALSE; +GLboolean _GLEE_AMD_query_buffer_object = GL_FALSE; +GLboolean _GLEE_NV_compute_program5 = GL_FALSE; +GLboolean _GLEE_NV_shader_storage_buffer_object = GL_FALSE; +GLboolean _GLEE_NV_shader_atomic_counters = GL_FALSE; +GLboolean _GLEE_NV_deep_texture3D = GL_FALSE; +GLboolean _GLEE_NVX_conditional_render = GL_FALSE; +GLboolean _GLEE_AMD_sparse_texture = GL_FALSE; +GLboolean _GLEE_AMD_shader_trinary_minmax = GL_FALSE; +GLboolean _GLEE_INTEL_map_texture = GL_FALSE; +GLboolean _GLEE_NV_draw_texture = GL_FALSE; GLboolean _GLEE_SGIX_texture_select = GL_FALSE; GLboolean _GLEE_INGR_blend_func_separate = GL_FALSE; GLboolean _GLEE_SGIX_depth_pass_instrument = GL_FALSE; GLboolean _GLEE_SGIX_igloo_interface = GL_FALSE; -GLboolean _GLEE_OES_compressed_paletted_texture = GL_FALSE; -GLboolean _GLEE_OES_fixed_point = GL_FALSE; -GLboolean _GLEE_OES_single_precision = GL_FALSE; -GLboolean _GLEE_OES_query_matrix = GL_FALSE; -GLboolean _GLEE_OES_byte_coordinates = GL_FALSE; -GLboolean _GLEE_NV_gpu_program4 = GL_FALSE; -GLboolean _GLEE_NV_path_rendering = GL_FALSE; -GLboolean _GLEE_AMD_vertex_shader_tessellator = GL_FALSE; -GLboolean _GLEE_EXT_fragment_lighting = GL_FALSE; -GLboolean _GLEE_EXT_texture_compression_dxt1 = GL_FALSE; -GLboolean _GLEE_EXT_scene_marker = GL_FALSE; -GLboolean _GLEE_EXT_geometry_shader4 = GL_FALSE; -GLboolean _GLEE_EXT_texture_env = GL_FALSE; -GLboolean _GLEE_SGIX_texture_range = GL_FALSE; -GLboolean _GLEE_SGIX_pixel_texture_bits = GL_FALSE; -GLboolean _GLEE_IBM_static_data = GL_FALSE; /* GL Extension names */ -char __GLeeGLExtensionNames[430][43]={ +char __GLeeGLExtensionNames[463][43]={ "GL_VERSION_1_2", "GL_ARB_imaging", "GL_VERSION_1_3", @@ -539,6 +587,7 @@ char __GLeeGLExtensionNames[430][43]={ "GL_VERSION_4_0", "GL_VERSION_4_1", "GL_VERSION_4_2", + "GL_VERSION_4_3", "GL_ARB_multitexture", "GL_ARB_transpose_matrix", "GL_ARB_multisample", @@ -629,6 +678,7 @@ char __GLeeGLExtensionNames[430][43]={ "GL_ARB_vertex_attrib_64bit", "GL_ARB_viewport_array", "GL_ARB_cl_event", + "GL_ARB_debug_output", "GL_ARB_robustness", "GL_ARB_shader_stencil_export", "GL_ARB_base_instance", @@ -642,6 +692,30 @@ char __GLeeGLExtensionNames[430][43]={ "GL_ARB_shader_image_load_store", "GL_ARB_shading_language_packing", "GL_ARB_texture_storage", + "GL_KHR_texture_compression_astc_ldr", + "GL_KHR_debug", + "GL_ARB_arrays_of_arrays", + "GL_ARB_clear_buffer_object", + "GL_ARB_compute_shader", + "GL_ARB_copy_image", + "GL_ARB_texture_view", + "GL_ARB_vertex_attrib_binding", + "GL_ARB_robustness_isolation", + "GL_ARB_ES3_compatibility", + "GL_ARB_explicit_uniform_location", + "GL_ARB_fragment_layer_viewport", + "GL_ARB_framebuffer_no_attachments", + "GL_ARB_internalformat_query2", + "GL_ARB_invalidate_subdata", + "GL_ARB_multi_draw_indirect", + "GL_ARB_program_interface_query", + "GL_ARB_robust_buffer_access_behavior", + "GL_ARB_shader_image_size", + "GL_ARB_shader_storage_buffer_object", + "GL_ARB_stencil_texturing", + "GL_ARB_texture_buffer_range", + "GL_ARB_texture_query_levels", + "GL_ARB_texture_storage_multisample", "GL_EXT_abgr", "GL_EXT_blend_color", "GL_EXT_polygon_offset", @@ -845,7 +919,12 @@ char __GLeeGLExtensionNames[430][43]={ "GL_ATI_map_object_buffer", "GL_ATI_separate_stencil", "GL_ATI_vertex_attrib_array_object", + "GL_OES_byte_coordinates", + "GL_OES_fixed_point", + "GL_OES_single_precision", + "GL_OES_compressed_paletted_texture", "GL_OES_read_format", + "GL_OES_query_matrix", "GL_EXT_depth_bounds_test", "GL_EXT_texture_mirror_clamp", "GL_EXT_blend_equation_separate", @@ -926,6 +1005,7 @@ char __GLeeGLExtensionNames[430][43]={ "GL_NV_vertex_attrib_integer_64bit", "GL_NV_multisample_coverage", "GL_AMD_name_gen_delete", + "GL_AMD_debug_output", "GL_AMD_transform_feedback3_lines_triangles", "GL_AMD_depth_clamp_separate", "GL_EXT_texture_sRGB_decode", @@ -935,35 +1015,36 @@ char __GLeeGLExtensionNames[430][43]={ "GL_EXT_x11_sync_object", "GL_AMD_multi_draw_indirect", "GL_EXT_framebuffer_multisample_blit_scaled", + "GL_NV_path_rendering", + "GL_AMD_pinned_memory", + "GL_AMD_stencil_operation_extended", + "GL_AMD_vertex_shader_viewport_index", + "GL_AMD_vertex_shader_layer", + "GL_NV_bindless_texture", + "GL_NV_shader_atomic_float", + "GL_AMD_query_buffer_object", + "GL_NV_compute_program5", + "GL_NV_shader_storage_buffer_object", + "GL_NV_shader_atomic_counters", + "GL_NV_deep_texture3D", + "GL_NVX_conditional_render", + "GL_AMD_sparse_texture", + "GL_AMD_shader_trinary_minmax", + "GL_INTEL_map_texture", + "GL_NV_draw_texture", "GL_SGIX_texture_select", "GL_INGR_blend_func_separate", "GL_SGIX_depth_pass_instrument", - "GL_SGIX_igloo_interface", - "GL_OES_compressed_paletted_texture", - "GL_OES_fixed_point", - "GL_OES_single_precision", - "GL_OES_query_matrix", - "GL_OES_byte_coordinates", - "GL_NV_gpu_program4", - "GL_NV_path_rendering", - "GL_AMD_vertex_shader_tessellator", - "GL_EXT_fragment_lighting", - "GL_EXT_texture_compression_dxt1", - "GL_EXT_scene_marker", - "GL_EXT_geometry_shader4", - "GL_EXT_texture_env", - "GL_SGIX_texture_range", - "GL_SGIX_pixel_texture_bits", - "GL_IBM_static_data" + "GL_SGIX_igloo_interface" }; -int __GLeeGLNumExtensions=430; +int __GLeeGLNumExtensions=463; /* GL_VERSION_1_2 */ #ifdef __GLEE_GL_VERSION_1_2 #ifndef GLEE_C_DEFINED_glBlendColor #define GLEE_C_DEFINED_glBlendColor - void __stdcall GLee_Lazy_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {if (GLeeInit()) glBlendColor(red, green, blue, alpha);} + void __stdcall GLee_Lazy_glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {if (GLeeInit()) glBlendColor(red, green, blue, alpha);} GLEEPFNGLBLENDCOLORPROC GLeeFuncPtr_glBlendColor=GLee_Lazy_glBlendColor; #endif #ifndef GLEE_C_DEFINED_glBlendEquation @@ -1168,7 +1249,7 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glSampleCoverage #define GLEE_C_DEFINED_glSampleCoverage - void __stdcall GLee_Lazy_glSampleCoverage(GLclampf value, GLboolean invert) {if (GLeeInit()) glSampleCoverage(value, invert);} + void __stdcall GLee_Lazy_glSampleCoverage(GLfloat value, GLboolean invert) {if (GLeeInit()) glSampleCoverage(value, invert);} GLEEPFNGLSAMPLECOVERAGEPROC GLeeFuncPtr_glSampleCoverage=GLee_Lazy_glSampleCoverage; #endif #ifndef GLEE_C_DEFINED_glCompressedTexImage3D @@ -1403,12 +1484,12 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glMultiDrawArrays #define GLEE_C_DEFINED_glMultiDrawArrays - void __stdcall GLee_Lazy_glMultiDrawArrays(GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount) {if (GLeeInit()) glMultiDrawArrays(mode, first, count, primcount);} + void __stdcall GLee_Lazy_glMultiDrawArrays(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount) {if (GLeeInit()) glMultiDrawArrays(mode, first, count, drawcount);} GLEEPFNGLMULTIDRAWARRAYSPROC GLeeFuncPtr_glMultiDrawArrays=GLee_Lazy_glMultiDrawArrays; #endif #ifndef GLEE_C_DEFINED_glMultiDrawElements #define GLEE_C_DEFINED_glMultiDrawElements - void __stdcall GLee_Lazy_glMultiDrawElements(GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount) {if (GLeeInit()) glMultiDrawElements(mode, count, type, indices, primcount);} + void __stdcall GLee_Lazy_glMultiDrawElements(GLenum mode, const GLsizei * count, GLenum type, const GLvoid* const * indices, GLsizei drawcount) {if (GLeeInit()) glMultiDrawElements(mode, count, type, indices, drawcount);} GLEEPFNGLMULTIDRAWELEMENTSPROC GLeeFuncPtr_glMultiDrawElements=GLee_Lazy_glMultiDrawElements; #endif #ifndef GLEE_C_DEFINED_glPointParameterf @@ -1898,7 +1979,7 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glShaderSource #define GLEE_C_DEFINED_glShaderSource - void __stdcall GLee_Lazy_glShaderSource(GLuint shader, GLsizei count, const GLchar* * string, const GLint * length) {if (GLeeInit()) glShaderSource(shader, count, string, length);} + void __stdcall GLee_Lazy_glShaderSource(GLuint shader, GLsizei count, const GLchar* const * string, const GLint * length) {if (GLeeInit()) glShaderSource(shader, count, string, length);} GLEEPFNGLSHADERSOURCEPROC GLeeFuncPtr_glShaderSource=GLee_Lazy_glShaderSource; #endif #ifndef GLEE_C_DEFINED_glUseProgram @@ -2283,7 +2364,7 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glTransformFeedbackVaryings #define GLEE_C_DEFINED_glTransformFeedbackVaryings - void __stdcall GLee_Lazy_glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* * varyings, GLenum bufferMode) {if (GLeeInit()) glTransformFeedbackVaryings(program, count, varyings, bufferMode);} + void __stdcall GLee_Lazy_glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const * varyings, GLenum bufferMode) {if (GLeeInit()) glTransformFeedbackVaryings(program, count, varyings, bufferMode);} GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC GLeeFuncPtr_glTransformFeedbackVaryings=GLee_Lazy_glTransformFeedbackVaryings; #endif #ifndef GLEE_C_DEFINED_glGetTransformFeedbackVarying @@ -2528,12 +2609,12 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_VERSION_3_1 #ifndef GLEE_C_DEFINED_glDrawArraysInstanced #define GLEE_C_DEFINED_glDrawArraysInstanced - void __stdcall GLee_Lazy_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) {if (GLeeInit()) glDrawArraysInstanced(mode, first, count, primcount);} + void __stdcall GLee_Lazy_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {if (GLeeInit()) glDrawArraysInstanced(mode, first, count, instancecount);} GLEEPFNGLDRAWARRAYSINSTANCEDPROC GLeeFuncPtr_glDrawArraysInstanced=GLee_Lazy_glDrawArraysInstanced; #endif #ifndef GLEE_C_DEFINED_glDrawElementsInstanced #define GLEE_C_DEFINED_glDrawElementsInstanced - void __stdcall GLee_Lazy_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount) {if (GLeeInit()) glDrawElementsInstanced(mode, count, type, indices, primcount);} + void __stdcall GLee_Lazy_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei instancecount) {if (GLeeInit()) glDrawElementsInstanced(mode, count, type, indices, instancecount);} GLEEPFNGLDRAWELEMENTSINSTANCEDPROC GLeeFuncPtr_glDrawElementsInstanced=GLee_Lazy_glDrawElementsInstanced; #endif #ifndef GLEE_C_DEFINED_glTexBuffer @@ -2583,7 +2664,7 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_VERSION_4_0 #ifndef GLEE_C_DEFINED_glMinSampleShading #define GLEE_C_DEFINED_glMinSampleShading - void __stdcall GLee_Lazy_glMinSampleShading(GLclampf value) {if (GLeeInit()) glMinSampleShading(value);} + void __stdcall GLee_Lazy_glMinSampleShading(GLfloat value) {if (GLeeInit()) glMinSampleShading(value);} GLEEPFNGLMINSAMPLESHADINGPROC GLeeFuncPtr_glMinSampleShading=GLee_Lazy_glMinSampleShading; #endif #ifndef GLEE_C_DEFINED_glBlendEquationi @@ -2618,6 +2699,11 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_VERSION_4_2 #endif +/* GL_VERSION_4_3 */ + +#ifdef __GLEE_GL_VERSION_4_3 +#endif + /* GL_ARB_multitexture */ #ifdef __GLEE_GL_ARB_multitexture @@ -2823,7 +2909,7 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_ARB_multisample #ifndef GLEE_C_DEFINED_glSampleCoverageARB #define GLEE_C_DEFINED_glSampleCoverageARB - void __stdcall GLee_Lazy_glSampleCoverageARB(GLclampf value, GLboolean invert) {if (GLeeInit()) glSampleCoverageARB(value, invert);} + void __stdcall GLee_Lazy_glSampleCoverageARB(GLfloat value, GLboolean invert) {if (GLeeInit()) glSampleCoverageARB(value, invert);} GLEEPFNGLSAMPLECOVERAGEARBPROC GLeeFuncPtr_glSampleCoverageARB=GLee_Lazy_glSampleCoverageARB; #endif #endif @@ -4048,7 +4134,7 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_ARB_uniform_buffer_object #ifndef GLEE_C_DEFINED_glGetUniformIndices #define GLEE_C_DEFINED_glGetUniformIndices - void __stdcall GLee_Lazy_glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* * uniformNames, GLuint * uniformIndices) {if (GLeeInit()) glGetUniformIndices(program, uniformCount, uniformNames, uniformIndices);} + void __stdcall GLee_Lazy_glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const * uniformNames, GLuint * uniformIndices) {if (GLeeInit()) glGetUniformIndices(program, uniformCount, uniformNames, uniformIndices);} GLEEPFNGLGETUNIFORMINDICESPROC GLeeFuncPtr_glGetUniformIndices=GLee_Lazy_glGetUniformIndices; #endif #ifndef GLEE_C_DEFINED_glGetActiveUniformsiv @@ -4123,12 +4209,12 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glDrawElementsInstancedBaseVertex #define GLEE_C_DEFINED_glDrawElementsInstancedBaseVertex - void __stdcall GLee_Lazy_glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount, GLint basevertex) {if (GLeeInit()) glDrawElementsInstancedBaseVertex(mode, count, type, indices, primcount, basevertex);} + void __stdcall GLee_Lazy_glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei instancecount, GLint basevertex) {if (GLeeInit()) glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex);} GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC GLeeFuncPtr_glDrawElementsInstancedBaseVertex=GLee_Lazy_glDrawElementsInstancedBaseVertex; #endif #ifndef GLEE_C_DEFINED_glMultiDrawElementsBaseVertex #define GLEE_C_DEFINED_glMultiDrawElementsBaseVertex - void __stdcall GLee_Lazy_glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount, const GLint * basevertex) {if (GLeeInit()) glMultiDrawElementsBaseVertex(mode, count, type, indices, primcount, basevertex);} + void __stdcall GLee_Lazy_glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei * count, GLenum type, const GLvoid* const * indices, GLsizei drawcount, const GLint * basevertex) {if (GLeeInit()) glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex);} GLEEPFNGLMULTIDRAWELEMENTSBASEVERTEXPROC GLeeFuncPtr_glMultiDrawElementsBaseVertex=GLee_Lazy_glMultiDrawElementsBaseVertex; #endif #endif @@ -4253,7 +4339,7 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_ARB_sample_shading #ifndef GLEE_C_DEFINED_glMinSampleShadingARB #define GLEE_C_DEFINED_glMinSampleShadingARB - void __stdcall GLee_Lazy_glMinSampleShadingARB(GLclampf value) {if (GLeeInit()) glMinSampleShadingARB(value);} + void __stdcall GLee_Lazy_glMinSampleShadingARB(GLfloat value) {if (GLeeInit()) glMinSampleShadingARB(value);} GLEEPFNGLMINSAMPLESHADINGARBPROC GLeeFuncPtr_glMinSampleShadingARB=GLee_Lazy_glMinSampleShadingARB; #endif #endif @@ -4908,12 +4994,12 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glDepthRangef #define GLEE_C_DEFINED_glDepthRangef - void __stdcall GLee_Lazy_glDepthRangef(GLclampf n, GLclampf f) {if (GLeeInit()) glDepthRangef(n, f);} + void __stdcall GLee_Lazy_glDepthRangef(GLfloat n, GLfloat f) {if (GLeeInit()) glDepthRangef(n, f);} GLEEPFNGLDEPTHRANGEFPROC GLeeFuncPtr_glDepthRangef=GLee_Lazy_glDepthRangef; #endif #ifndef GLEE_C_DEFINED_glClearDepthf #define GLEE_C_DEFINED_glClearDepthf - void __stdcall GLee_Lazy_glClearDepthf(GLclampf d) {if (GLeeInit()) glClearDepthf(d);} + void __stdcall GLee_Lazy_glClearDepthf(GLfloat d) {if (GLeeInit()) glClearDepthf(d);} GLEEPFNGLCLEARDEPTHFPROC GLeeFuncPtr_glClearDepthf=GLee_Lazy_glClearDepthf; #endif #endif @@ -4953,7 +5039,7 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glCreateShaderProgramv #define GLEE_C_DEFINED_glCreateShaderProgramv - GLuint __stdcall GLee_Lazy_glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar* * strings) {if (GLeeInit()) return glCreateShaderProgramv(type, count, strings); return (GLuint)0;} + GLuint __stdcall GLee_Lazy_glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const * strings) {if (GLeeInit()) return glCreateShaderProgramv(type, count, strings); return (GLuint)0;} GLEEPFNGLCREATESHADERPROGRAMVPROC GLeeFuncPtr_glCreateShaderProgramv=GLee_Lazy_glCreateShaderProgramv; #endif #ifndef GLEE_C_DEFINED_glBindProgramPipeline @@ -5338,12 +5424,12 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glDepthRangeArrayv #define GLEE_C_DEFINED_glDepthRangeArrayv - void __stdcall GLee_Lazy_glDepthRangeArrayv(GLuint first, GLsizei count, const GLclampd * v) {if (GLeeInit()) glDepthRangeArrayv(first, count, v);} + void __stdcall GLee_Lazy_glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble * v) {if (GLeeInit()) glDepthRangeArrayv(first, count, v);} GLEEPFNGLDEPTHRANGEARRAYVPROC GLeeFuncPtr_glDepthRangeArrayv=GLee_Lazy_glDepthRangeArrayv; #endif #ifndef GLEE_C_DEFINED_glDepthRangeIndexed #define GLEE_C_DEFINED_glDepthRangeIndexed - void __stdcall GLee_Lazy_glDepthRangeIndexed(GLuint index, GLclampd n, GLclampd f) {if (GLeeInit()) glDepthRangeIndexed(index, n, f);} + void __stdcall GLee_Lazy_glDepthRangeIndexed(GLuint index, GLdouble n, GLdouble f) {if (GLeeInit()) glDepthRangeIndexed(index, n, f);} GLEEPFNGLDEPTHRANGEINDEXEDPROC GLeeFuncPtr_glDepthRangeIndexed=GLee_Lazy_glDepthRangeIndexed; #endif #ifndef GLEE_C_DEFINED_glGetFloati_v @@ -5368,6 +5454,31 @@ int __GLeeGLNumExtensions=430; #endif #endif +/* GL_ARB_debug_output */ + +#ifdef __GLEE_GL_ARB_debug_output +#ifndef GLEE_C_DEFINED_glDebugMessageControlARB +#define GLEE_C_DEFINED_glDebugMessageControlARB + void __stdcall GLee_Lazy_glDebugMessageControlARB(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled) {if (GLeeInit()) glDebugMessageControlARB(source, type, severity, count, ids, enabled);} + GLEEPFNGLDEBUGMESSAGECONTROLARBPROC GLeeFuncPtr_glDebugMessageControlARB=GLee_Lazy_glDebugMessageControlARB; +#endif +#ifndef GLEE_C_DEFINED_glDebugMessageInsertARB +#define GLEE_C_DEFINED_glDebugMessageInsertARB + void __stdcall GLee_Lazy_glDebugMessageInsertARB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf) {if (GLeeInit()) glDebugMessageInsertARB(source, type, id, severity, length, buf);} + GLEEPFNGLDEBUGMESSAGEINSERTARBPROC GLeeFuncPtr_glDebugMessageInsertARB=GLee_Lazy_glDebugMessageInsertARB; +#endif +#ifndef GLEE_C_DEFINED_glDebugMessageCallbackARB +#define GLEE_C_DEFINED_glDebugMessageCallbackARB + void __stdcall GLee_Lazy_glDebugMessageCallbackARB(GLDEBUGPROCARB callback, const GLvoid * userParam) {if (GLeeInit()) glDebugMessageCallbackARB(callback, userParam);} + GLEEPFNGLDEBUGMESSAGECALLBACKARBPROC GLeeFuncPtr_glDebugMessageCallbackARB=GLee_Lazy_glDebugMessageCallbackARB; +#endif +#ifndef GLEE_C_DEFINED_glGetDebugMessageLogARB +#define GLEE_C_DEFINED_glGetDebugMessageLogARB + GLuint __stdcall GLee_Lazy_glGetDebugMessageLogARB(GLuint count, GLsizei bufsize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog) {if (GLeeInit()) return glGetDebugMessageLogARB(count, bufsize, sources, types, ids, severities, lengths, messageLog); return (GLuint)0;} + GLEEPFNGLGETDEBUGMESSAGELOGARBPROC GLeeFuncPtr_glGetDebugMessageLogARB=GLee_Lazy_glGetDebugMessageLogARB; +#endif +#endif + /* GL_ARB_robustness */ #ifdef __GLEE_GL_ARB_robustness @@ -5483,17 +5594,17 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_ARB_base_instance #ifndef GLEE_C_DEFINED_glDrawArraysInstancedBaseInstance #define GLEE_C_DEFINED_glDrawArraysInstancedBaseInstance - void __stdcall GLee_Lazy_glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance) {if (GLeeInit()) glDrawArraysInstancedBaseInstance(mode, first, count, primcount, baseinstance);} + void __stdcall GLee_Lazy_glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) {if (GLeeInit()) glDrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance);} GLEEPFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC GLeeFuncPtr_glDrawArraysInstancedBaseInstance=GLee_Lazy_glDrawArraysInstancedBaseInstance; #endif #ifndef GLEE_C_DEFINED_glDrawElementsInstancedBaseInstance #define GLEE_C_DEFINED_glDrawElementsInstancedBaseInstance - void __stdcall GLee_Lazy_glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount, GLuint baseinstance) {if (GLeeInit()) glDrawElementsInstancedBaseInstance(mode, count, type, indices, primcount, baseinstance);} + void __stdcall GLee_Lazy_glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance) {if (GLeeInit()) glDrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount, baseinstance);} GLEEPFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC GLeeFuncPtr_glDrawElementsInstancedBaseInstance=GLee_Lazy_glDrawElementsInstancedBaseInstance; #endif #ifndef GLEE_C_DEFINED_glDrawElementsInstancedBaseVertexBaseInstance #define GLEE_C_DEFINED_glDrawElementsInstancedBaseVertexBaseInstance - void __stdcall GLee_Lazy_glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount, GLint basevertex, GLuint baseinstance) {if (GLeeInit()) glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, primcount, basevertex, baseinstance);} + void __stdcall GLee_Lazy_glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) {if (GLeeInit()) glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, basevertex, baseinstance);} GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC GLeeFuncPtr_glDrawElementsInstancedBaseVertexBaseInstance=GLee_Lazy_glDrawElementsInstancedBaseVertexBaseInstance; #endif #endif @@ -5508,12 +5619,12 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_ARB_transform_feedback_instanced #ifndef GLEE_C_DEFINED_glDrawTransformFeedbackInstanced #define GLEE_C_DEFINED_glDrawTransformFeedbackInstanced - void __stdcall GLee_Lazy_glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei primcount) {if (GLeeInit()) glDrawTransformFeedbackInstanced(mode, id, primcount);} + void __stdcall GLee_Lazy_glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount) {if (GLeeInit()) glDrawTransformFeedbackInstanced(mode, id, instancecount);} GLEEPFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC GLeeFuncPtr_glDrawTransformFeedbackInstanced=GLee_Lazy_glDrawTransformFeedbackInstanced; #endif #ifndef GLEE_C_DEFINED_glDrawTransformFeedbackStreamInstanced #define GLEE_C_DEFINED_glDrawTransformFeedbackStreamInstanced - void __stdcall GLee_Lazy_glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei primcount) {if (GLeeInit()) glDrawTransformFeedbackStreamInstanced(mode, id, stream, primcount);} + void __stdcall GLee_Lazy_glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount) {if (GLeeInit()) glDrawTransformFeedbackStreamInstanced(mode, id, stream, instancecount);} GLEEPFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC GLeeFuncPtr_glDrawTransformFeedbackStreamInstanced=GLee_Lazy_glDrawTransformFeedbackStreamInstanced; #endif #endif @@ -5608,6 +5719,406 @@ int __GLeeGLNumExtensions=430; #endif #endif +/* GL_KHR_texture_compression_astc_ldr */ + +#ifdef __GLEE_GL_KHR_texture_compression_astc_ldr +#endif + +/* GL_KHR_debug */ + +#ifdef __GLEE_GL_KHR_debug +#ifndef GLEE_C_DEFINED_glDebugMessageControl +#define GLEE_C_DEFINED_glDebugMessageControl + void __stdcall GLee_Lazy_glDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled) {if (GLeeInit()) glDebugMessageControl(source, type, severity, count, ids, enabled);} + GLEEPFNGLDEBUGMESSAGECONTROLPROC GLeeFuncPtr_glDebugMessageControl=GLee_Lazy_glDebugMessageControl; +#endif +#ifndef GLEE_C_DEFINED_glDebugMessageInsert +#define GLEE_C_DEFINED_glDebugMessageInsert + void __stdcall GLee_Lazy_glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf) {if (GLeeInit()) glDebugMessageInsert(source, type, id, severity, length, buf);} + GLEEPFNGLDEBUGMESSAGEINSERTPROC GLeeFuncPtr_glDebugMessageInsert=GLee_Lazy_glDebugMessageInsert; +#endif +#ifndef GLEE_C_DEFINED_glDebugMessageCallback +#define GLEE_C_DEFINED_glDebugMessageCallback + void __stdcall GLee_Lazy_glDebugMessageCallback(GLDEBUGPROC callback, const void * userParam) {if (GLeeInit()) glDebugMessageCallback(callback, userParam);} + GLEEPFNGLDEBUGMESSAGECALLBACKPROC GLeeFuncPtr_glDebugMessageCallback=GLee_Lazy_glDebugMessageCallback; +#endif +#ifndef GLEE_C_DEFINED_glGetDebugMessageLog +#define GLEE_C_DEFINED_glGetDebugMessageLog + GLuint __stdcall GLee_Lazy_glGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog) {if (GLeeInit()) return glGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog); return (GLuint)0;} + GLEEPFNGLGETDEBUGMESSAGELOGPROC GLeeFuncPtr_glGetDebugMessageLog=GLee_Lazy_glGetDebugMessageLog; +#endif +#ifndef GLEE_C_DEFINED_glPushDebugGroup +#define GLEE_C_DEFINED_glPushDebugGroup + void __stdcall GLee_Lazy_glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar * message) {if (GLeeInit()) glPushDebugGroup(source, id, length, message);} + GLEEPFNGLPUSHDEBUGGROUPPROC GLeeFuncPtr_glPushDebugGroup=GLee_Lazy_glPushDebugGroup; +#endif +#ifndef GLEE_C_DEFINED_glPopDebugGroup +#define GLEE_C_DEFINED_glPopDebugGroup + void __stdcall GLee_Lazy_glPopDebugGroup(void) {if (GLeeInit()) glPopDebugGroup();} + GLEEPFNGLPOPDEBUGGROUPPROC GLeeFuncPtr_glPopDebugGroup=GLee_Lazy_glPopDebugGroup; +#endif +#ifndef GLEE_C_DEFINED_glObjectLabel +#define GLEE_C_DEFINED_glObjectLabel + void __stdcall GLee_Lazy_glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar * label) {if (GLeeInit()) glObjectLabel(identifier, name, length, label);} + GLEEPFNGLOBJECTLABELPROC GLeeFuncPtr_glObjectLabel=GLee_Lazy_glObjectLabel; +#endif +#ifndef GLEE_C_DEFINED_glGetObjectLabel +#define GLEE_C_DEFINED_glGetObjectLabel + void __stdcall GLee_Lazy_glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label) {if (GLeeInit()) glGetObjectLabel(identifier, name, bufSize, length, label);} + GLEEPFNGLGETOBJECTLABELPROC GLeeFuncPtr_glGetObjectLabel=GLee_Lazy_glGetObjectLabel; +#endif +#ifndef GLEE_C_DEFINED_glObjectPtrLabel +#define GLEE_C_DEFINED_glObjectPtrLabel + void __stdcall GLee_Lazy_glObjectPtrLabel(const void * ptr, GLsizei length, const GLchar * label) {if (GLeeInit()) glObjectPtrLabel(ptr, length, label);} + GLEEPFNGLOBJECTPTRLABELPROC GLeeFuncPtr_glObjectPtrLabel=GLee_Lazy_glObjectPtrLabel; +#endif +#ifndef GLEE_C_DEFINED_glGetObjectPtrLabel +#define GLEE_C_DEFINED_glGetObjectPtrLabel + void __stdcall GLee_Lazy_glGetObjectPtrLabel(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label) {if (GLeeInit()) glGetObjectPtrLabel(ptr, bufSize, length, label);} + GLEEPFNGLGETOBJECTPTRLABELPROC GLeeFuncPtr_glGetObjectPtrLabel=GLee_Lazy_glGetObjectPtrLabel; +#endif +#endif + +/* GL_ARB_arrays_of_arrays */ + +#ifdef __GLEE_GL_ARB_arrays_of_arrays +#endif + +/* GL_ARB_clear_buffer_object */ + +#ifdef __GLEE_GL_ARB_clear_buffer_object +#ifndef GLEE_C_DEFINED_glClearBufferData +#define GLEE_C_DEFINED_glClearBufferData + void __stdcall GLee_Lazy_glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data) {if (GLeeInit()) glClearBufferData(target, internalformat, format, type, data);} + GLEEPFNGLCLEARBUFFERDATAPROC GLeeFuncPtr_glClearBufferData=GLee_Lazy_glClearBufferData; +#endif +#ifndef GLEE_C_DEFINED_glClearBufferSubData +#define GLEE_C_DEFINED_glClearBufferSubData + void __stdcall GLee_Lazy_glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data) {if (GLeeInit()) glClearBufferSubData(target, internalformat, offset, size, format, type, data);} + GLEEPFNGLCLEARBUFFERSUBDATAPROC GLeeFuncPtr_glClearBufferSubData=GLee_Lazy_glClearBufferSubData; +#endif +#ifndef GLEE_C_DEFINED_glClearNamedBufferDataEXT +#define GLEE_C_DEFINED_glClearNamedBufferDataEXT + void __stdcall GLee_Lazy_glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data) {if (GLeeInit()) glClearNamedBufferDataEXT(buffer, internalformat, format, type, data);} + GLEEPFNGLCLEARNAMEDBUFFERDATAEXTPROC GLeeFuncPtr_glClearNamedBufferDataEXT=GLee_Lazy_glClearNamedBufferDataEXT; +#endif +#ifndef GLEE_C_DEFINED_glClearNamedBufferSubDataEXT +#define GLEE_C_DEFINED_glClearNamedBufferSubDataEXT + void __stdcall GLee_Lazy_glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void * data) {if (GLeeInit()) glClearNamedBufferSubDataEXT(buffer, internalformat, format, type, offset, size, data);} + GLEEPFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC GLeeFuncPtr_glClearNamedBufferSubDataEXT=GLee_Lazy_glClearNamedBufferSubDataEXT; +#endif +#endif + +/* GL_ARB_compute_shader */ + +#ifdef __GLEE_GL_ARB_compute_shader +#ifndef GLEE_C_DEFINED_glDispatchCompute +#define GLEE_C_DEFINED_glDispatchCompute + void __stdcall GLee_Lazy_glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {if (GLeeInit()) glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);} + GLEEPFNGLDISPATCHCOMPUTEPROC GLeeFuncPtr_glDispatchCompute=GLee_Lazy_glDispatchCompute; +#endif +#ifndef GLEE_C_DEFINED_glDispatchComputeIndirect +#define GLEE_C_DEFINED_glDispatchComputeIndirect + void __stdcall GLee_Lazy_glDispatchComputeIndirect(GLintptr indirect) {if (GLeeInit()) glDispatchComputeIndirect(indirect);} + GLEEPFNGLDISPATCHCOMPUTEINDIRECTPROC GLeeFuncPtr_glDispatchComputeIndirect=GLee_Lazy_glDispatchComputeIndirect; +#endif +#endif + +/* GL_ARB_copy_image */ + +#ifdef __GLEE_GL_ARB_copy_image +#ifndef GLEE_C_DEFINED_glCopyImageSubData +#define GLEE_C_DEFINED_glCopyImageSubData + void __stdcall GLee_Lazy_glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {if (GLeeInit()) glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);} + GLEEPFNGLCOPYIMAGESUBDATAPROC GLeeFuncPtr_glCopyImageSubData=GLee_Lazy_glCopyImageSubData; +#endif +#endif + +/* GL_ARB_texture_view */ + +#ifdef __GLEE_GL_ARB_texture_view +#ifndef GLEE_C_DEFINED_glTextureView +#define GLEE_C_DEFINED_glTextureView + void __stdcall GLee_Lazy_glTextureView(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) {if (GLeeInit()) glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);} + GLEEPFNGLTEXTUREVIEWPROC GLeeFuncPtr_glTextureView=GLee_Lazy_glTextureView; +#endif +#endif + +/* GL_ARB_vertex_attrib_binding */ + +#ifdef __GLEE_GL_ARB_vertex_attrib_binding +#ifndef GLEE_C_DEFINED_glBindVertexBuffer +#define GLEE_C_DEFINED_glBindVertexBuffer + void __stdcall GLee_Lazy_glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) {if (GLeeInit()) glBindVertexBuffer(bindingindex, buffer, offset, stride);} + GLEEPFNGLBINDVERTEXBUFFERPROC GLeeFuncPtr_glBindVertexBuffer=GLee_Lazy_glBindVertexBuffer; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribFormat +#define GLEE_C_DEFINED_glVertexAttribFormat + void __stdcall GLee_Lazy_glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {if (GLeeInit()) glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset);} + GLEEPFNGLVERTEXATTRIBFORMATPROC GLeeFuncPtr_glVertexAttribFormat=GLee_Lazy_glVertexAttribFormat; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribIFormat +#define GLEE_C_DEFINED_glVertexAttribIFormat + void __stdcall GLee_Lazy_glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {if (GLeeInit()) glVertexAttribIFormat(attribindex, size, type, relativeoffset);} + GLEEPFNGLVERTEXATTRIBIFORMATPROC GLeeFuncPtr_glVertexAttribIFormat=GLee_Lazy_glVertexAttribIFormat; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribLFormat +#define GLEE_C_DEFINED_glVertexAttribLFormat + void __stdcall GLee_Lazy_glVertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {if (GLeeInit()) glVertexAttribLFormat(attribindex, size, type, relativeoffset);} + GLEEPFNGLVERTEXATTRIBLFORMATPROC GLeeFuncPtr_glVertexAttribLFormat=GLee_Lazy_glVertexAttribLFormat; +#endif +#ifndef GLEE_C_DEFINED_glVertexAttribBinding +#define GLEE_C_DEFINED_glVertexAttribBinding + void __stdcall GLee_Lazy_glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) {if (GLeeInit()) glVertexAttribBinding(attribindex, bindingindex);} + GLEEPFNGLVERTEXATTRIBBINDINGPROC GLeeFuncPtr_glVertexAttribBinding=GLee_Lazy_glVertexAttribBinding; +#endif +#ifndef GLEE_C_DEFINED_glVertexBindingDivisor +#define GLEE_C_DEFINED_glVertexBindingDivisor + void __stdcall GLee_Lazy_glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) {if (GLeeInit()) glVertexBindingDivisor(bindingindex, divisor);} + GLEEPFNGLVERTEXBINDINGDIVISORPROC GLeeFuncPtr_glVertexBindingDivisor=GLee_Lazy_glVertexBindingDivisor; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayBindVertexBufferEXT +#define GLEE_C_DEFINED_glVertexArrayBindVertexBufferEXT + void __stdcall GLee_Lazy_glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) {if (GLeeInit()) glVertexArrayBindVertexBufferEXT(vaobj, bindingindex, buffer, offset, stride);} + GLEEPFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC GLeeFuncPtr_glVertexArrayBindVertexBufferEXT=GLee_Lazy_glVertexArrayBindVertexBufferEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayVertexAttribFormatEXT +#define GLEE_C_DEFINED_glVertexArrayVertexAttribFormatEXT + void __stdcall GLee_Lazy_glVertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {if (GLeeInit()) glVertexArrayVertexAttribFormatEXT(vaobj, attribindex, size, type, normalized, relativeoffset);} + GLEEPFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribFormatEXT=GLee_Lazy_glVertexArrayVertexAttribFormatEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayVertexAttribIFormatEXT +#define GLEE_C_DEFINED_glVertexArrayVertexAttribIFormatEXT + void __stdcall GLee_Lazy_glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {if (GLeeInit()) glVertexArrayVertexAttribIFormatEXT(vaobj, attribindex, size, type, relativeoffset);} + GLEEPFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribIFormatEXT=GLee_Lazy_glVertexArrayVertexAttribIFormatEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayVertexAttribLFormatEXT +#define GLEE_C_DEFINED_glVertexArrayVertexAttribLFormatEXT + void __stdcall GLee_Lazy_glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {if (GLeeInit()) glVertexArrayVertexAttribLFormatEXT(vaobj, attribindex, size, type, relativeoffset);} + GLEEPFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribLFormatEXT=GLee_Lazy_glVertexArrayVertexAttribLFormatEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayVertexAttribBindingEXT +#define GLEE_C_DEFINED_glVertexArrayVertexAttribBindingEXT + void __stdcall GLee_Lazy_glVertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribindex, GLuint bindingindex) {if (GLeeInit()) glVertexArrayVertexAttribBindingEXT(vaobj, attribindex, bindingindex);} + GLEEPFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribBindingEXT=GLee_Lazy_glVertexArrayVertexAttribBindingEXT; +#endif +#ifndef GLEE_C_DEFINED_glVertexArrayVertexBindingDivisorEXT +#define GLEE_C_DEFINED_glVertexArrayVertexBindingDivisorEXT + void __stdcall GLee_Lazy_glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingindex, GLuint divisor) {if (GLeeInit()) glVertexArrayVertexBindingDivisorEXT(vaobj, bindingindex, divisor);} + GLEEPFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC GLeeFuncPtr_glVertexArrayVertexBindingDivisorEXT=GLee_Lazy_glVertexArrayVertexBindingDivisorEXT; +#endif +#endif + +/* GL_ARB_robustness_isolation */ + +#ifdef __GLEE_GL_ARB_robustness_isolation +#endif + +/* GL_ARB_ES3_compatibility */ + +#ifdef __GLEE_GL_ARB_ES3_compatibility +#endif + +/* GL_ARB_explicit_uniform_location */ + +#ifdef __GLEE_GL_ARB_explicit_uniform_location +#endif + +/* GL_ARB_fragment_layer_viewport */ + +#ifdef __GLEE_GL_ARB_fragment_layer_viewport +#endif + +/* GL_ARB_framebuffer_no_attachments */ + +#ifdef __GLEE_GL_ARB_framebuffer_no_attachments +#ifndef GLEE_C_DEFINED_glFramebufferParameteri +#define GLEE_C_DEFINED_glFramebufferParameteri + void __stdcall GLee_Lazy_glFramebufferParameteri(GLenum target, GLenum pname, GLint param) {if (GLeeInit()) glFramebufferParameteri(target, pname, param);} + GLEEPFNGLFRAMEBUFFERPARAMETERIPROC GLeeFuncPtr_glFramebufferParameteri=GLee_Lazy_glFramebufferParameteri; +#endif +#ifndef GLEE_C_DEFINED_glGetFramebufferParameteriv +#define GLEE_C_DEFINED_glGetFramebufferParameteriv + void __stdcall GLee_Lazy_glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetFramebufferParameteriv(target, pname, params);} + GLEEPFNGLGETFRAMEBUFFERPARAMETERIVPROC GLeeFuncPtr_glGetFramebufferParameteriv=GLee_Lazy_glGetFramebufferParameteriv; +#endif +#ifndef GLEE_C_DEFINED_glNamedFramebufferParameteriEXT +#define GLEE_C_DEFINED_glNamedFramebufferParameteriEXT + void __stdcall GLee_Lazy_glNamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, GLint param) {if (GLeeInit()) glNamedFramebufferParameteriEXT(framebuffer, pname, param);} + GLEEPFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC GLeeFuncPtr_glNamedFramebufferParameteriEXT=GLee_Lazy_glNamedFramebufferParameteriEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetNamedFramebufferParameterivEXT +#define GLEE_C_DEFINED_glGetNamedFramebufferParameterivEXT + void __stdcall GLee_Lazy_glGetNamedFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, GLint * params) {if (GLeeInit()) glGetNamedFramebufferParameterivEXT(framebuffer, pname, params);} + GLEEPFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedFramebufferParameterivEXT=GLee_Lazy_glGetNamedFramebufferParameterivEXT; +#endif +#endif + +/* GL_ARB_internalformat_query2 */ + +#ifdef __GLEE_GL_ARB_internalformat_query2 +#ifndef GLEE_C_DEFINED_glGetInternalformati64v +#define GLEE_C_DEFINED_glGetInternalformati64v + void __stdcall GLee_Lazy_glGetInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 * params) {if (GLeeInit()) glGetInternalformati64v(target, internalformat, pname, bufSize, params);} + GLEEPFNGLGETINTERNALFORMATI64VPROC GLeeFuncPtr_glGetInternalformati64v=GLee_Lazy_glGetInternalformati64v; +#endif +#endif + +/* GL_ARB_invalidate_subdata */ + +#ifdef __GLEE_GL_ARB_invalidate_subdata +#ifndef GLEE_C_DEFINED_glInvalidateTexSubImage +#define GLEE_C_DEFINED_glInvalidateTexSubImage + void __stdcall GLee_Lazy_glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) {if (GLeeInit()) glInvalidateTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth);} + GLEEPFNGLINVALIDATETEXSUBIMAGEPROC GLeeFuncPtr_glInvalidateTexSubImage=GLee_Lazy_glInvalidateTexSubImage; +#endif +#ifndef GLEE_C_DEFINED_glInvalidateTexImage +#define GLEE_C_DEFINED_glInvalidateTexImage + void __stdcall GLee_Lazy_glInvalidateTexImage(GLuint texture, GLint level) {if (GLeeInit()) glInvalidateTexImage(texture, level);} + GLEEPFNGLINVALIDATETEXIMAGEPROC GLeeFuncPtr_glInvalidateTexImage=GLee_Lazy_glInvalidateTexImage; +#endif +#ifndef GLEE_C_DEFINED_glInvalidateBufferSubData +#define GLEE_C_DEFINED_glInvalidateBufferSubData + void __stdcall GLee_Lazy_glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length) {if (GLeeInit()) glInvalidateBufferSubData(buffer, offset, length);} + GLEEPFNGLINVALIDATEBUFFERSUBDATAPROC GLeeFuncPtr_glInvalidateBufferSubData=GLee_Lazy_glInvalidateBufferSubData; +#endif +#ifndef GLEE_C_DEFINED_glInvalidateBufferData +#define GLEE_C_DEFINED_glInvalidateBufferData + void __stdcall GLee_Lazy_glInvalidateBufferData(GLuint buffer) {if (GLeeInit()) glInvalidateBufferData(buffer);} + GLEEPFNGLINVALIDATEBUFFERDATAPROC GLeeFuncPtr_glInvalidateBufferData=GLee_Lazy_glInvalidateBufferData; +#endif +#ifndef GLEE_C_DEFINED_glInvalidateFramebuffer +#define GLEE_C_DEFINED_glInvalidateFramebuffer + void __stdcall GLee_Lazy_glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments) {if (GLeeInit()) glInvalidateFramebuffer(target, numAttachments, attachments);} + GLEEPFNGLINVALIDATEFRAMEBUFFERPROC GLeeFuncPtr_glInvalidateFramebuffer=GLee_Lazy_glInvalidateFramebuffer; +#endif +#ifndef GLEE_C_DEFINED_glInvalidateSubFramebuffer +#define GLEE_C_DEFINED_glInvalidateSubFramebuffer + void __stdcall GLee_Lazy_glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) {if (GLeeInit()) glInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);} + GLEEPFNGLINVALIDATESUBFRAMEBUFFERPROC GLeeFuncPtr_glInvalidateSubFramebuffer=GLee_Lazy_glInvalidateSubFramebuffer; +#endif +#endif + +/* GL_ARB_multi_draw_indirect */ + +#ifdef __GLEE_GL_ARB_multi_draw_indirect +#ifndef GLEE_C_DEFINED_glMultiDrawArraysIndirect +#define GLEE_C_DEFINED_glMultiDrawArraysIndirect + void __stdcall GLee_Lazy_glMultiDrawArraysIndirect(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride) {if (GLeeInit()) glMultiDrawArraysIndirect(mode, indirect, drawcount, stride);} + GLEEPFNGLMULTIDRAWARRAYSINDIRECTPROC GLeeFuncPtr_glMultiDrawArraysIndirect=GLee_Lazy_glMultiDrawArraysIndirect; +#endif +#ifndef GLEE_C_DEFINED_glMultiDrawElementsIndirect +#define GLEE_C_DEFINED_glMultiDrawElementsIndirect + void __stdcall GLee_Lazy_glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride) {if (GLeeInit()) glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);} + GLEEPFNGLMULTIDRAWELEMENTSINDIRECTPROC GLeeFuncPtr_glMultiDrawElementsIndirect=GLee_Lazy_glMultiDrawElementsIndirect; +#endif +#endif + +/* GL_ARB_program_interface_query */ + +#ifdef __GLEE_GL_ARB_program_interface_query +#ifndef GLEE_C_DEFINED_glGetProgramInterfaceiv +#define GLEE_C_DEFINED_glGetProgramInterfaceiv + void __stdcall GLee_Lazy_glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint * params) {if (GLeeInit()) glGetProgramInterfaceiv(program, programInterface, pname, params);} + GLEEPFNGLGETPROGRAMINTERFACEIVPROC GLeeFuncPtr_glGetProgramInterfaceiv=GLee_Lazy_glGetProgramInterfaceiv; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramResourceIndex +#define GLEE_C_DEFINED_glGetProgramResourceIndex + GLuint __stdcall GLee_Lazy_glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar * name) {if (GLeeInit()) return glGetProgramResourceIndex(program, programInterface, name); return (GLuint)0;} + GLEEPFNGLGETPROGRAMRESOURCEINDEXPROC GLeeFuncPtr_glGetProgramResourceIndex=GLee_Lazy_glGetProgramResourceIndex; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramResourceName +#define GLEE_C_DEFINED_glGetProgramResourceName + void __stdcall GLee_Lazy_glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name) {if (GLeeInit()) glGetProgramResourceName(program, programInterface, index, bufSize, length, name);} + GLEEPFNGLGETPROGRAMRESOURCENAMEPROC GLeeFuncPtr_glGetProgramResourceName=GLee_Lazy_glGetProgramResourceName; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramResourceiv +#define GLEE_C_DEFINED_glGetProgramResourceiv + void __stdcall GLee_Lazy_glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {if (GLeeInit()) glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params);} + GLEEPFNGLGETPROGRAMRESOURCEIVPROC GLeeFuncPtr_glGetProgramResourceiv=GLee_Lazy_glGetProgramResourceiv; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramResourceLocation +#define GLEE_C_DEFINED_glGetProgramResourceLocation + GLint __stdcall GLee_Lazy_glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar * name) {if (GLeeInit()) return glGetProgramResourceLocation(program, programInterface, name); return (GLint)0;} + GLEEPFNGLGETPROGRAMRESOURCELOCATIONPROC GLeeFuncPtr_glGetProgramResourceLocation=GLee_Lazy_glGetProgramResourceLocation; +#endif +#ifndef GLEE_C_DEFINED_glGetProgramResourceLocationIndex +#define GLEE_C_DEFINED_glGetProgramResourceLocationIndex + GLint __stdcall GLee_Lazy_glGetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar * name) {if (GLeeInit()) return glGetProgramResourceLocationIndex(program, programInterface, name); return (GLint)0;} + GLEEPFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC GLeeFuncPtr_glGetProgramResourceLocationIndex=GLee_Lazy_glGetProgramResourceLocationIndex; +#endif +#endif + +/* GL_ARB_robust_buffer_access_behavior */ + +#ifdef __GLEE_GL_ARB_robust_buffer_access_behavior +#endif + +/* GL_ARB_shader_image_size */ + +#ifdef __GLEE_GL_ARB_shader_image_size +#endif + +/* GL_ARB_shader_storage_buffer_object */ + +#ifdef __GLEE_GL_ARB_shader_storage_buffer_object +#ifndef GLEE_C_DEFINED_glShaderStorageBlockBinding +#define GLEE_C_DEFINED_glShaderStorageBlockBinding + void __stdcall GLee_Lazy_glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) {if (GLeeInit()) glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);} + GLEEPFNGLSHADERSTORAGEBLOCKBINDINGPROC GLeeFuncPtr_glShaderStorageBlockBinding=GLee_Lazy_glShaderStorageBlockBinding; +#endif +#endif + +/* GL_ARB_stencil_texturing */ + +#ifdef __GLEE_GL_ARB_stencil_texturing +#endif + +/* GL_ARB_texture_buffer_range */ + +#ifdef __GLEE_GL_ARB_texture_buffer_range +#ifndef GLEE_C_DEFINED_glTexBufferRange +#define GLEE_C_DEFINED_glTexBufferRange + void __stdcall GLee_Lazy_glTexBufferRange(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) {if (GLeeInit()) glTexBufferRange(target, internalformat, buffer, offset, size);} + GLEEPFNGLTEXBUFFERRANGEPROC GLeeFuncPtr_glTexBufferRange=GLee_Lazy_glTexBufferRange; +#endif +#ifndef GLEE_C_DEFINED_glTextureBufferRangeEXT +#define GLEE_C_DEFINED_glTextureBufferRangeEXT + void __stdcall GLee_Lazy_glTextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) {if (GLeeInit()) glTextureBufferRangeEXT(texture, target, internalformat, buffer, offset, size);} + GLEEPFNGLTEXTUREBUFFERRANGEEXTPROC GLeeFuncPtr_glTextureBufferRangeEXT=GLee_Lazy_glTextureBufferRangeEXT; +#endif +#endif + +/* GL_ARB_texture_query_levels */ + +#ifdef __GLEE_GL_ARB_texture_query_levels +#endif + +/* GL_ARB_texture_storage_multisample */ + +#ifdef __GLEE_GL_ARB_texture_storage_multisample +#ifndef GLEE_C_DEFINED_glTexStorage2DMultisample +#define GLEE_C_DEFINED_glTexStorage2DMultisample + void __stdcall GLee_Lazy_glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {if (GLeeInit()) glTexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);} + GLEEPFNGLTEXSTORAGE2DMULTISAMPLEPROC GLeeFuncPtr_glTexStorage2DMultisample=GLee_Lazy_glTexStorage2DMultisample; +#endif +#ifndef GLEE_C_DEFINED_glTexStorage3DMultisample +#define GLEE_C_DEFINED_glTexStorage3DMultisample + void __stdcall GLee_Lazy_glTexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {if (GLeeInit()) glTexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations);} + GLEEPFNGLTEXSTORAGE3DMULTISAMPLEPROC GLeeFuncPtr_glTexStorage3DMultisample=GLee_Lazy_glTexStorage3DMultisample; +#endif +#ifndef GLEE_C_DEFINED_glTextureStorage2DMultisampleEXT +#define GLEE_C_DEFINED_glTextureStorage2DMultisampleEXT + void __stdcall GLee_Lazy_glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {if (GLeeInit()) glTextureStorage2DMultisampleEXT(texture, target, samples, internalformat, width, height, fixedsamplelocations);} + GLEEPFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC GLeeFuncPtr_glTextureStorage2DMultisampleEXT=GLee_Lazy_glTextureStorage2DMultisampleEXT; +#endif +#ifndef GLEE_C_DEFINED_glTextureStorage3DMultisampleEXT +#define GLEE_C_DEFINED_glTextureStorage3DMultisampleEXT + void __stdcall GLee_Lazy_glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {if (GLeeInit()) glTextureStorage3DMultisampleEXT(texture, target, samples, internalformat, width, height, depth, fixedsamplelocations);} + GLEEPFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC GLeeFuncPtr_glTextureStorage3DMultisampleEXT=GLee_Lazy_glTextureStorage3DMultisampleEXT; +#endif +#endif + /* GL_EXT_abgr */ #ifdef __GLEE_GL_EXT_abgr @@ -5618,7 +6129,7 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_EXT_blend_color #ifndef GLEE_C_DEFINED_glBlendColorEXT #define GLEE_C_DEFINED_glBlendColorEXT - void __stdcall GLee_Lazy_glBlendColorEXT(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {if (GLeeInit()) glBlendColorEXT(red, green, blue, alpha);} + void __stdcall GLee_Lazy_glBlendColorEXT(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {if (GLeeInit()) glBlendColorEXT(red, green, blue, alpha);} GLEEPFNGLBLENDCOLOREXTPROC GLeeFuncPtr_glBlendColorEXT=GLee_Lazy_glBlendColorEXT; #endif #endif @@ -6851,6 +7362,16 @@ int __GLeeGLNumExtensions=430; void __stdcall GLee_Lazy_glPixelTransformParameterfvEXT(GLenum target, GLenum pname, const GLfloat * params) {if (GLeeInit()) glPixelTransformParameterfvEXT(target, pname, params);} GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC GLeeFuncPtr_glPixelTransformParameterfvEXT=GLee_Lazy_glPixelTransformParameterfvEXT; #endif +#ifndef GLEE_C_DEFINED_glGetPixelTransformParameterivEXT +#define GLEE_C_DEFINED_glGetPixelTransformParameterivEXT + void __stdcall GLee_Lazy_glGetPixelTransformParameterivEXT(GLenum target, GLenum pname, GLint * params) {if (GLeeInit()) glGetPixelTransformParameterivEXT(target, pname, params);} + GLEEPFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC GLeeFuncPtr_glGetPixelTransformParameterivEXT=GLee_Lazy_glGetPixelTransformParameterivEXT; +#endif +#ifndef GLEE_C_DEFINED_glGetPixelTransformParameterfvEXT +#define GLEE_C_DEFINED_glGetPixelTransformParameterfvEXT + void __stdcall GLee_Lazy_glGetPixelTransformParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) {if (GLeeInit()) glGetPixelTransformParameterfvEXT(target, pname, params);} + GLEEPFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC GLeeFuncPtr_glGetPixelTransformParameterfvEXT=GLee_Lazy_glGetPixelTransformParameterfvEXT; +#endif #endif /* GL_EXT_pixel_transform_color_table */ @@ -7528,7 +8049,7 @@ int __GLeeGLNumExtensions=430; #endif #ifndef GLEE_C_DEFINED_glVertexWeightPointerEXT #define GLEE_C_DEFINED_glVertexWeightPointerEXT - void __stdcall GLee_Lazy_glVertexWeightPointerEXT(GLsizei size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexWeightPointerEXT(size, type, stride, pointer);} + void __stdcall GLee_Lazy_glVertexWeightPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {if (GLeeInit()) glVertexWeightPointerEXT(size, type, stride, pointer);} GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC GLeeFuncPtr_glVertexWeightPointerEXT=GLee_Lazy_glVertexWeightPointerEXT; #endif #endif @@ -9366,16 +9887,16 @@ int __GLeeGLNumExtensions=430; void __stdcall GLee_Lazy_glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {if (GLeeInit()) glProgramNamedParameter4fNV(id, len, name, x, y, z, w);} GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC GLeeFuncPtr_glProgramNamedParameter4fNV=GLee_Lazy_glProgramNamedParameter4fNV; #endif -#ifndef GLEE_C_DEFINED_glProgramNamedParameter4dNV -#define GLEE_C_DEFINED_glProgramNamedParameter4dNV - void __stdcall GLee_Lazy_glProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glProgramNamedParameter4dNV(id, len, name, x, y, z, w);} - GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC GLeeFuncPtr_glProgramNamedParameter4dNV=GLee_Lazy_glProgramNamedParameter4dNV; -#endif #ifndef GLEE_C_DEFINED_glProgramNamedParameter4fvNV #define GLEE_C_DEFINED_glProgramNamedParameter4fvNV void __stdcall GLee_Lazy_glProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v) {if (GLeeInit()) glProgramNamedParameter4fvNV(id, len, name, v);} GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC GLeeFuncPtr_glProgramNamedParameter4fvNV=GLee_Lazy_glProgramNamedParameter4fvNV; #endif +#ifndef GLEE_C_DEFINED_glProgramNamedParameter4dNV +#define GLEE_C_DEFINED_glProgramNamedParameter4dNV + void __stdcall GLee_Lazy_glProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {if (GLeeInit()) glProgramNamedParameter4dNV(id, len, name, x, y, z, w);} + GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC GLeeFuncPtr_glProgramNamedParameter4dNV=GLee_Lazy_glProgramNamedParameter4dNV; +#endif #ifndef GLEE_C_DEFINED_glProgramNamedParameter4dvNV #define GLEE_C_DEFINED_glProgramNamedParameter4dvNV void __stdcall GLee_Lazy_glProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v) {if (GLeeInit()) glProgramNamedParameter4dvNV(id, len, name, v);} @@ -9633,7 +10154,7 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_NV_pixel_data_range #ifndef GLEE_C_DEFINED_glPixelDataRangeNV #define GLEE_C_DEFINED_glPixelDataRangeNV - void __stdcall GLee_Lazy_glPixelDataRangeNV(GLenum target, GLsizei length, GLvoid * pointer) {if (GLeeInit()) glPixelDataRangeNV(target, length, pointer);} + void __stdcall GLee_Lazy_glPixelDataRangeNV(GLenum target, GLsizei length, const GLvoid * pointer) {if (GLeeInit()) glPixelDataRangeNV(target, length, pointer);} GLEEPFNGLPIXELDATARANGENVPROC GLeeFuncPtr_glPixelDataRangeNV=GLee_Lazy_glPixelDataRangeNV; #endif #ifndef GLEE_C_DEFINED_glFlushPixelDataRangeNV @@ -9718,11 +10239,701 @@ int __GLeeGLNumExtensions=430; #endif #endif +/* GL_OES_byte_coordinates */ + +#ifdef __GLEE_GL_OES_byte_coordinates +#ifndef GLEE_C_DEFINED_glMultiTexCoord1bOES +#define GLEE_C_DEFINED_glMultiTexCoord1bOES + void __stdcall GLee_Lazy_glMultiTexCoord1bOES(GLenum texture, GLbyte s) {if (GLeeInit()) glMultiTexCoord1bOES(texture, s);} + GLEEPFNGLMULTITEXCOORD1BOESPROC GLeeFuncPtr_glMultiTexCoord1bOES=GLee_Lazy_glMultiTexCoord1bOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1bvOES +#define GLEE_C_DEFINED_glMultiTexCoord1bvOES + void __stdcall GLee_Lazy_glMultiTexCoord1bvOES(GLenum texture, const GLbyte * coords) {if (GLeeInit()) glMultiTexCoord1bvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD1BVOESPROC GLeeFuncPtr_glMultiTexCoord1bvOES=GLee_Lazy_glMultiTexCoord1bvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2bOES +#define GLEE_C_DEFINED_glMultiTexCoord2bOES + void __stdcall GLee_Lazy_glMultiTexCoord2bOES(GLenum texture, GLbyte s, GLbyte t) {if (GLeeInit()) glMultiTexCoord2bOES(texture, s, t);} + GLEEPFNGLMULTITEXCOORD2BOESPROC GLeeFuncPtr_glMultiTexCoord2bOES=GLee_Lazy_glMultiTexCoord2bOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2bvOES +#define GLEE_C_DEFINED_glMultiTexCoord2bvOES + void __stdcall GLee_Lazy_glMultiTexCoord2bvOES(GLenum texture, const GLbyte * coords) {if (GLeeInit()) glMultiTexCoord2bvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD2BVOESPROC GLeeFuncPtr_glMultiTexCoord2bvOES=GLee_Lazy_glMultiTexCoord2bvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3bOES +#define GLEE_C_DEFINED_glMultiTexCoord3bOES + void __stdcall GLee_Lazy_glMultiTexCoord3bOES(GLenum texture, GLbyte s, GLbyte t, GLbyte r) {if (GLeeInit()) glMultiTexCoord3bOES(texture, s, t, r);} + GLEEPFNGLMULTITEXCOORD3BOESPROC GLeeFuncPtr_glMultiTexCoord3bOES=GLee_Lazy_glMultiTexCoord3bOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3bvOES +#define GLEE_C_DEFINED_glMultiTexCoord3bvOES + void __stdcall GLee_Lazy_glMultiTexCoord3bvOES(GLenum texture, const GLbyte * coords) {if (GLeeInit()) glMultiTexCoord3bvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD3BVOESPROC GLeeFuncPtr_glMultiTexCoord3bvOES=GLee_Lazy_glMultiTexCoord3bvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4bOES +#define GLEE_C_DEFINED_glMultiTexCoord4bOES + void __stdcall GLee_Lazy_glMultiTexCoord4bOES(GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q) {if (GLeeInit()) glMultiTexCoord4bOES(texture, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4BOESPROC GLeeFuncPtr_glMultiTexCoord4bOES=GLee_Lazy_glMultiTexCoord4bOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4bvOES +#define GLEE_C_DEFINED_glMultiTexCoord4bvOES + void __stdcall GLee_Lazy_glMultiTexCoord4bvOES(GLenum texture, const GLbyte * coords) {if (GLeeInit()) glMultiTexCoord4bvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD4BVOESPROC GLeeFuncPtr_glMultiTexCoord4bvOES=GLee_Lazy_glMultiTexCoord4bvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord1bOES +#define GLEE_C_DEFINED_glTexCoord1bOES + void __stdcall GLee_Lazy_glTexCoord1bOES(GLbyte s) {if (GLeeInit()) glTexCoord1bOES(s);} + GLEEPFNGLTEXCOORD1BOESPROC GLeeFuncPtr_glTexCoord1bOES=GLee_Lazy_glTexCoord1bOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord1bvOES +#define GLEE_C_DEFINED_glTexCoord1bvOES + void __stdcall GLee_Lazy_glTexCoord1bvOES(const GLbyte * coords) {if (GLeeInit()) glTexCoord1bvOES(coords);} + GLEEPFNGLTEXCOORD1BVOESPROC GLeeFuncPtr_glTexCoord1bvOES=GLee_Lazy_glTexCoord1bvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2bOES +#define GLEE_C_DEFINED_glTexCoord2bOES + void __stdcall GLee_Lazy_glTexCoord2bOES(GLbyte s, GLbyte t) {if (GLeeInit()) glTexCoord2bOES(s, t);} + GLEEPFNGLTEXCOORD2BOESPROC GLeeFuncPtr_glTexCoord2bOES=GLee_Lazy_glTexCoord2bOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2bvOES +#define GLEE_C_DEFINED_glTexCoord2bvOES + void __stdcall GLee_Lazy_glTexCoord2bvOES(const GLbyte * coords) {if (GLeeInit()) glTexCoord2bvOES(coords);} + GLEEPFNGLTEXCOORD2BVOESPROC GLeeFuncPtr_glTexCoord2bvOES=GLee_Lazy_glTexCoord2bvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord3bOES +#define GLEE_C_DEFINED_glTexCoord3bOES + void __stdcall GLee_Lazy_glTexCoord3bOES(GLbyte s, GLbyte t, GLbyte r) {if (GLeeInit()) glTexCoord3bOES(s, t, r);} + GLEEPFNGLTEXCOORD3BOESPROC GLeeFuncPtr_glTexCoord3bOES=GLee_Lazy_glTexCoord3bOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord3bvOES +#define GLEE_C_DEFINED_glTexCoord3bvOES + void __stdcall GLee_Lazy_glTexCoord3bvOES(const GLbyte * coords) {if (GLeeInit()) glTexCoord3bvOES(coords);} + GLEEPFNGLTEXCOORD3BVOESPROC GLeeFuncPtr_glTexCoord3bvOES=GLee_Lazy_glTexCoord3bvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4bOES +#define GLEE_C_DEFINED_glTexCoord4bOES + void __stdcall GLee_Lazy_glTexCoord4bOES(GLbyte s, GLbyte t, GLbyte r, GLbyte q) {if (GLeeInit()) glTexCoord4bOES(s, t, r, q);} + GLEEPFNGLTEXCOORD4BOESPROC GLeeFuncPtr_glTexCoord4bOES=GLee_Lazy_glTexCoord4bOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4bvOES +#define GLEE_C_DEFINED_glTexCoord4bvOES + void __stdcall GLee_Lazy_glTexCoord4bvOES(const GLbyte * coords) {if (GLeeInit()) glTexCoord4bvOES(coords);} + GLEEPFNGLTEXCOORD4BVOESPROC GLeeFuncPtr_glTexCoord4bvOES=GLee_Lazy_glTexCoord4bvOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex2bOES +#define GLEE_C_DEFINED_glVertex2bOES + void __stdcall GLee_Lazy_glVertex2bOES(GLbyte x) {if (GLeeInit()) glVertex2bOES(x);} + GLEEPFNGLVERTEX2BOESPROC GLeeFuncPtr_glVertex2bOES=GLee_Lazy_glVertex2bOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex2bvOES +#define GLEE_C_DEFINED_glVertex2bvOES + void __stdcall GLee_Lazy_glVertex2bvOES(const GLbyte * coords) {if (GLeeInit()) glVertex2bvOES(coords);} + GLEEPFNGLVERTEX2BVOESPROC GLeeFuncPtr_glVertex2bvOES=GLee_Lazy_glVertex2bvOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex3bOES +#define GLEE_C_DEFINED_glVertex3bOES + void __stdcall GLee_Lazy_glVertex3bOES(GLbyte x, GLbyte y) {if (GLeeInit()) glVertex3bOES(x, y);} + GLEEPFNGLVERTEX3BOESPROC GLeeFuncPtr_glVertex3bOES=GLee_Lazy_glVertex3bOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex3bvOES +#define GLEE_C_DEFINED_glVertex3bvOES + void __stdcall GLee_Lazy_glVertex3bvOES(const GLbyte * coords) {if (GLeeInit()) glVertex3bvOES(coords);} + GLEEPFNGLVERTEX3BVOESPROC GLeeFuncPtr_glVertex3bvOES=GLee_Lazy_glVertex3bvOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex4bOES +#define GLEE_C_DEFINED_glVertex4bOES + void __stdcall GLee_Lazy_glVertex4bOES(GLbyte x, GLbyte y, GLbyte z) {if (GLeeInit()) glVertex4bOES(x, y, z);} + GLEEPFNGLVERTEX4BOESPROC GLeeFuncPtr_glVertex4bOES=GLee_Lazy_glVertex4bOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex4bvOES +#define GLEE_C_DEFINED_glVertex4bvOES + void __stdcall GLee_Lazy_glVertex4bvOES(const GLbyte * coords) {if (GLeeInit()) glVertex4bvOES(coords);} + GLEEPFNGLVERTEX4BVOESPROC GLeeFuncPtr_glVertex4bvOES=GLee_Lazy_glVertex4bvOES; +#endif +#endif + +/* GL_OES_fixed_point */ + +#ifdef __GLEE_GL_OES_fixed_point +#ifndef GLEE_C_DEFINED_glAccumxOES +#define GLEE_C_DEFINED_glAccumxOES + void __stdcall GLee_Lazy_glAccumxOES(GLenum op, GLfixed value) {if (GLeeInit()) glAccumxOES(op, value);} + GLEEPFNGLACCUMXOESPROC GLeeFuncPtr_glAccumxOES=GLee_Lazy_glAccumxOES; +#endif +#ifndef GLEE_C_DEFINED_glAlphaFuncxOES +#define GLEE_C_DEFINED_glAlphaFuncxOES + void __stdcall GLee_Lazy_glAlphaFuncxOES(GLenum func, GLfixed ref) {if (GLeeInit()) glAlphaFuncxOES(func, ref);} + GLEEPFNGLALPHAFUNCXOESPROC GLeeFuncPtr_glAlphaFuncxOES=GLee_Lazy_glAlphaFuncxOES; +#endif +#ifndef GLEE_C_DEFINED_glBitmapxOES +#define GLEE_C_DEFINED_glBitmapxOES + void __stdcall GLee_Lazy_glBitmapxOES(GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte * bitmap) {if (GLeeInit()) glBitmapxOES(width, height, xorig, yorig, xmove, ymove, bitmap);} + GLEEPFNGLBITMAPXOESPROC GLeeFuncPtr_glBitmapxOES=GLee_Lazy_glBitmapxOES; +#endif +#ifndef GLEE_C_DEFINED_glBlendColorxOES +#define GLEE_C_DEFINED_glBlendColorxOES + void __stdcall GLee_Lazy_glBlendColorxOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {if (GLeeInit()) glBlendColorxOES(red, green, blue, alpha);} + GLEEPFNGLBLENDCOLORXOESPROC GLeeFuncPtr_glBlendColorxOES=GLee_Lazy_glBlendColorxOES; +#endif +#ifndef GLEE_C_DEFINED_glClearAccumxOES +#define GLEE_C_DEFINED_glClearAccumxOES + void __stdcall GLee_Lazy_glClearAccumxOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {if (GLeeInit()) glClearAccumxOES(red, green, blue, alpha);} + GLEEPFNGLCLEARACCUMXOESPROC GLeeFuncPtr_glClearAccumxOES=GLee_Lazy_glClearAccumxOES; +#endif +#ifndef GLEE_C_DEFINED_glClearColorxOES +#define GLEE_C_DEFINED_glClearColorxOES + void __stdcall GLee_Lazy_glClearColorxOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {if (GLeeInit()) glClearColorxOES(red, green, blue, alpha);} + GLEEPFNGLCLEARCOLORXOESPROC GLeeFuncPtr_glClearColorxOES=GLee_Lazy_glClearColorxOES; +#endif +#ifndef GLEE_C_DEFINED_glClearDepthxOES +#define GLEE_C_DEFINED_glClearDepthxOES + void __stdcall GLee_Lazy_glClearDepthxOES(GLfixed depth) {if (GLeeInit()) glClearDepthxOES(depth);} + GLEEPFNGLCLEARDEPTHXOESPROC GLeeFuncPtr_glClearDepthxOES=GLee_Lazy_glClearDepthxOES; +#endif +#ifndef GLEE_C_DEFINED_glClipPlanexOES +#define GLEE_C_DEFINED_glClipPlanexOES + void __stdcall GLee_Lazy_glClipPlanexOES(GLenum plane, const GLfixed * equation) {if (GLeeInit()) glClipPlanexOES(plane, equation);} + GLEEPFNGLCLIPPLANEXOESPROC GLeeFuncPtr_glClipPlanexOES=GLee_Lazy_glClipPlanexOES; +#endif +#ifndef GLEE_C_DEFINED_glColor3xOES +#define GLEE_C_DEFINED_glColor3xOES + void __stdcall GLee_Lazy_glColor3xOES(GLfixed red, GLfixed green, GLfixed blue) {if (GLeeInit()) glColor3xOES(red, green, blue);} + GLEEPFNGLCOLOR3XOESPROC GLeeFuncPtr_glColor3xOES=GLee_Lazy_glColor3xOES; +#endif +#ifndef GLEE_C_DEFINED_glColor4xOES +#define GLEE_C_DEFINED_glColor4xOES + void __stdcall GLee_Lazy_glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {if (GLeeInit()) glColor4xOES(red, green, blue, alpha);} + GLEEPFNGLCOLOR4XOESPROC GLeeFuncPtr_glColor4xOES=GLee_Lazy_glColor4xOES; +#endif +#ifndef GLEE_C_DEFINED_glColor3xvOES +#define GLEE_C_DEFINED_glColor3xvOES + void __stdcall GLee_Lazy_glColor3xvOES(const GLfixed * components) {if (GLeeInit()) glColor3xvOES(components);} + GLEEPFNGLCOLOR3XVOESPROC GLeeFuncPtr_glColor3xvOES=GLee_Lazy_glColor3xvOES; +#endif +#ifndef GLEE_C_DEFINED_glColor4xvOES +#define GLEE_C_DEFINED_glColor4xvOES + void __stdcall GLee_Lazy_glColor4xvOES(const GLfixed * components) {if (GLeeInit()) glColor4xvOES(components);} + GLEEPFNGLCOLOR4XVOESPROC GLeeFuncPtr_glColor4xvOES=GLee_Lazy_glColor4xvOES; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterxOES +#define GLEE_C_DEFINED_glConvolutionParameterxOES + void __stdcall GLee_Lazy_glConvolutionParameterxOES(GLenum target, GLenum pname, GLfixed param) {if (GLeeInit()) glConvolutionParameterxOES(target, pname, param);} + GLEEPFNGLCONVOLUTIONPARAMETERXOESPROC GLeeFuncPtr_glConvolutionParameterxOES=GLee_Lazy_glConvolutionParameterxOES; +#endif +#ifndef GLEE_C_DEFINED_glConvolutionParameterxvOES +#define GLEE_C_DEFINED_glConvolutionParameterxvOES + void __stdcall GLee_Lazy_glConvolutionParameterxvOES(GLenum target, GLenum pname, const GLfixed * params) {if (GLeeInit()) glConvolutionParameterxvOES(target, pname, params);} + GLEEPFNGLCONVOLUTIONPARAMETERXVOESPROC GLeeFuncPtr_glConvolutionParameterxvOES=GLee_Lazy_glConvolutionParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glDepthRangexOES +#define GLEE_C_DEFINED_glDepthRangexOES + void __stdcall GLee_Lazy_glDepthRangexOES(GLfixed n, GLfixed f) {if (GLeeInit()) glDepthRangexOES(n, f);} + GLEEPFNGLDEPTHRANGEXOESPROC GLeeFuncPtr_glDepthRangexOES=GLee_Lazy_glDepthRangexOES; +#endif +#ifndef GLEE_C_DEFINED_glEvalCoord1xOES +#define GLEE_C_DEFINED_glEvalCoord1xOES + void __stdcall GLee_Lazy_glEvalCoord1xOES(GLfixed u) {if (GLeeInit()) glEvalCoord1xOES(u);} + GLEEPFNGLEVALCOORD1XOESPROC GLeeFuncPtr_glEvalCoord1xOES=GLee_Lazy_glEvalCoord1xOES; +#endif +#ifndef GLEE_C_DEFINED_glEvalCoord2xOES +#define GLEE_C_DEFINED_glEvalCoord2xOES + void __stdcall GLee_Lazy_glEvalCoord2xOES(GLfixed u, GLfixed v) {if (GLeeInit()) glEvalCoord2xOES(u, v);} + GLEEPFNGLEVALCOORD2XOESPROC GLeeFuncPtr_glEvalCoord2xOES=GLee_Lazy_glEvalCoord2xOES; +#endif +#ifndef GLEE_C_DEFINED_glEvalCoord1xvOES +#define GLEE_C_DEFINED_glEvalCoord1xvOES + void __stdcall GLee_Lazy_glEvalCoord1xvOES(const GLfixed * coords) {if (GLeeInit()) glEvalCoord1xvOES(coords);} + GLEEPFNGLEVALCOORD1XVOESPROC GLeeFuncPtr_glEvalCoord1xvOES=GLee_Lazy_glEvalCoord1xvOES; +#endif +#ifndef GLEE_C_DEFINED_glEvalCoord2xvOES +#define GLEE_C_DEFINED_glEvalCoord2xvOES + void __stdcall GLee_Lazy_glEvalCoord2xvOES(const GLfixed * coords) {if (GLeeInit()) glEvalCoord2xvOES(coords);} + GLEEPFNGLEVALCOORD2XVOESPROC GLeeFuncPtr_glEvalCoord2xvOES=GLee_Lazy_glEvalCoord2xvOES; +#endif +#ifndef GLEE_C_DEFINED_glFeedbackBufferxOES +#define GLEE_C_DEFINED_glFeedbackBufferxOES + void __stdcall GLee_Lazy_glFeedbackBufferxOES(GLsizei n, GLenum type, const GLfixed * buffer) {if (GLeeInit()) glFeedbackBufferxOES(n, type, buffer);} + GLEEPFNGLFEEDBACKBUFFERXOESPROC GLeeFuncPtr_glFeedbackBufferxOES=GLee_Lazy_glFeedbackBufferxOES; +#endif +#ifndef GLEE_C_DEFINED_glFogxOES +#define GLEE_C_DEFINED_glFogxOES + void __stdcall GLee_Lazy_glFogxOES(GLenum pname, GLfixed param) {if (GLeeInit()) glFogxOES(pname, param);} + GLEEPFNGLFOGXOESPROC GLeeFuncPtr_glFogxOES=GLee_Lazy_glFogxOES; +#endif +#ifndef GLEE_C_DEFINED_glFogxvOES +#define GLEE_C_DEFINED_glFogxvOES + void __stdcall GLee_Lazy_glFogxvOES(GLenum pname, const GLfixed * param) {if (GLeeInit()) glFogxvOES(pname, param);} + GLEEPFNGLFOGXVOESPROC GLeeFuncPtr_glFogxvOES=GLee_Lazy_glFogxvOES; +#endif +#ifndef GLEE_C_DEFINED_glFrustumxOES +#define GLEE_C_DEFINED_glFrustumxOES + void __stdcall GLee_Lazy_glFrustumxOES(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f) {if (GLeeInit()) glFrustumxOES(l, r, b, t, n, f);} + GLEEPFNGLFRUSTUMXOESPROC GLeeFuncPtr_glFrustumxOES=GLee_Lazy_glFrustumxOES; +#endif +#ifndef GLEE_C_DEFINED_glGetClipPlanexOES +#define GLEE_C_DEFINED_glGetClipPlanexOES + void __stdcall GLee_Lazy_glGetClipPlanexOES(GLenum plane, GLfixed * equation) {if (GLeeInit()) glGetClipPlanexOES(plane, equation);} + GLEEPFNGLGETCLIPPLANEXOESPROC GLeeFuncPtr_glGetClipPlanexOES=GLee_Lazy_glGetClipPlanexOES; +#endif +#ifndef GLEE_C_DEFINED_glGetConvolutionParameterxvOES +#define GLEE_C_DEFINED_glGetConvolutionParameterxvOES + void __stdcall GLee_Lazy_glGetConvolutionParameterxvOES(GLenum target, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetConvolutionParameterxvOES(target, pname, params);} + GLEEPFNGLGETCONVOLUTIONPARAMETERXVOESPROC GLeeFuncPtr_glGetConvolutionParameterxvOES=GLee_Lazy_glGetConvolutionParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetFixedvOES +#define GLEE_C_DEFINED_glGetFixedvOES + void __stdcall GLee_Lazy_glGetFixedvOES(GLenum pname, GLfixed * params) {if (GLeeInit()) glGetFixedvOES(pname, params);} + GLEEPFNGLGETFIXEDVOESPROC GLeeFuncPtr_glGetFixedvOES=GLee_Lazy_glGetFixedvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetHistogramParameterxvOES +#define GLEE_C_DEFINED_glGetHistogramParameterxvOES + void __stdcall GLee_Lazy_glGetHistogramParameterxvOES(GLenum target, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetHistogramParameterxvOES(target, pname, params);} + GLEEPFNGLGETHISTOGRAMPARAMETERXVOESPROC GLeeFuncPtr_glGetHistogramParameterxvOES=GLee_Lazy_glGetHistogramParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetLightxOES +#define GLEE_C_DEFINED_glGetLightxOES + void __stdcall GLee_Lazy_glGetLightxOES(GLenum light, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetLightxOES(light, pname, params);} + GLEEPFNGLGETLIGHTXOESPROC GLeeFuncPtr_glGetLightxOES=GLee_Lazy_glGetLightxOES; +#endif +#ifndef GLEE_C_DEFINED_glGetMapxvOES +#define GLEE_C_DEFINED_glGetMapxvOES + void __stdcall GLee_Lazy_glGetMapxvOES(GLenum target, GLenum query, GLfixed * v) {if (GLeeInit()) glGetMapxvOES(target, query, v);} + GLEEPFNGLGETMAPXVOESPROC GLeeFuncPtr_glGetMapxvOES=GLee_Lazy_glGetMapxvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetMaterialxOES +#define GLEE_C_DEFINED_glGetMaterialxOES + void __stdcall GLee_Lazy_glGetMaterialxOES(GLenum face, GLenum pname, GLfixed param) {if (GLeeInit()) glGetMaterialxOES(face, pname, param);} + GLEEPFNGLGETMATERIALXOESPROC GLeeFuncPtr_glGetMaterialxOES=GLee_Lazy_glGetMaterialxOES; +#endif +#ifndef GLEE_C_DEFINED_glGetPixelMapxv +#define GLEE_C_DEFINED_glGetPixelMapxv + void __stdcall GLee_Lazy_glGetPixelMapxv(GLenum map, GLint size, GLfixed * values) {if (GLeeInit()) glGetPixelMapxv(map, size, values);} + GLEEPFNGLGETPIXELMAPXVPROC GLeeFuncPtr_glGetPixelMapxv=GLee_Lazy_glGetPixelMapxv; +#endif +#ifndef GLEE_C_DEFINED_glGetTexEnvxvOES +#define GLEE_C_DEFINED_glGetTexEnvxvOES + void __stdcall GLee_Lazy_glGetTexEnvxvOES(GLenum target, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetTexEnvxvOES(target, pname, params);} + GLEEPFNGLGETTEXENVXVOESPROC GLeeFuncPtr_glGetTexEnvxvOES=GLee_Lazy_glGetTexEnvxvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetTexGenxvOES +#define GLEE_C_DEFINED_glGetTexGenxvOES + void __stdcall GLee_Lazy_glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetTexGenxvOES(coord, pname, params);} + GLEEPFNGLGETTEXGENXVOESPROC GLeeFuncPtr_glGetTexGenxvOES=GLee_Lazy_glGetTexGenxvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetTexLevelParameterxvOES +#define GLEE_C_DEFINED_glGetTexLevelParameterxvOES + void __stdcall GLee_Lazy_glGetTexLevelParameterxvOES(GLenum target, GLint level, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetTexLevelParameterxvOES(target, level, pname, params);} + GLEEPFNGLGETTEXLEVELPARAMETERXVOESPROC GLeeFuncPtr_glGetTexLevelParameterxvOES=GLee_Lazy_glGetTexLevelParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glGetTexParameterxvOES +#define GLEE_C_DEFINED_glGetTexParameterxvOES + void __stdcall GLee_Lazy_glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed * params) {if (GLeeInit()) glGetTexParameterxvOES(target, pname, params);} + GLEEPFNGLGETTEXPARAMETERXVOESPROC GLeeFuncPtr_glGetTexParameterxvOES=GLee_Lazy_glGetTexParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glIndexxOES +#define GLEE_C_DEFINED_glIndexxOES + void __stdcall GLee_Lazy_glIndexxOES(GLfixed component) {if (GLeeInit()) glIndexxOES(component);} + GLEEPFNGLINDEXXOESPROC GLeeFuncPtr_glIndexxOES=GLee_Lazy_glIndexxOES; +#endif +#ifndef GLEE_C_DEFINED_glIndexxvOES +#define GLEE_C_DEFINED_glIndexxvOES + void __stdcall GLee_Lazy_glIndexxvOES(const GLfixed * component) {if (GLeeInit()) glIndexxvOES(component);} + GLEEPFNGLINDEXXVOESPROC GLeeFuncPtr_glIndexxvOES=GLee_Lazy_glIndexxvOES; +#endif +#ifndef GLEE_C_DEFINED_glLightModelxOES +#define GLEE_C_DEFINED_glLightModelxOES + void __stdcall GLee_Lazy_glLightModelxOES(GLenum pname, GLfixed param) {if (GLeeInit()) glLightModelxOES(pname, param);} + GLEEPFNGLLIGHTMODELXOESPROC GLeeFuncPtr_glLightModelxOES=GLee_Lazy_glLightModelxOES; +#endif +#ifndef GLEE_C_DEFINED_glLightModelxvOES +#define GLEE_C_DEFINED_glLightModelxvOES + void __stdcall GLee_Lazy_glLightModelxvOES(GLenum pname, const GLfixed * param) {if (GLeeInit()) glLightModelxvOES(pname, param);} + GLEEPFNGLLIGHTMODELXVOESPROC GLeeFuncPtr_glLightModelxvOES=GLee_Lazy_glLightModelxvOES; +#endif +#ifndef GLEE_C_DEFINED_glLightxOES +#define GLEE_C_DEFINED_glLightxOES + void __stdcall GLee_Lazy_glLightxOES(GLenum light, GLenum pname, GLfixed param) {if (GLeeInit()) glLightxOES(light, pname, param);} + GLEEPFNGLLIGHTXOESPROC GLeeFuncPtr_glLightxOES=GLee_Lazy_glLightxOES; +#endif +#ifndef GLEE_C_DEFINED_glLightxvOES +#define GLEE_C_DEFINED_glLightxvOES + void __stdcall GLee_Lazy_glLightxvOES(GLenum light, GLenum pname, const GLfixed * params) {if (GLeeInit()) glLightxvOES(light, pname, params);} + GLEEPFNGLLIGHTXVOESPROC GLeeFuncPtr_glLightxvOES=GLee_Lazy_glLightxvOES; +#endif +#ifndef GLEE_C_DEFINED_glLineWidthxOES +#define GLEE_C_DEFINED_glLineWidthxOES + void __stdcall GLee_Lazy_glLineWidthxOES(GLfixed width) {if (GLeeInit()) glLineWidthxOES(width);} + GLEEPFNGLLINEWIDTHXOESPROC GLeeFuncPtr_glLineWidthxOES=GLee_Lazy_glLineWidthxOES; +#endif +#ifndef GLEE_C_DEFINED_glLoadMatrixxOES +#define GLEE_C_DEFINED_glLoadMatrixxOES + void __stdcall GLee_Lazy_glLoadMatrixxOES(const GLfixed * m) {if (GLeeInit()) glLoadMatrixxOES(m);} + GLEEPFNGLLOADMATRIXXOESPROC GLeeFuncPtr_glLoadMatrixxOES=GLee_Lazy_glLoadMatrixxOES; +#endif +#ifndef GLEE_C_DEFINED_glLoadTransposeMatrixxOES +#define GLEE_C_DEFINED_glLoadTransposeMatrixxOES + void __stdcall GLee_Lazy_glLoadTransposeMatrixxOES(const GLfixed * m) {if (GLeeInit()) glLoadTransposeMatrixxOES(m);} + GLEEPFNGLLOADTRANSPOSEMATRIXXOESPROC GLeeFuncPtr_glLoadTransposeMatrixxOES=GLee_Lazy_glLoadTransposeMatrixxOES; +#endif +#ifndef GLEE_C_DEFINED_glMap1xOES +#define GLEE_C_DEFINED_glMap1xOES + void __stdcall GLee_Lazy_glMap1xOES(GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points) {if (GLeeInit()) glMap1xOES(target, u1, u2, stride, order, points);} + GLEEPFNGLMAP1XOESPROC GLeeFuncPtr_glMap1xOES=GLee_Lazy_glMap1xOES; +#endif +#ifndef GLEE_C_DEFINED_glMap2xOES +#define GLEE_C_DEFINED_glMap2xOES + void __stdcall GLee_Lazy_glMap2xOES(GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points) {if (GLeeInit()) glMap2xOES(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);} + GLEEPFNGLMAP2XOESPROC GLeeFuncPtr_glMap2xOES=GLee_Lazy_glMap2xOES; +#endif +#ifndef GLEE_C_DEFINED_glMapGrid1xOES +#define GLEE_C_DEFINED_glMapGrid1xOES + void __stdcall GLee_Lazy_glMapGrid1xOES(GLint n, GLfixed u1, GLfixed u2) {if (GLeeInit()) glMapGrid1xOES(n, u1, u2);} + GLEEPFNGLMAPGRID1XOESPROC GLeeFuncPtr_glMapGrid1xOES=GLee_Lazy_glMapGrid1xOES; +#endif +#ifndef GLEE_C_DEFINED_glMapGrid2xOES +#define GLEE_C_DEFINED_glMapGrid2xOES + void __stdcall GLee_Lazy_glMapGrid2xOES(GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2) {if (GLeeInit()) glMapGrid2xOES(n, u1, u2, v1, v2);} + GLEEPFNGLMAPGRID2XOESPROC GLeeFuncPtr_glMapGrid2xOES=GLee_Lazy_glMapGrid2xOES; +#endif +#ifndef GLEE_C_DEFINED_glMaterialxOES +#define GLEE_C_DEFINED_glMaterialxOES + void __stdcall GLee_Lazy_glMaterialxOES(GLenum face, GLenum pname, GLfixed param) {if (GLeeInit()) glMaterialxOES(face, pname, param);} + GLEEPFNGLMATERIALXOESPROC GLeeFuncPtr_glMaterialxOES=GLee_Lazy_glMaterialxOES; +#endif +#ifndef GLEE_C_DEFINED_glMaterialxvOES +#define GLEE_C_DEFINED_glMaterialxvOES + void __stdcall GLee_Lazy_glMaterialxvOES(GLenum face, GLenum pname, const GLfixed * param) {if (GLeeInit()) glMaterialxvOES(face, pname, param);} + GLEEPFNGLMATERIALXVOESPROC GLeeFuncPtr_glMaterialxvOES=GLee_Lazy_glMaterialxvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultMatrixxOES +#define GLEE_C_DEFINED_glMultMatrixxOES + void __stdcall GLee_Lazy_glMultMatrixxOES(const GLfixed * m) {if (GLeeInit()) glMultMatrixxOES(m);} + GLEEPFNGLMULTMATRIXXOESPROC GLeeFuncPtr_glMultMatrixxOES=GLee_Lazy_glMultMatrixxOES; +#endif +#ifndef GLEE_C_DEFINED_glMultTransposeMatrixxOES +#define GLEE_C_DEFINED_glMultTransposeMatrixxOES + void __stdcall GLee_Lazy_glMultTransposeMatrixxOES(const GLfixed * m) {if (GLeeInit()) glMultTransposeMatrixxOES(m);} + GLEEPFNGLMULTTRANSPOSEMATRIXXOESPROC GLeeFuncPtr_glMultTransposeMatrixxOES=GLee_Lazy_glMultTransposeMatrixxOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1xOES +#define GLEE_C_DEFINED_glMultiTexCoord1xOES + void __stdcall GLee_Lazy_glMultiTexCoord1xOES(GLenum texture, GLfixed s) {if (GLeeInit()) glMultiTexCoord1xOES(texture, s);} + GLEEPFNGLMULTITEXCOORD1XOESPROC GLeeFuncPtr_glMultiTexCoord1xOES=GLee_Lazy_glMultiTexCoord1xOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2xOES +#define GLEE_C_DEFINED_glMultiTexCoord2xOES + void __stdcall GLee_Lazy_glMultiTexCoord2xOES(GLenum texture, GLfixed s, GLfixed t) {if (GLeeInit()) glMultiTexCoord2xOES(texture, s, t);} + GLEEPFNGLMULTITEXCOORD2XOESPROC GLeeFuncPtr_glMultiTexCoord2xOES=GLee_Lazy_glMultiTexCoord2xOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3xOES +#define GLEE_C_DEFINED_glMultiTexCoord3xOES + void __stdcall GLee_Lazy_glMultiTexCoord3xOES(GLenum texture, GLfixed s, GLfixed t, GLfixed r) {if (GLeeInit()) glMultiTexCoord3xOES(texture, s, t, r);} + GLEEPFNGLMULTITEXCOORD3XOESPROC GLeeFuncPtr_glMultiTexCoord3xOES=GLee_Lazy_glMultiTexCoord3xOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4xOES +#define GLEE_C_DEFINED_glMultiTexCoord4xOES + void __stdcall GLee_Lazy_glMultiTexCoord4xOES(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {if (GLeeInit()) glMultiTexCoord4xOES(texture, s, t, r, q);} + GLEEPFNGLMULTITEXCOORD4XOESPROC GLeeFuncPtr_glMultiTexCoord4xOES=GLee_Lazy_glMultiTexCoord4xOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord1xvOES +#define GLEE_C_DEFINED_glMultiTexCoord1xvOES + void __stdcall GLee_Lazy_glMultiTexCoord1xvOES(GLenum texture, const GLfixed * coords) {if (GLeeInit()) glMultiTexCoord1xvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD1XVOESPROC GLeeFuncPtr_glMultiTexCoord1xvOES=GLee_Lazy_glMultiTexCoord1xvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord2xvOES +#define GLEE_C_DEFINED_glMultiTexCoord2xvOES + void __stdcall GLee_Lazy_glMultiTexCoord2xvOES(GLenum texture, const GLfixed * coords) {if (GLeeInit()) glMultiTexCoord2xvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD2XVOESPROC GLeeFuncPtr_glMultiTexCoord2xvOES=GLee_Lazy_glMultiTexCoord2xvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord3xvOES +#define GLEE_C_DEFINED_glMultiTexCoord3xvOES + void __stdcall GLee_Lazy_glMultiTexCoord3xvOES(GLenum texture, const GLfixed * coords) {if (GLeeInit()) glMultiTexCoord3xvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD3XVOESPROC GLeeFuncPtr_glMultiTexCoord3xvOES=GLee_Lazy_glMultiTexCoord3xvOES; +#endif +#ifndef GLEE_C_DEFINED_glMultiTexCoord4xvOES +#define GLEE_C_DEFINED_glMultiTexCoord4xvOES + void __stdcall GLee_Lazy_glMultiTexCoord4xvOES(GLenum texture, const GLfixed * coords) {if (GLeeInit()) glMultiTexCoord4xvOES(texture, coords);} + GLEEPFNGLMULTITEXCOORD4XVOESPROC GLeeFuncPtr_glMultiTexCoord4xvOES=GLee_Lazy_glMultiTexCoord4xvOES; +#endif +#ifndef GLEE_C_DEFINED_glNormal3xOES +#define GLEE_C_DEFINED_glNormal3xOES + void __stdcall GLee_Lazy_glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz) {if (GLeeInit()) glNormal3xOES(nx, ny, nz);} + GLEEPFNGLNORMAL3XOESPROC GLeeFuncPtr_glNormal3xOES=GLee_Lazy_glNormal3xOES; +#endif +#ifndef GLEE_C_DEFINED_glNormal3xvOES +#define GLEE_C_DEFINED_glNormal3xvOES + void __stdcall GLee_Lazy_glNormal3xvOES(const GLfixed * coords) {if (GLeeInit()) glNormal3xvOES(coords);} + GLEEPFNGLNORMAL3XVOESPROC GLeeFuncPtr_glNormal3xvOES=GLee_Lazy_glNormal3xvOES; +#endif +#ifndef GLEE_C_DEFINED_glOrthoxOES +#define GLEE_C_DEFINED_glOrthoxOES + void __stdcall GLee_Lazy_glOrthoxOES(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f) {if (GLeeInit()) glOrthoxOES(l, r, b, t, n, f);} + GLEEPFNGLORTHOXOESPROC GLeeFuncPtr_glOrthoxOES=GLee_Lazy_glOrthoxOES; +#endif +#ifndef GLEE_C_DEFINED_glPassThroughxOES +#define GLEE_C_DEFINED_glPassThroughxOES + void __stdcall GLee_Lazy_glPassThroughxOES(GLfixed token) {if (GLeeInit()) glPassThroughxOES(token);} + GLEEPFNGLPASSTHROUGHXOESPROC GLeeFuncPtr_glPassThroughxOES=GLee_Lazy_glPassThroughxOES; +#endif +#ifndef GLEE_C_DEFINED_glPixelMapx +#define GLEE_C_DEFINED_glPixelMapx + void __stdcall GLee_Lazy_glPixelMapx(GLenum map, GLint size, const GLfixed * values) {if (GLeeInit()) glPixelMapx(map, size, values);} + GLEEPFNGLPIXELMAPXPROC GLeeFuncPtr_glPixelMapx=GLee_Lazy_glPixelMapx; +#endif +#ifndef GLEE_C_DEFINED_glPixelStorex +#define GLEE_C_DEFINED_glPixelStorex + void __stdcall GLee_Lazy_glPixelStorex(GLenum pname, GLfixed param) {if (GLeeInit()) glPixelStorex(pname, param);} + GLEEPFNGLPIXELSTOREXPROC GLeeFuncPtr_glPixelStorex=GLee_Lazy_glPixelStorex; +#endif +#ifndef GLEE_C_DEFINED_glPixelTransferxOES +#define GLEE_C_DEFINED_glPixelTransferxOES + void __stdcall GLee_Lazy_glPixelTransferxOES(GLenum pname, GLfixed param) {if (GLeeInit()) glPixelTransferxOES(pname, param);} + GLEEPFNGLPIXELTRANSFERXOESPROC GLeeFuncPtr_glPixelTransferxOES=GLee_Lazy_glPixelTransferxOES; +#endif +#ifndef GLEE_C_DEFINED_glPixelZoomxOES +#define GLEE_C_DEFINED_glPixelZoomxOES + void __stdcall GLee_Lazy_glPixelZoomxOES(GLfixed xfactor, GLfixed yfactor) {if (GLeeInit()) glPixelZoomxOES(xfactor, yfactor);} + GLEEPFNGLPIXELZOOMXOESPROC GLeeFuncPtr_glPixelZoomxOES=GLee_Lazy_glPixelZoomxOES; +#endif +#ifndef GLEE_C_DEFINED_glPointParameterxvOES +#define GLEE_C_DEFINED_glPointParameterxvOES + void __stdcall GLee_Lazy_glPointParameterxvOES(GLenum pname, const GLfixed * params) {if (GLeeInit()) glPointParameterxvOES(pname, params);} + GLEEPFNGLPOINTPARAMETERXVOESPROC GLeeFuncPtr_glPointParameterxvOES=GLee_Lazy_glPointParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glPointSizexOES +#define GLEE_C_DEFINED_glPointSizexOES + void __stdcall GLee_Lazy_glPointSizexOES(GLfixed size) {if (GLeeInit()) glPointSizexOES(size);} + GLEEPFNGLPOINTSIZEXOESPROC GLeeFuncPtr_glPointSizexOES=GLee_Lazy_glPointSizexOES; +#endif +#ifndef GLEE_C_DEFINED_glPolygonOffsetxOES +#define GLEE_C_DEFINED_glPolygonOffsetxOES + void __stdcall GLee_Lazy_glPolygonOffsetxOES(GLfixed factor, GLfixed units) {if (GLeeInit()) glPolygonOffsetxOES(factor, units);} + GLEEPFNGLPOLYGONOFFSETXOESPROC GLeeFuncPtr_glPolygonOffsetxOES=GLee_Lazy_glPolygonOffsetxOES; +#endif +#ifndef GLEE_C_DEFINED_glPrioritizeTexturesxOES +#define GLEE_C_DEFINED_glPrioritizeTexturesxOES + void __stdcall GLee_Lazy_glPrioritizeTexturesxOES(GLsizei n, const GLuint * textures, const GLfixed * priorities) {if (GLeeInit()) glPrioritizeTexturesxOES(n, textures, priorities);} + GLEEPFNGLPRIORITIZETEXTURESXOESPROC GLeeFuncPtr_glPrioritizeTexturesxOES=GLee_Lazy_glPrioritizeTexturesxOES; +#endif +#ifndef GLEE_C_DEFINED_glRasterPos2xOES +#define GLEE_C_DEFINED_glRasterPos2xOES + void __stdcall GLee_Lazy_glRasterPos2xOES(GLfixed x, GLfixed y) {if (GLeeInit()) glRasterPos2xOES(x, y);} + GLEEPFNGLRASTERPOS2XOESPROC GLeeFuncPtr_glRasterPos2xOES=GLee_Lazy_glRasterPos2xOES; +#endif +#ifndef GLEE_C_DEFINED_glRasterPos3xOES +#define GLEE_C_DEFINED_glRasterPos3xOES + void __stdcall GLee_Lazy_glRasterPos3xOES(GLfixed x, GLfixed y, GLfixed z) {if (GLeeInit()) glRasterPos3xOES(x, y, z);} + GLEEPFNGLRASTERPOS3XOESPROC GLeeFuncPtr_glRasterPos3xOES=GLee_Lazy_glRasterPos3xOES; +#endif +#ifndef GLEE_C_DEFINED_glRasterPos4xOES +#define GLEE_C_DEFINED_glRasterPos4xOES + void __stdcall GLee_Lazy_glRasterPos4xOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w) {if (GLeeInit()) glRasterPos4xOES(x, y, z, w);} + GLEEPFNGLRASTERPOS4XOESPROC GLeeFuncPtr_glRasterPos4xOES=GLee_Lazy_glRasterPos4xOES; +#endif +#ifndef GLEE_C_DEFINED_glRasterPos2xvOES +#define GLEE_C_DEFINED_glRasterPos2xvOES + void __stdcall GLee_Lazy_glRasterPos2xvOES(const GLfixed * coords) {if (GLeeInit()) glRasterPos2xvOES(coords);} + GLEEPFNGLRASTERPOS2XVOESPROC GLeeFuncPtr_glRasterPos2xvOES=GLee_Lazy_glRasterPos2xvOES; +#endif +#ifndef GLEE_C_DEFINED_glRasterPos3xvOES +#define GLEE_C_DEFINED_glRasterPos3xvOES + void __stdcall GLee_Lazy_glRasterPos3xvOES(const GLfixed * coords) {if (GLeeInit()) glRasterPos3xvOES(coords);} + GLEEPFNGLRASTERPOS3XVOESPROC GLeeFuncPtr_glRasterPos3xvOES=GLee_Lazy_glRasterPos3xvOES; +#endif +#ifndef GLEE_C_DEFINED_glRasterPos4xvOES +#define GLEE_C_DEFINED_glRasterPos4xvOES + void __stdcall GLee_Lazy_glRasterPos4xvOES(const GLfixed * coords) {if (GLeeInit()) glRasterPos4xvOES(coords);} + GLEEPFNGLRASTERPOS4XVOESPROC GLeeFuncPtr_glRasterPos4xvOES=GLee_Lazy_glRasterPos4xvOES; +#endif +#ifndef GLEE_C_DEFINED_glRectxOES +#define GLEE_C_DEFINED_glRectxOES + void __stdcall GLee_Lazy_glRectxOES(GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2) {if (GLeeInit()) glRectxOES(x1, y1, x2, y2);} + GLEEPFNGLRECTXOESPROC GLeeFuncPtr_glRectxOES=GLee_Lazy_glRectxOES; +#endif +#ifndef GLEE_C_DEFINED_glRectxvOES +#define GLEE_C_DEFINED_glRectxvOES + void __stdcall GLee_Lazy_glRectxvOES(const GLfixed * v1, const GLfixed * v2) {if (GLeeInit()) glRectxvOES(v1, v2);} + GLEEPFNGLRECTXVOESPROC GLeeFuncPtr_glRectxvOES=GLee_Lazy_glRectxvOES; +#endif +#ifndef GLEE_C_DEFINED_glRotatexOES +#define GLEE_C_DEFINED_glRotatexOES + void __stdcall GLee_Lazy_glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {if (GLeeInit()) glRotatexOES(angle, x, y, z);} + GLEEPFNGLROTATEXOESPROC GLeeFuncPtr_glRotatexOES=GLee_Lazy_glRotatexOES; +#endif +#ifndef GLEE_C_DEFINED_glSampleCoverageOES +#define GLEE_C_DEFINED_glSampleCoverageOES + void __stdcall GLee_Lazy_glSampleCoverageOES(GLfixed value, GLboolean invert) {if (GLeeInit()) glSampleCoverageOES(value, invert);} + GLEEPFNGLSAMPLECOVERAGEOESPROC GLeeFuncPtr_glSampleCoverageOES=GLee_Lazy_glSampleCoverageOES; +#endif +#ifndef GLEE_C_DEFINED_glScalexOES +#define GLEE_C_DEFINED_glScalexOES + void __stdcall GLee_Lazy_glScalexOES(GLfixed x, GLfixed y, GLfixed z) {if (GLeeInit()) glScalexOES(x, y, z);} + GLEEPFNGLSCALEXOESPROC GLeeFuncPtr_glScalexOES=GLee_Lazy_glScalexOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord1xOES +#define GLEE_C_DEFINED_glTexCoord1xOES + void __stdcall GLee_Lazy_glTexCoord1xOES(GLfixed s) {if (GLeeInit()) glTexCoord1xOES(s);} + GLEEPFNGLTEXCOORD1XOESPROC GLeeFuncPtr_glTexCoord1xOES=GLee_Lazy_glTexCoord1xOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2xOES +#define GLEE_C_DEFINED_glTexCoord2xOES + void __stdcall GLee_Lazy_glTexCoord2xOES(GLfixed s, GLfixed t) {if (GLeeInit()) glTexCoord2xOES(s, t);} + GLEEPFNGLTEXCOORD2XOESPROC GLeeFuncPtr_glTexCoord2xOES=GLee_Lazy_glTexCoord2xOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord3xOES +#define GLEE_C_DEFINED_glTexCoord3xOES + void __stdcall GLee_Lazy_glTexCoord3xOES(GLfixed s, GLfixed t, GLfixed r) {if (GLeeInit()) glTexCoord3xOES(s, t, r);} + GLEEPFNGLTEXCOORD3XOESPROC GLeeFuncPtr_glTexCoord3xOES=GLee_Lazy_glTexCoord3xOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4xOES +#define GLEE_C_DEFINED_glTexCoord4xOES + void __stdcall GLee_Lazy_glTexCoord4xOES(GLfixed s, GLfixed t, GLfixed r, GLfixed q) {if (GLeeInit()) glTexCoord4xOES(s, t, r, q);} + GLEEPFNGLTEXCOORD4XOESPROC GLeeFuncPtr_glTexCoord4xOES=GLee_Lazy_glTexCoord4xOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord1xvOES +#define GLEE_C_DEFINED_glTexCoord1xvOES + void __stdcall GLee_Lazy_glTexCoord1xvOES(const GLfixed * coords) {if (GLeeInit()) glTexCoord1xvOES(coords);} + GLEEPFNGLTEXCOORD1XVOESPROC GLeeFuncPtr_glTexCoord1xvOES=GLee_Lazy_glTexCoord1xvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord2xvOES +#define GLEE_C_DEFINED_glTexCoord2xvOES + void __stdcall GLee_Lazy_glTexCoord2xvOES(const GLfixed * coords) {if (GLeeInit()) glTexCoord2xvOES(coords);} + GLEEPFNGLTEXCOORD2XVOESPROC GLeeFuncPtr_glTexCoord2xvOES=GLee_Lazy_glTexCoord2xvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord3xvOES +#define GLEE_C_DEFINED_glTexCoord3xvOES + void __stdcall GLee_Lazy_glTexCoord3xvOES(const GLfixed * coords) {if (GLeeInit()) glTexCoord3xvOES(coords);} + GLEEPFNGLTEXCOORD3XVOESPROC GLeeFuncPtr_glTexCoord3xvOES=GLee_Lazy_glTexCoord3xvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexCoord4xvOES +#define GLEE_C_DEFINED_glTexCoord4xvOES + void __stdcall GLee_Lazy_glTexCoord4xvOES(const GLfixed * coords) {if (GLeeInit()) glTexCoord4xvOES(coords);} + GLEEPFNGLTEXCOORD4XVOESPROC GLeeFuncPtr_glTexCoord4xvOES=GLee_Lazy_glTexCoord4xvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexEnvxOES +#define GLEE_C_DEFINED_glTexEnvxOES + void __stdcall GLee_Lazy_glTexEnvxOES(GLenum target, GLenum pname, GLfixed param) {if (GLeeInit()) glTexEnvxOES(target, pname, param);} + GLEEPFNGLTEXENVXOESPROC GLeeFuncPtr_glTexEnvxOES=GLee_Lazy_glTexEnvxOES; +#endif +#ifndef GLEE_C_DEFINED_glTexEnvxvOES +#define GLEE_C_DEFINED_glTexEnvxvOES + void __stdcall GLee_Lazy_glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed * params) {if (GLeeInit()) glTexEnvxvOES(target, pname, params);} + GLEEPFNGLTEXENVXVOESPROC GLeeFuncPtr_glTexEnvxvOES=GLee_Lazy_glTexEnvxvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexGenxOES +#define GLEE_C_DEFINED_glTexGenxOES + void __stdcall GLee_Lazy_glTexGenxOES(GLenum coord, GLenum pname, GLfixed param) {if (GLeeInit()) glTexGenxOES(coord, pname, param);} + GLEEPFNGLTEXGENXOESPROC GLeeFuncPtr_glTexGenxOES=GLee_Lazy_glTexGenxOES; +#endif +#ifndef GLEE_C_DEFINED_glTexGenxvOES +#define GLEE_C_DEFINED_glTexGenxvOES + void __stdcall GLee_Lazy_glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed * params) {if (GLeeInit()) glTexGenxvOES(coord, pname, params);} + GLEEPFNGLTEXGENXVOESPROC GLeeFuncPtr_glTexGenxvOES=GLee_Lazy_glTexGenxvOES; +#endif +#ifndef GLEE_C_DEFINED_glTexParameterxOES +#define GLEE_C_DEFINED_glTexParameterxOES + void __stdcall GLee_Lazy_glTexParameterxOES(GLenum target, GLenum pname, GLfixed param) {if (GLeeInit()) glTexParameterxOES(target, pname, param);} + GLEEPFNGLTEXPARAMETERXOESPROC GLeeFuncPtr_glTexParameterxOES=GLee_Lazy_glTexParameterxOES; +#endif +#ifndef GLEE_C_DEFINED_glTexParameterxvOES +#define GLEE_C_DEFINED_glTexParameterxvOES + void __stdcall GLee_Lazy_glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed * params) {if (GLeeInit()) glTexParameterxvOES(target, pname, params);} + GLEEPFNGLTEXPARAMETERXVOESPROC GLeeFuncPtr_glTexParameterxvOES=GLee_Lazy_glTexParameterxvOES; +#endif +#ifndef GLEE_C_DEFINED_glTranslatexOES +#define GLEE_C_DEFINED_glTranslatexOES + void __stdcall GLee_Lazy_glTranslatexOES(GLfixed x, GLfixed y, GLfixed z) {if (GLeeInit()) glTranslatexOES(x, y, z);} + GLEEPFNGLTRANSLATEXOESPROC GLeeFuncPtr_glTranslatexOES=GLee_Lazy_glTranslatexOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex2xOES +#define GLEE_C_DEFINED_glVertex2xOES + void __stdcall GLee_Lazy_glVertex2xOES(GLfixed x) {if (GLeeInit()) glVertex2xOES(x);} + GLEEPFNGLVERTEX2XOESPROC GLeeFuncPtr_glVertex2xOES=GLee_Lazy_glVertex2xOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex3xOES +#define GLEE_C_DEFINED_glVertex3xOES + void __stdcall GLee_Lazy_glVertex3xOES(GLfixed x, GLfixed y) {if (GLeeInit()) glVertex3xOES(x, y);} + GLEEPFNGLVERTEX3XOESPROC GLeeFuncPtr_glVertex3xOES=GLee_Lazy_glVertex3xOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex4xOES +#define GLEE_C_DEFINED_glVertex4xOES + void __stdcall GLee_Lazy_glVertex4xOES(GLfixed x, GLfixed y, GLfixed z) {if (GLeeInit()) glVertex4xOES(x, y, z);} + GLEEPFNGLVERTEX4XOESPROC GLeeFuncPtr_glVertex4xOES=GLee_Lazy_glVertex4xOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex2xvOES +#define GLEE_C_DEFINED_glVertex2xvOES + void __stdcall GLee_Lazy_glVertex2xvOES(const GLfixed * coords) {if (GLeeInit()) glVertex2xvOES(coords);} + GLEEPFNGLVERTEX2XVOESPROC GLeeFuncPtr_glVertex2xvOES=GLee_Lazy_glVertex2xvOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex3xvOES +#define GLEE_C_DEFINED_glVertex3xvOES + void __stdcall GLee_Lazy_glVertex3xvOES(const GLfixed * coords) {if (GLeeInit()) glVertex3xvOES(coords);} + GLEEPFNGLVERTEX3XVOESPROC GLeeFuncPtr_glVertex3xvOES=GLee_Lazy_glVertex3xvOES; +#endif +#ifndef GLEE_C_DEFINED_glVertex4xvOES +#define GLEE_C_DEFINED_glVertex4xvOES + void __stdcall GLee_Lazy_glVertex4xvOES(const GLfixed * coords) {if (GLeeInit()) glVertex4xvOES(coords);} + GLEEPFNGLVERTEX4XVOESPROC GLeeFuncPtr_glVertex4xvOES=GLee_Lazy_glVertex4xvOES; +#endif +#endif + +/* GL_OES_single_precision */ + +#ifdef __GLEE_GL_OES_single_precision +#ifndef GLEE_C_DEFINED_glDepthRangefOES +#define GLEE_C_DEFINED_glDepthRangefOES + void __stdcall GLee_Lazy_glDepthRangefOES(GLclampf n, GLclampf f) {if (GLeeInit()) glDepthRangefOES(n, f);} + GLEEPFNGLDEPTHRANGEFOESPROC GLeeFuncPtr_glDepthRangefOES=GLee_Lazy_glDepthRangefOES; +#endif +#ifndef GLEE_C_DEFINED_glFrustumfOES +#define GLEE_C_DEFINED_glFrustumfOES + void __stdcall GLee_Lazy_glFrustumfOES(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) {if (GLeeInit()) glFrustumfOES(l, r, b, t, n, f);} + GLEEPFNGLFRUSTUMFOESPROC GLeeFuncPtr_glFrustumfOES=GLee_Lazy_glFrustumfOES; +#endif +#ifndef GLEE_C_DEFINED_glOrthofOES +#define GLEE_C_DEFINED_glOrthofOES + void __stdcall GLee_Lazy_glOrthofOES(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) {if (GLeeInit()) glOrthofOES(l, r, b, t, n, f);} + GLEEPFNGLORTHOFOESPROC GLeeFuncPtr_glOrthofOES=GLee_Lazy_glOrthofOES; +#endif +#ifndef GLEE_C_DEFINED_glClipPlanefOES +#define GLEE_C_DEFINED_glClipPlanefOES + void __stdcall GLee_Lazy_glClipPlanefOES(GLenum plane, const GLfloat * equation) {if (GLeeInit()) glClipPlanefOES(plane, equation);} + GLEEPFNGLCLIPPLANEFOESPROC GLeeFuncPtr_glClipPlanefOES=GLee_Lazy_glClipPlanefOES; +#endif +#ifndef GLEE_C_DEFINED_glClearDepthfOES +#define GLEE_C_DEFINED_glClearDepthfOES + void __stdcall GLee_Lazy_glClearDepthfOES(GLclampd depth) {if (GLeeInit()) glClearDepthfOES(depth);} + GLEEPFNGLCLEARDEPTHFOESPROC GLeeFuncPtr_glClearDepthfOES=GLee_Lazy_glClearDepthfOES; +#endif +#ifndef GLEE_C_DEFINED_glGetClipPlanefOES +#define GLEE_C_DEFINED_glGetClipPlanefOES + void __stdcall GLee_Lazy_glGetClipPlanefOES(GLenum plane, GLfloat * equation) {if (GLeeInit()) glGetClipPlanefOES(plane, equation);} + GLEEPFNGLGETCLIPPLANEFOESPROC GLeeFuncPtr_glGetClipPlanefOES=GLee_Lazy_glGetClipPlanefOES; +#endif +#endif + +/* GL_OES_compressed_paletted_texture */ + +#ifdef __GLEE_GL_OES_compressed_paletted_texture +#endif + /* GL_OES_read_format */ #ifdef __GLEE_GL_OES_read_format #endif +/* GL_OES_query_matrix */ + +#ifdef __GLEE_GL_OES_query_matrix +#ifndef GLEE_C_DEFINED_glQueryMatrixxOES +#define GLEE_C_DEFINED_glQueryMatrixxOES + GLbitfield __stdcall GLee_Lazy_glQueryMatrixxOES(const GLfixed * mantissa, const GLint * exponent) {if (GLeeInit()) return glQueryMatrixxOES(mantissa, exponent); return (GLbitfield)0;} + GLEEPFNGLQUERYMATRIXXOESPROC GLeeFuncPtr_glQueryMatrixxOES=GLee_Lazy_glQueryMatrixxOES; +#endif +#endif + /* GL_EXT_depth_bounds_test */ #ifdef __GLEE_GL_EXT_depth_bounds_test @@ -10128,17 +11339,17 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_NV_parameter_buffer_object #ifndef GLEE_C_DEFINED_glProgramBufferParametersfvNV #define GLEE_C_DEFINED_glProgramBufferParametersfvNV - void __stdcall GLee_Lazy_glProgramBufferParametersfvNV(GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat * params) {if (GLeeInit()) glProgramBufferParametersfvNV(target, buffer, index, count, params);} + void __stdcall GLee_Lazy_glProgramBufferParametersfvNV(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat * params) {if (GLeeInit()) glProgramBufferParametersfvNV(target, bindingIndex, wordIndex, count, params);} GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC GLeeFuncPtr_glProgramBufferParametersfvNV=GLee_Lazy_glProgramBufferParametersfvNV; #endif #ifndef GLEE_C_DEFINED_glProgramBufferParametersIivNV #define GLEE_C_DEFINED_glProgramBufferParametersIivNV - void __stdcall GLee_Lazy_glProgramBufferParametersIivNV(GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint * params) {if (GLeeInit()) glProgramBufferParametersIivNV(target, buffer, index, count, params);} + void __stdcall GLee_Lazy_glProgramBufferParametersIivNV(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint * params) {if (GLeeInit()) glProgramBufferParametersIivNV(target, bindingIndex, wordIndex, count, params);} GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC GLeeFuncPtr_glProgramBufferParametersIivNV=GLee_Lazy_glProgramBufferParametersIivNV; #endif #ifndef GLEE_C_DEFINED_glProgramBufferParametersIuivNV #define GLEE_C_DEFINED_glProgramBufferParametersIuivNV - void __stdcall GLee_Lazy_glProgramBufferParametersIuivNV(GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint * params) {if (GLeeInit()) glProgramBufferParametersIuivNV(target, buffer, index, count, params);} + void __stdcall GLee_Lazy_glProgramBufferParametersIuivNV(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint * params) {if (GLeeInit()) glProgramBufferParametersIuivNV(target, bindingIndex, wordIndex, count, params);} GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC GLeeFuncPtr_glProgramBufferParametersIuivNV=GLee_Lazy_glProgramBufferParametersIuivNV; #endif #endif @@ -12383,6 +13594,31 @@ int __GLeeGLNumExtensions=430; #endif #endif +/* GL_AMD_debug_output */ + +#ifdef __GLEE_GL_AMD_debug_output +#ifndef GLEE_C_DEFINED_glDebugMessageEnableAMD +#define GLEE_C_DEFINED_glDebugMessageEnableAMD + void __stdcall GLee_Lazy_glDebugMessageEnableAMD(GLenum category, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled) {if (GLeeInit()) glDebugMessageEnableAMD(category, severity, count, ids, enabled);} + GLEEPFNGLDEBUGMESSAGEENABLEAMDPROC GLeeFuncPtr_glDebugMessageEnableAMD=GLee_Lazy_glDebugMessageEnableAMD; +#endif +#ifndef GLEE_C_DEFINED_glDebugMessageInsertAMD +#define GLEE_C_DEFINED_glDebugMessageInsertAMD + void __stdcall GLee_Lazy_glDebugMessageInsertAMD(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar * buf) {if (GLeeInit()) glDebugMessageInsertAMD(category, severity, id, length, buf);} + GLEEPFNGLDEBUGMESSAGEINSERTAMDPROC GLeeFuncPtr_glDebugMessageInsertAMD=GLee_Lazy_glDebugMessageInsertAMD; +#endif +#ifndef GLEE_C_DEFINED_glDebugMessageCallbackAMD +#define GLEE_C_DEFINED_glDebugMessageCallbackAMD + void __stdcall GLee_Lazy_glDebugMessageCallbackAMD(GLDEBUGPROCAMD callback, GLvoid * userParam) {if (GLeeInit()) glDebugMessageCallbackAMD(callback, userParam);} + GLEEPFNGLDEBUGMESSAGECALLBACKAMDPROC GLeeFuncPtr_glDebugMessageCallbackAMD=GLee_Lazy_glDebugMessageCallbackAMD; +#endif +#ifndef GLEE_C_DEFINED_glGetDebugMessageLogAMD +#define GLEE_C_DEFINED_glGetDebugMessageLogAMD + GLuint __stdcall GLee_Lazy_glGetDebugMessageLogAMD(GLuint count, GLsizei bufsize, GLenum * categories, GLuint * severities, GLuint * ids, GLsizei * lengths, GLchar * message) {if (GLeeInit()) return glGetDebugMessageLogAMD(count, bufsize, categories, severities, ids, lengths, message); return (GLuint)0;} + GLEEPFNGLGETDEBUGMESSAGELOGAMDPROC GLeeFuncPtr_glGetDebugMessageLogAMD=GLee_Lazy_glGetDebugMessageLogAMD; +#endif +#endif + /* GL_AMD_transform_feedback3_lines_triangles */ #ifdef __GLEE_GL_AMD_transform_feedback3_lines_triangles @@ -12478,6 +13714,446 @@ int __GLeeGLNumExtensions=430; #ifdef __GLEE_GL_EXT_framebuffer_multisample_blit_scaled #endif +/* GL_NV_path_rendering */ + +#ifdef __GLEE_GL_NV_path_rendering +#ifndef GLEE_C_DEFINED_glGenPathsNV +#define GLEE_C_DEFINED_glGenPathsNV + GLuint __stdcall GLee_Lazy_glGenPathsNV(GLsizei range) {if (GLeeInit()) return glGenPathsNV(range); return (GLuint)0;} + GLEEPFNGLGENPATHSNVPROC GLeeFuncPtr_glGenPathsNV=GLee_Lazy_glGenPathsNV; +#endif +#ifndef GLEE_C_DEFINED_glDeletePathsNV +#define GLEE_C_DEFINED_glDeletePathsNV + void __stdcall GLee_Lazy_glDeletePathsNV(GLuint path, GLsizei range) {if (GLeeInit()) glDeletePathsNV(path, range);} + GLEEPFNGLDELETEPATHSNVPROC GLeeFuncPtr_glDeletePathsNV=GLee_Lazy_glDeletePathsNV; +#endif +#ifndef GLEE_C_DEFINED_glIsPathNV +#define GLEE_C_DEFINED_glIsPathNV + GLboolean __stdcall GLee_Lazy_glIsPathNV(GLuint path) {if (GLeeInit()) return glIsPathNV(path); return (GLboolean)0;} + GLEEPFNGLISPATHNVPROC GLeeFuncPtr_glIsPathNV=GLee_Lazy_glIsPathNV; +#endif +#ifndef GLEE_C_DEFINED_glPathCommandsNV +#define GLEE_C_DEFINED_glPathCommandsNV + void __stdcall GLee_Lazy_glPathCommandsNV(GLuint path, GLsizei numCommands, const GLubyte * commands, GLsizei numCoords, GLenum coordType, const GLvoid * coords) {if (GLeeInit()) glPathCommandsNV(path, numCommands, commands, numCoords, coordType, coords);} + GLEEPFNGLPATHCOMMANDSNVPROC GLeeFuncPtr_glPathCommandsNV=GLee_Lazy_glPathCommandsNV; +#endif +#ifndef GLEE_C_DEFINED_glPathCoordsNV +#define GLEE_C_DEFINED_glPathCoordsNV + void __stdcall GLee_Lazy_glPathCoordsNV(GLuint path, GLsizei numCoords, GLenum coordType, const GLvoid * coords) {if (GLeeInit()) glPathCoordsNV(path, numCoords, coordType, coords);} + GLEEPFNGLPATHCOORDSNVPROC GLeeFuncPtr_glPathCoordsNV=GLee_Lazy_glPathCoordsNV; +#endif +#ifndef GLEE_C_DEFINED_glPathSubCommandsNV +#define GLEE_C_DEFINED_glPathSubCommandsNV + void __stdcall GLee_Lazy_glPathSubCommandsNV(GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte * commands, GLsizei numCoords, GLenum coordType, const GLvoid * coords) {if (GLeeInit()) glPathSubCommandsNV(path, commandStart, commandsToDelete, numCommands, commands, numCoords, coordType, coords);} + GLEEPFNGLPATHSUBCOMMANDSNVPROC GLeeFuncPtr_glPathSubCommandsNV=GLee_Lazy_glPathSubCommandsNV; +#endif +#ifndef GLEE_C_DEFINED_glPathSubCoordsNV +#define GLEE_C_DEFINED_glPathSubCoordsNV + void __stdcall GLee_Lazy_glPathSubCoordsNV(GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const GLvoid * coords) {if (GLeeInit()) glPathSubCoordsNV(path, coordStart, numCoords, coordType, coords);} + GLEEPFNGLPATHSUBCOORDSNVPROC GLeeFuncPtr_glPathSubCoordsNV=GLee_Lazy_glPathSubCoordsNV; +#endif +#ifndef GLEE_C_DEFINED_glPathStringNV +#define GLEE_C_DEFINED_glPathStringNV + void __stdcall GLee_Lazy_glPathStringNV(GLuint path, GLenum format, GLsizei length, const GLvoid * pathString) {if (GLeeInit()) glPathStringNV(path, format, length, pathString);} + GLEEPFNGLPATHSTRINGNVPROC GLeeFuncPtr_glPathStringNV=GLee_Lazy_glPathStringNV; +#endif +#ifndef GLEE_C_DEFINED_glPathGlyphsNV +#define GLEE_C_DEFINED_glPathGlyphsNV + void __stdcall GLee_Lazy_glPathGlyphsNV(GLuint firstPathName, GLenum fontTarget, const GLvoid * fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const GLvoid * charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale) {if (GLeeInit()) glPathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, numGlyphs, type, charcodes, handleMissingGlyphs, pathParameterTemplate, emScale);} + GLEEPFNGLPATHGLYPHSNVPROC GLeeFuncPtr_glPathGlyphsNV=GLee_Lazy_glPathGlyphsNV; +#endif +#ifndef GLEE_C_DEFINED_glPathGlyphRangeNV +#define GLEE_C_DEFINED_glPathGlyphRangeNV + void __stdcall GLee_Lazy_glPathGlyphRangeNV(GLuint firstPathName, GLenum fontTarget, const GLvoid * fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale) {if (GLeeInit()) glPathGlyphRangeNV(firstPathName, fontTarget, fontName, fontStyle, firstGlyph, numGlyphs, handleMissingGlyphs, pathParameterTemplate, emScale);} + GLEEPFNGLPATHGLYPHRANGENVPROC GLeeFuncPtr_glPathGlyphRangeNV=GLee_Lazy_glPathGlyphRangeNV; +#endif +#ifndef GLEE_C_DEFINED_glWeightPathsNV +#define GLEE_C_DEFINED_glWeightPathsNV + void __stdcall GLee_Lazy_glWeightPathsNV(GLuint resultPath, GLsizei numPaths, const GLuint * paths, const GLfloat * weights) {if (GLeeInit()) glWeightPathsNV(resultPath, numPaths, paths, weights);} + GLEEPFNGLWEIGHTPATHSNVPROC GLeeFuncPtr_glWeightPathsNV=GLee_Lazy_glWeightPathsNV; +#endif +#ifndef GLEE_C_DEFINED_glCopyPathNV +#define GLEE_C_DEFINED_glCopyPathNV + void __stdcall GLee_Lazy_glCopyPathNV(GLuint resultPath, GLuint srcPath) {if (GLeeInit()) glCopyPathNV(resultPath, srcPath);} + GLEEPFNGLCOPYPATHNVPROC GLeeFuncPtr_glCopyPathNV=GLee_Lazy_glCopyPathNV; +#endif +#ifndef GLEE_C_DEFINED_glInterpolatePathsNV +#define GLEE_C_DEFINED_glInterpolatePathsNV + void __stdcall GLee_Lazy_glInterpolatePathsNV(GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight) {if (GLeeInit()) glInterpolatePathsNV(resultPath, pathA, pathB, weight);} + GLEEPFNGLINTERPOLATEPATHSNVPROC GLeeFuncPtr_glInterpolatePathsNV=GLee_Lazy_glInterpolatePathsNV; +#endif +#ifndef GLEE_C_DEFINED_glTransformPathNV +#define GLEE_C_DEFINED_glTransformPathNV + void __stdcall GLee_Lazy_glTransformPathNV(GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat * transformValues) {if (GLeeInit()) glTransformPathNV(resultPath, srcPath, transformType, transformValues);} + GLEEPFNGLTRANSFORMPATHNVPROC GLeeFuncPtr_glTransformPathNV=GLee_Lazy_glTransformPathNV; +#endif +#ifndef GLEE_C_DEFINED_glPathParameterivNV +#define GLEE_C_DEFINED_glPathParameterivNV + void __stdcall GLee_Lazy_glPathParameterivNV(GLuint path, GLenum pname, const GLint * value) {if (GLeeInit()) glPathParameterivNV(path, pname, value);} + GLEEPFNGLPATHPARAMETERIVNVPROC GLeeFuncPtr_glPathParameterivNV=GLee_Lazy_glPathParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glPathParameteriNV +#define GLEE_C_DEFINED_glPathParameteriNV + void __stdcall GLee_Lazy_glPathParameteriNV(GLuint path, GLenum pname, GLint value) {if (GLeeInit()) glPathParameteriNV(path, pname, value);} + GLEEPFNGLPATHPARAMETERINVPROC GLeeFuncPtr_glPathParameteriNV=GLee_Lazy_glPathParameteriNV; +#endif +#ifndef GLEE_C_DEFINED_glPathParameterfvNV +#define GLEE_C_DEFINED_glPathParameterfvNV + void __stdcall GLee_Lazy_glPathParameterfvNV(GLuint path, GLenum pname, const GLfloat * value) {if (GLeeInit()) glPathParameterfvNV(path, pname, value);} + GLEEPFNGLPATHPARAMETERFVNVPROC GLeeFuncPtr_glPathParameterfvNV=GLee_Lazy_glPathParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glPathParameterfNV +#define GLEE_C_DEFINED_glPathParameterfNV + void __stdcall GLee_Lazy_glPathParameterfNV(GLuint path, GLenum pname, GLfloat value) {if (GLeeInit()) glPathParameterfNV(path, pname, value);} + GLEEPFNGLPATHPARAMETERFNVPROC GLeeFuncPtr_glPathParameterfNV=GLee_Lazy_glPathParameterfNV; +#endif +#ifndef GLEE_C_DEFINED_glPathDashArrayNV +#define GLEE_C_DEFINED_glPathDashArrayNV + void __stdcall GLee_Lazy_glPathDashArrayNV(GLuint path, GLsizei dashCount, const GLfloat * dashArray) {if (GLeeInit()) glPathDashArrayNV(path, dashCount, dashArray);} + GLEEPFNGLPATHDASHARRAYNVPROC GLeeFuncPtr_glPathDashArrayNV=GLee_Lazy_glPathDashArrayNV; +#endif +#ifndef GLEE_C_DEFINED_glPathStencilFuncNV +#define GLEE_C_DEFINED_glPathStencilFuncNV + void __stdcall GLee_Lazy_glPathStencilFuncNV(GLenum func, GLint ref, GLuint mask) {if (GLeeInit()) glPathStencilFuncNV(func, ref, mask);} + GLEEPFNGLPATHSTENCILFUNCNVPROC GLeeFuncPtr_glPathStencilFuncNV=GLee_Lazy_glPathStencilFuncNV; +#endif +#ifndef GLEE_C_DEFINED_glPathStencilDepthOffsetNV +#define GLEE_C_DEFINED_glPathStencilDepthOffsetNV + void __stdcall GLee_Lazy_glPathStencilDepthOffsetNV(GLfloat factor, GLfloat units) {if (GLeeInit()) glPathStencilDepthOffsetNV(factor, units);} + GLEEPFNGLPATHSTENCILDEPTHOFFSETNVPROC GLeeFuncPtr_glPathStencilDepthOffsetNV=GLee_Lazy_glPathStencilDepthOffsetNV; +#endif +#ifndef GLEE_C_DEFINED_glStencilFillPathNV +#define GLEE_C_DEFINED_glStencilFillPathNV + void __stdcall GLee_Lazy_glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask) {if (GLeeInit()) glStencilFillPathNV(path, fillMode, mask);} + GLEEPFNGLSTENCILFILLPATHNVPROC GLeeFuncPtr_glStencilFillPathNV=GLee_Lazy_glStencilFillPathNV; +#endif +#ifndef GLEE_C_DEFINED_glStencilStrokePathNV +#define GLEE_C_DEFINED_glStencilStrokePathNV + void __stdcall GLee_Lazy_glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask) {if (GLeeInit()) glStencilStrokePathNV(path, reference, mask);} + GLEEPFNGLSTENCILSTROKEPATHNVPROC GLeeFuncPtr_glStencilStrokePathNV=GLee_Lazy_glStencilStrokePathNV; +#endif +#ifndef GLEE_C_DEFINED_glStencilFillPathInstancedNV +#define GLEE_C_DEFINED_glStencilFillPathInstancedNV + void __stdcall GLee_Lazy_glStencilFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat * transformValues) {if (GLeeInit()) glStencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, fillMode, mask, transformType, transformValues);} + GLEEPFNGLSTENCILFILLPATHINSTANCEDNVPROC GLeeFuncPtr_glStencilFillPathInstancedNV=GLee_Lazy_glStencilFillPathInstancedNV; +#endif +#ifndef GLEE_C_DEFINED_glStencilStrokePathInstancedNV +#define GLEE_C_DEFINED_glStencilStrokePathInstancedNV + void __stdcall GLee_Lazy_glStencilStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat * transformValues) {if (GLeeInit()) glStencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, reference, mask, transformType, transformValues);} + GLEEPFNGLSTENCILSTROKEPATHINSTANCEDNVPROC GLeeFuncPtr_glStencilStrokePathInstancedNV=GLee_Lazy_glStencilStrokePathInstancedNV; +#endif +#ifndef GLEE_C_DEFINED_glPathCoverDepthFuncNV +#define GLEE_C_DEFINED_glPathCoverDepthFuncNV + void __stdcall GLee_Lazy_glPathCoverDepthFuncNV(GLenum func) {if (GLeeInit()) glPathCoverDepthFuncNV(func);} + GLEEPFNGLPATHCOVERDEPTHFUNCNVPROC GLeeFuncPtr_glPathCoverDepthFuncNV=GLee_Lazy_glPathCoverDepthFuncNV; +#endif +#ifndef GLEE_C_DEFINED_glPathColorGenNV +#define GLEE_C_DEFINED_glPathColorGenNV + void __stdcall GLee_Lazy_glPathColorGenNV(GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat * coeffs) {if (GLeeInit()) glPathColorGenNV(color, genMode, colorFormat, coeffs);} + GLEEPFNGLPATHCOLORGENNVPROC GLeeFuncPtr_glPathColorGenNV=GLee_Lazy_glPathColorGenNV; +#endif +#ifndef GLEE_C_DEFINED_glPathTexGenNV +#define GLEE_C_DEFINED_glPathTexGenNV + void __stdcall GLee_Lazy_glPathTexGenNV(GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat * coeffs) {if (GLeeInit()) glPathTexGenNV(texCoordSet, genMode, components, coeffs);} + GLEEPFNGLPATHTEXGENNVPROC GLeeFuncPtr_glPathTexGenNV=GLee_Lazy_glPathTexGenNV; +#endif +#ifndef GLEE_C_DEFINED_glPathFogGenNV +#define GLEE_C_DEFINED_glPathFogGenNV + void __stdcall GLee_Lazy_glPathFogGenNV(GLenum genMode) {if (GLeeInit()) glPathFogGenNV(genMode);} + GLEEPFNGLPATHFOGGENNVPROC GLeeFuncPtr_glPathFogGenNV=GLee_Lazy_glPathFogGenNV; +#endif +#ifndef GLEE_C_DEFINED_glCoverFillPathNV +#define GLEE_C_DEFINED_glCoverFillPathNV + void __stdcall GLee_Lazy_glCoverFillPathNV(GLuint path, GLenum coverMode) {if (GLeeInit()) glCoverFillPathNV(path, coverMode);} + GLEEPFNGLCOVERFILLPATHNVPROC GLeeFuncPtr_glCoverFillPathNV=GLee_Lazy_glCoverFillPathNV; +#endif +#ifndef GLEE_C_DEFINED_glCoverStrokePathNV +#define GLEE_C_DEFINED_glCoverStrokePathNV + void __stdcall GLee_Lazy_glCoverStrokePathNV(GLuint path, GLenum coverMode) {if (GLeeInit()) glCoverStrokePathNV(path, coverMode);} + GLEEPFNGLCOVERSTROKEPATHNVPROC GLeeFuncPtr_glCoverStrokePathNV=GLee_Lazy_glCoverStrokePathNV; +#endif +#ifndef GLEE_C_DEFINED_glCoverFillPathInstancedNV +#define GLEE_C_DEFINED_glCoverFillPathInstancedNV + void __stdcall GLee_Lazy_glCoverFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat * transformValues) {if (GLeeInit()) glCoverFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues);} + GLEEPFNGLCOVERFILLPATHINSTANCEDNVPROC GLeeFuncPtr_glCoverFillPathInstancedNV=GLee_Lazy_glCoverFillPathInstancedNV; +#endif +#ifndef GLEE_C_DEFINED_glCoverStrokePathInstancedNV +#define GLEE_C_DEFINED_glCoverStrokePathInstancedNV + void __stdcall GLee_Lazy_glCoverStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat * transformValues) {if (GLeeInit()) glCoverStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues);} + GLEEPFNGLCOVERSTROKEPATHINSTANCEDNVPROC GLeeFuncPtr_glCoverStrokePathInstancedNV=GLee_Lazy_glCoverStrokePathInstancedNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathParameterivNV +#define GLEE_C_DEFINED_glGetPathParameterivNV + void __stdcall GLee_Lazy_glGetPathParameterivNV(GLuint path, GLenum pname, GLint * value) {if (GLeeInit()) glGetPathParameterivNV(path, pname, value);} + GLEEPFNGLGETPATHPARAMETERIVNVPROC GLeeFuncPtr_glGetPathParameterivNV=GLee_Lazy_glGetPathParameterivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathParameterfvNV +#define GLEE_C_DEFINED_glGetPathParameterfvNV + void __stdcall GLee_Lazy_glGetPathParameterfvNV(GLuint path, GLenum pname, GLfloat * value) {if (GLeeInit()) glGetPathParameterfvNV(path, pname, value);} + GLEEPFNGLGETPATHPARAMETERFVNVPROC GLeeFuncPtr_glGetPathParameterfvNV=GLee_Lazy_glGetPathParameterfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathCommandsNV +#define GLEE_C_DEFINED_glGetPathCommandsNV + void __stdcall GLee_Lazy_glGetPathCommandsNV(GLuint path, GLubyte * commands) {if (GLeeInit()) glGetPathCommandsNV(path, commands);} + GLEEPFNGLGETPATHCOMMANDSNVPROC GLeeFuncPtr_glGetPathCommandsNV=GLee_Lazy_glGetPathCommandsNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathCoordsNV +#define GLEE_C_DEFINED_glGetPathCoordsNV + void __stdcall GLee_Lazy_glGetPathCoordsNV(GLuint path, GLfloat * coords) {if (GLeeInit()) glGetPathCoordsNV(path, coords);} + GLEEPFNGLGETPATHCOORDSNVPROC GLeeFuncPtr_glGetPathCoordsNV=GLee_Lazy_glGetPathCoordsNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathDashArrayNV +#define GLEE_C_DEFINED_glGetPathDashArrayNV + void __stdcall GLee_Lazy_glGetPathDashArrayNV(GLuint path, GLfloat * dashArray) {if (GLeeInit()) glGetPathDashArrayNV(path, dashArray);} + GLEEPFNGLGETPATHDASHARRAYNVPROC GLeeFuncPtr_glGetPathDashArrayNV=GLee_Lazy_glGetPathDashArrayNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathMetricsNV +#define GLEE_C_DEFINED_glGetPathMetricsNV + void __stdcall GLee_Lazy_glGetPathMetricsNV(GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLsizei stride, GLfloat * metrics) {if (GLeeInit()) glGetPathMetricsNV(metricQueryMask, numPaths, pathNameType, paths, pathBase, stride, metrics);} + GLEEPFNGLGETPATHMETRICSNVPROC GLeeFuncPtr_glGetPathMetricsNV=GLee_Lazy_glGetPathMetricsNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathMetricRangeNV +#define GLEE_C_DEFINED_glGetPathMetricRangeNV + void __stdcall GLee_Lazy_glGetPathMetricRangeNV(GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat * metrics) {if (GLeeInit()) glGetPathMetricRangeNV(metricQueryMask, firstPathName, numPaths, stride, metrics);} + GLEEPFNGLGETPATHMETRICRANGENVPROC GLeeFuncPtr_glGetPathMetricRangeNV=GLee_Lazy_glGetPathMetricRangeNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathSpacingNV +#define GLEE_C_DEFINED_glGetPathSpacingNV + void __stdcall GLee_Lazy_glGetPathSpacingNV(GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat * returnedSpacing) {if (GLeeInit()) glGetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase, advanceScale, kerningScale, transformType, returnedSpacing);} + GLEEPFNGLGETPATHSPACINGNVPROC GLeeFuncPtr_glGetPathSpacingNV=GLee_Lazy_glGetPathSpacingNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathColorGenivNV +#define GLEE_C_DEFINED_glGetPathColorGenivNV + void __stdcall GLee_Lazy_glGetPathColorGenivNV(GLenum color, GLenum pname, GLint * value) {if (GLeeInit()) glGetPathColorGenivNV(color, pname, value);} + GLEEPFNGLGETPATHCOLORGENIVNVPROC GLeeFuncPtr_glGetPathColorGenivNV=GLee_Lazy_glGetPathColorGenivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathColorGenfvNV +#define GLEE_C_DEFINED_glGetPathColorGenfvNV + void __stdcall GLee_Lazy_glGetPathColorGenfvNV(GLenum color, GLenum pname, GLfloat * value) {if (GLeeInit()) glGetPathColorGenfvNV(color, pname, value);} + GLEEPFNGLGETPATHCOLORGENFVNVPROC GLeeFuncPtr_glGetPathColorGenfvNV=GLee_Lazy_glGetPathColorGenfvNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathTexGenivNV +#define GLEE_C_DEFINED_glGetPathTexGenivNV + void __stdcall GLee_Lazy_glGetPathTexGenivNV(GLenum texCoordSet, GLenum pname, GLint * value) {if (GLeeInit()) glGetPathTexGenivNV(texCoordSet, pname, value);} + GLEEPFNGLGETPATHTEXGENIVNVPROC GLeeFuncPtr_glGetPathTexGenivNV=GLee_Lazy_glGetPathTexGenivNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathTexGenfvNV +#define GLEE_C_DEFINED_glGetPathTexGenfvNV + void __stdcall GLee_Lazy_glGetPathTexGenfvNV(GLenum texCoordSet, GLenum pname, GLfloat * value) {if (GLeeInit()) glGetPathTexGenfvNV(texCoordSet, pname, value);} + GLEEPFNGLGETPATHTEXGENFVNVPROC GLeeFuncPtr_glGetPathTexGenfvNV=GLee_Lazy_glGetPathTexGenfvNV; +#endif +#ifndef GLEE_C_DEFINED_glIsPointInFillPathNV +#define GLEE_C_DEFINED_glIsPointInFillPathNV + GLboolean __stdcall GLee_Lazy_glIsPointInFillPathNV(GLuint path, GLuint mask, GLfloat x, GLfloat y) {if (GLeeInit()) return glIsPointInFillPathNV(path, mask, x, y); return (GLboolean)0;} + GLEEPFNGLISPOINTINFILLPATHNVPROC GLeeFuncPtr_glIsPointInFillPathNV=GLee_Lazy_glIsPointInFillPathNV; +#endif +#ifndef GLEE_C_DEFINED_glIsPointInStrokePathNV +#define GLEE_C_DEFINED_glIsPointInStrokePathNV + GLboolean __stdcall GLee_Lazy_glIsPointInStrokePathNV(GLuint path, GLfloat x, GLfloat y) {if (GLeeInit()) return glIsPointInStrokePathNV(path, x, y); return (GLboolean)0;} + GLEEPFNGLISPOINTINSTROKEPATHNVPROC GLeeFuncPtr_glIsPointInStrokePathNV=GLee_Lazy_glIsPointInStrokePathNV; +#endif +#ifndef GLEE_C_DEFINED_glGetPathLengthNV +#define GLEE_C_DEFINED_glGetPathLengthNV + GLfloat __stdcall GLee_Lazy_glGetPathLengthNV(GLuint path, GLsizei startSegment, GLsizei numSegments) {if (GLeeInit()) return glGetPathLengthNV(path, startSegment, numSegments); return (GLfloat)0;} + GLEEPFNGLGETPATHLENGTHNVPROC GLeeFuncPtr_glGetPathLengthNV=GLee_Lazy_glGetPathLengthNV; +#endif +#ifndef GLEE_C_DEFINED_glPointAlongPathNV +#define GLEE_C_DEFINED_glPointAlongPathNV + GLboolean __stdcall GLee_Lazy_glPointAlongPathNV(GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat * x, GLfloat * y, GLfloat * tangentX, GLfloat * tangentY) {if (GLeeInit()) return glPointAlongPathNV(path, startSegment, numSegments, distance, x, y, tangentX, tangentY); return (GLboolean)0;} + GLEEPFNGLPOINTALONGPATHNVPROC GLeeFuncPtr_glPointAlongPathNV=GLee_Lazy_glPointAlongPathNV; +#endif +#endif + +/* GL_AMD_pinned_memory */ + +#ifdef __GLEE_GL_AMD_pinned_memory +#endif + +/* GL_AMD_stencil_operation_extended */ + +#ifdef __GLEE_GL_AMD_stencil_operation_extended +#ifndef GLEE_C_DEFINED_glStencilOpValueAMD +#define GLEE_C_DEFINED_glStencilOpValueAMD + void __stdcall GLee_Lazy_glStencilOpValueAMD(GLenum face, GLuint value) {if (GLeeInit()) glStencilOpValueAMD(face, value);} + GLEEPFNGLSTENCILOPVALUEAMDPROC GLeeFuncPtr_glStencilOpValueAMD=GLee_Lazy_glStencilOpValueAMD; +#endif +#endif + +/* GL_AMD_vertex_shader_viewport_index */ + +#ifdef __GLEE_GL_AMD_vertex_shader_viewport_index +#endif + +/* GL_AMD_vertex_shader_layer */ + +#ifdef __GLEE_GL_AMD_vertex_shader_layer +#endif + +/* GL_NV_bindless_texture */ + +#ifdef __GLEE_GL_NV_bindless_texture +#ifndef GLEE_C_DEFINED_glGetTextureHandleNV +#define GLEE_C_DEFINED_glGetTextureHandleNV + GLuint64 __stdcall GLee_Lazy_glGetTextureHandleNV(GLuint texture) {if (GLeeInit()) return glGetTextureHandleNV(texture); return (GLuint64)0;} + GLEEPFNGLGETTEXTUREHANDLENVPROC GLeeFuncPtr_glGetTextureHandleNV=GLee_Lazy_glGetTextureHandleNV; +#endif +#ifndef GLEE_C_DEFINED_glGetTextureSamplerHandleNV +#define GLEE_C_DEFINED_glGetTextureSamplerHandleNV + GLuint64 __stdcall GLee_Lazy_glGetTextureSamplerHandleNV(GLuint texture, GLuint sampler) {if (GLeeInit()) return glGetTextureSamplerHandleNV(texture, sampler); return (GLuint64)0;} + GLEEPFNGLGETTEXTURESAMPLERHANDLENVPROC GLeeFuncPtr_glGetTextureSamplerHandleNV=GLee_Lazy_glGetTextureSamplerHandleNV; +#endif +#ifndef GLEE_C_DEFINED_glMakeTextureHandleResidentNV +#define GLEE_C_DEFINED_glMakeTextureHandleResidentNV + void __stdcall GLee_Lazy_glMakeTextureHandleResidentNV(GLuint64 handle) {if (GLeeInit()) glMakeTextureHandleResidentNV(handle);} + GLEEPFNGLMAKETEXTUREHANDLERESIDENTNVPROC GLeeFuncPtr_glMakeTextureHandleResidentNV=GLee_Lazy_glMakeTextureHandleResidentNV; +#endif +#ifndef GLEE_C_DEFINED_glMakeTextureHandleNonResidentNV +#define GLEE_C_DEFINED_glMakeTextureHandleNonResidentNV + void __stdcall GLee_Lazy_glMakeTextureHandleNonResidentNV(GLuint64 handle) {if (GLeeInit()) glMakeTextureHandleNonResidentNV(handle);} + GLEEPFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC GLeeFuncPtr_glMakeTextureHandleNonResidentNV=GLee_Lazy_glMakeTextureHandleNonResidentNV; +#endif +#ifndef GLEE_C_DEFINED_glGetImageHandleNV +#define GLEE_C_DEFINED_glGetImageHandleNV + GLuint64 __stdcall GLee_Lazy_glGetImageHandleNV(GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format) {if (GLeeInit()) return glGetImageHandleNV(texture, level, layered, layer, format); return (GLuint64)0;} + GLEEPFNGLGETIMAGEHANDLENVPROC GLeeFuncPtr_glGetImageHandleNV=GLee_Lazy_glGetImageHandleNV; +#endif +#ifndef GLEE_C_DEFINED_glMakeImageHandleResidentNV +#define GLEE_C_DEFINED_glMakeImageHandleResidentNV + void __stdcall GLee_Lazy_glMakeImageHandleResidentNV(GLuint64 handle, GLenum access) {if (GLeeInit()) glMakeImageHandleResidentNV(handle, access);} + GLEEPFNGLMAKEIMAGEHANDLERESIDENTNVPROC GLeeFuncPtr_glMakeImageHandleResidentNV=GLee_Lazy_glMakeImageHandleResidentNV; +#endif +#ifndef GLEE_C_DEFINED_glMakeImageHandleNonResidentNV +#define GLEE_C_DEFINED_glMakeImageHandleNonResidentNV + void __stdcall GLee_Lazy_glMakeImageHandleNonResidentNV(GLuint64 handle) {if (GLeeInit()) glMakeImageHandleNonResidentNV(handle);} + GLEEPFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC GLeeFuncPtr_glMakeImageHandleNonResidentNV=GLee_Lazy_glMakeImageHandleNonResidentNV; +#endif +#ifndef GLEE_C_DEFINED_glUniformHandleui64NV +#define GLEE_C_DEFINED_glUniformHandleui64NV + void __stdcall GLee_Lazy_glUniformHandleui64NV(GLint location, GLuint64 value) {if (GLeeInit()) glUniformHandleui64NV(location, value);} + GLEEPFNGLUNIFORMHANDLEUI64NVPROC GLeeFuncPtr_glUniformHandleui64NV=GLee_Lazy_glUniformHandleui64NV; +#endif +#ifndef GLEE_C_DEFINED_glUniformHandleui64vNV +#define GLEE_C_DEFINED_glUniformHandleui64vNV + void __stdcall GLee_Lazy_glUniformHandleui64vNV(GLint location, GLsizei count, const GLuint64 * value) {if (GLeeInit()) glUniformHandleui64vNV(location, count, value);} + GLEEPFNGLUNIFORMHANDLEUI64VNVPROC GLeeFuncPtr_glUniformHandleui64vNV=GLee_Lazy_glUniformHandleui64vNV; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformHandleui64NV +#define GLEE_C_DEFINED_glProgramUniformHandleui64NV + void __stdcall GLee_Lazy_glProgramUniformHandleui64NV(GLuint program, GLint location, GLuint64 value) {if (GLeeInit()) glProgramUniformHandleui64NV(program, location, value);} + GLEEPFNGLPROGRAMUNIFORMHANDLEUI64NVPROC GLeeFuncPtr_glProgramUniformHandleui64NV=GLee_Lazy_glProgramUniformHandleui64NV; +#endif +#ifndef GLEE_C_DEFINED_glProgramUniformHandleui64vNV +#define GLEE_C_DEFINED_glProgramUniformHandleui64vNV + void __stdcall GLee_Lazy_glProgramUniformHandleui64vNV(GLuint program, GLint location, GLsizei count, const GLuint64 * values) {if (GLeeInit()) glProgramUniformHandleui64vNV(program, location, count, values);} + GLEEPFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC GLeeFuncPtr_glProgramUniformHandleui64vNV=GLee_Lazy_glProgramUniformHandleui64vNV; +#endif +#ifndef GLEE_C_DEFINED_glIsTextureHandleResidentNV +#define GLEE_C_DEFINED_glIsTextureHandleResidentNV + GLboolean __stdcall GLee_Lazy_glIsTextureHandleResidentNV(GLuint64 handle) {if (GLeeInit()) return glIsTextureHandleResidentNV(handle); return (GLboolean)0;} + GLEEPFNGLISTEXTUREHANDLERESIDENTNVPROC GLeeFuncPtr_glIsTextureHandleResidentNV=GLee_Lazy_glIsTextureHandleResidentNV; +#endif +#ifndef GLEE_C_DEFINED_glIsImageHandleResidentNV +#define GLEE_C_DEFINED_glIsImageHandleResidentNV + GLboolean __stdcall GLee_Lazy_glIsImageHandleResidentNV(GLuint64 handle) {if (GLeeInit()) return glIsImageHandleResidentNV(handle); return (GLboolean)0;} + GLEEPFNGLISIMAGEHANDLERESIDENTNVPROC GLeeFuncPtr_glIsImageHandleResidentNV=GLee_Lazy_glIsImageHandleResidentNV; +#endif +#endif + +/* GL_NV_shader_atomic_float */ + +#ifdef __GLEE_GL_NV_shader_atomic_float +#endif + +/* GL_AMD_query_buffer_object */ + +#ifdef __GLEE_GL_AMD_query_buffer_object +#endif + +/* GL_NV_compute_program5 */ + +#ifdef __GLEE_GL_NV_compute_program5 +#endif + +/* GL_NV_shader_storage_buffer_object */ + +#ifdef __GLEE_GL_NV_shader_storage_buffer_object +#endif + +/* GL_NV_shader_atomic_counters */ + +#ifdef __GLEE_GL_NV_shader_atomic_counters +#endif + +/* GL_NV_deep_texture3D */ + +#ifdef __GLEE_GL_NV_deep_texture3D +#endif + +/* GL_NVX_conditional_render */ + +#ifdef __GLEE_GL_NVX_conditional_render +#ifndef GLEE_C_DEFINED_glBeginConditionalRenderNVX +#define GLEE_C_DEFINED_glBeginConditionalRenderNVX + void __stdcall GLee_Lazy_glBeginConditionalRenderNVX(GLuint id) {if (GLeeInit()) glBeginConditionalRenderNVX(id);} + GLEEPFNGLBEGINCONDITIONALRENDERNVXPROC GLeeFuncPtr_glBeginConditionalRenderNVX=GLee_Lazy_glBeginConditionalRenderNVX; +#endif +#ifndef GLEE_C_DEFINED_glEndConditionalRenderNVX +#define GLEE_C_DEFINED_glEndConditionalRenderNVX + void __stdcall GLee_Lazy_glEndConditionalRenderNVX(void) {if (GLeeInit()) glEndConditionalRenderNVX();} + GLEEPFNGLENDCONDITIONALRENDERNVXPROC GLeeFuncPtr_glEndConditionalRenderNVX=GLee_Lazy_glEndConditionalRenderNVX; +#endif +#endif + +/* GL_AMD_sparse_texture */ + +#ifdef __GLEE_GL_AMD_sparse_texture +#ifndef GLEE_C_DEFINED_glTexStorageSparseAMD +#define GLEE_C_DEFINED_glTexStorageSparseAMD + void __stdcall GLee_Lazy_glTexStorageSparseAMD(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags) {if (GLeeInit()) glTexStorageSparseAMD(target, internalFormat, width, height, depth, layers, flags);} + GLEEPFNGLTEXSTORAGESPARSEAMDPROC GLeeFuncPtr_glTexStorageSparseAMD=GLee_Lazy_glTexStorageSparseAMD; +#endif +#ifndef GLEE_C_DEFINED_glTextureStorageSparseAMD +#define GLEE_C_DEFINED_glTextureStorageSparseAMD + void __stdcall GLee_Lazy_glTextureStorageSparseAMD(GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags) {if (GLeeInit()) glTextureStorageSparseAMD(texture, target, internalFormat, width, height, depth, layers, flags);} + GLEEPFNGLTEXTURESTORAGESPARSEAMDPROC GLeeFuncPtr_glTextureStorageSparseAMD=GLee_Lazy_glTextureStorageSparseAMD; +#endif +#endif + +/* GL_AMD_shader_trinary_minmax */ + +#ifdef __GLEE_GL_AMD_shader_trinary_minmax +#endif + +/* GL_INTEL_map_texture */ + +#ifdef __GLEE_GL_INTEL_map_texture +#ifndef GLEE_C_DEFINED_glSyncTextureINTEL +#define GLEE_C_DEFINED_glSyncTextureINTEL + void __stdcall GLee_Lazy_glSyncTextureINTEL(GLuint texture) {if (GLeeInit()) glSyncTextureINTEL(texture);} + GLEEPFNGLSYNCTEXTUREINTELPROC GLeeFuncPtr_glSyncTextureINTEL=GLee_Lazy_glSyncTextureINTEL; +#endif +#ifndef GLEE_C_DEFINED_glUnmapTexture2DINTEL +#define GLEE_C_DEFINED_glUnmapTexture2DINTEL + void __stdcall GLee_Lazy_glUnmapTexture2DINTEL(GLuint texture, GLint level) {if (GLeeInit()) glUnmapTexture2DINTEL(texture, level);} + GLEEPFNGLUNMAPTEXTURE2DINTELPROC GLeeFuncPtr_glUnmapTexture2DINTEL=GLee_Lazy_glUnmapTexture2DINTEL; +#endif +#ifndef GLEE_C_DEFINED_glMapTexture2DINTEL +#define GLEE_C_DEFINED_glMapTexture2DINTEL + GLvoid* __stdcall GLee_Lazy_glMapTexture2DINTEL(GLuint texture, GLint level, GLbitfield access, const GLint * stride, const GLenum * layout) {if (GLeeInit()) return glMapTexture2DINTEL(texture, level, access, stride, layout); return (GLvoid*)0;} + GLEEPFNGLMAPTEXTURE2DINTELPROC GLeeFuncPtr_glMapTexture2DINTEL=GLee_Lazy_glMapTexture2DINTEL; +#endif +#endif + +/* GL_NV_draw_texture */ + +#ifdef __GLEE_GL_NV_draw_texture +#ifndef GLEE_C_DEFINED_glDrawTextureNV +#define GLEE_C_DEFINED_glDrawTextureNV + void __stdcall GLee_Lazy_glDrawTextureNV(GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1) {if (GLeeInit()) glDrawTextureNV(texture, sampler, x0, y0, x1, y1, z, s0, t0, s1, t1);} + GLEEPFNGLDRAWTEXTURENVPROC GLeeFuncPtr_glDrawTextureNV=GLee_Lazy_glDrawTextureNV; +#endif +#endif + /* GL_SGIX_texture_select */ #ifdef __GLEE_GL_SGIX_texture_select @@ -12508,101 +14184,6 @@ int __GLeeGLNumExtensions=430; #endif #endif -/* GL_OES_compressed_paletted_texture */ - -#ifdef __GLEE_GL_OES_compressed_paletted_texture -#endif - -/* GL_OES_fixed_point */ - -#ifdef __GLEE_GL_OES_fixed_point -#endif - -/* GL_OES_single_precision */ - -#ifdef __GLEE_GL_OES_single_precision -#ifndef GLEE_C_DEFINED_glClearDepthfOES -#define GLEE_C_DEFINED_glClearDepthfOES - GLvoid __stdcall GLee_Lazy_glClearDepthfOES(GLclampd depth) {if (GLeeInit()) glClearDepthfOES(depth);} - GLEEPFNGLCLEARDEPTHFOESPROC GLeeFuncPtr_glClearDepthfOES=GLee_Lazy_glClearDepthfOES; -#endif -#endif - -/* GL_OES_query_matrix */ - -#ifdef __GLEE_GL_OES_query_matrix -#endif - -/* GL_OES_byte_coordinates */ - -#ifdef __GLEE_GL_OES_byte_coordinates -#endif - -/* GL_NV_gpu_program4 */ - -#ifdef __GLEE_GL_NV_gpu_program4 -#endif - -/* GL_NV_path_rendering */ - -#ifdef __GLEE_GL_NV_path_rendering -#endif - -/* GL_AMD_vertex_shader_tessellator */ - -#ifdef __GLEE_GL_AMD_vertex_shader_tessellator -#ifndef GLEE_C_DEFINED_glTessellationModeAMD -#define GLEE_C_DEFINED_glTessellationModeAMD - GLvoid __stdcall GLee_Lazy_glTessellationModeAMD(GLenum mode) {if (GLeeInit()) glTessellationModeAMD(mode);} - GLEEPFNGLTESSELLATIONMODEAMDPROC GLeeFuncPtr_glTessellationModeAMD=GLee_Lazy_glTessellationModeAMD; -#endif -#endif - -/* GL_EXT_fragment_lighting */ - -#ifdef __GLEE_GL_EXT_fragment_lighting -#endif - -/* GL_EXT_texture_compression_dxt1 */ - -#ifdef __GLEE_GL_EXT_texture_compression_dxt1 -#endif - -/* GL_EXT_scene_marker */ - -#ifdef __GLEE_GL_EXT_scene_marker -#ifndef GLEE_C_DEFINED_glEndSceneEXT -#define GLEE_C_DEFINED_glEndSceneEXT - GLvoid __stdcall GLee_Lazy_glEndSceneEXT(void) {if (GLeeInit()) glEndSceneEXT();} - GLEEPFNGLENDSCENEEXTPROC GLeeFuncPtr_glEndSceneEXT=GLee_Lazy_glEndSceneEXT; -#endif -#endif - -/* GL_EXT_geometry_shader4 */ - -#ifdef __GLEE_GL_EXT_geometry_shader4 -#endif - -/* GL_EXT_texture_env */ - -#ifdef __GLEE_GL_EXT_texture_env -#endif - -/* GL_SGIX_texture_range */ - -#ifdef __GLEE_GL_SGIX_texture_range -#endif - -/* GL_SGIX_pixel_texture_bits */ - -#ifdef __GLEE_GL_SGIX_pixel_texture_bits -#endif - -/* GL_IBM_static_data */ - -#ifdef __GLEE_GL_IBM_static_data -#endif - /* WGL */ #ifdef _WIN32 @@ -12647,6 +14228,8 @@ GLboolean _GLEE_WGL_NV_copy_image = GL_FALSE; GLboolean _GLEE_WGL_NV_multisample_coverage = GL_FALSE; GLboolean _GLEE_WGL_EXT_create_context_es2_profile = GL_FALSE; GLboolean _GLEE_WGL_NV_DX_interop = GL_FALSE; +GLboolean _GLEE_WGL_NV_DX_interop2 = GL_FALSE; +GLboolean _GLEE_WGL_EXT_swap_control_tear = GL_FALSE; GLboolean _GLEE_WGL_EXT_display_color_table = GL_FALSE; GLboolean _GLEE_WGL_EXT_extensions_string = GL_FALSE; GLboolean _GLEE_WGL_EXT_swap_control = GL_FALSE; @@ -12657,7 +14240,7 @@ GLboolean _GLEE_WGL_NV_video_output = GL_FALSE; /* WGL Extension names */ -char __GLeeWGLExtensionNames[45][35]={ +char __GLeeWGLExtensionNames[47][35]={ "WGL_ARB_buffer_region", "WGL_ARB_multisample", "WGL_ARB_extensions_string", @@ -12696,6 +14279,8 @@ char __GLeeWGLExtensionNames[45][35]={ "WGL_NV_multisample_coverage", "WGL_EXT_create_context_es2_profile", "WGL_NV_DX_interop", + "WGL_NV_DX_interop2", + "WGL_EXT_swap_control_tear", "WGL_EXT_display_color_table", "WGL_EXT_extensions_string", "WGL_EXT_swap_control", @@ -12704,7 +14289,7 @@ char __GLeeWGLExtensionNames[45][35]={ "WGL_I3D_swap_frame_usage", "WGL_NV_video_output" }; -int __GLeeWGLNumExtensions=45; +int __GLeeWGLNumExtensions=47; /* WGL_ARB_buffer_region */ @@ -13336,6 +14921,16 @@ int __GLeeWGLNumExtensions=45; #endif #endif +/* WGL_NV_DX_interop2 */ + +#ifdef __GLEE_WGL_NV_DX_interop2 +#endif + +/* WGL_EXT_swap_control_tear */ + +#ifdef __GLEE_WGL_EXT_swap_control_tear +#endif + /* WGL_EXT_display_color_table */ #ifdef __GLEE_WGL_EXT_display_color_table @@ -13549,12 +15144,14 @@ GLboolean _GLEE_GLX_INTEL_swap_event = GL_FALSE; GLboolean _GLEE_GLX_NV_multisample_coverage = GL_FALSE; GLboolean _GLEE_GLX_AMD_gpu_association = GL_FALSE; GLboolean _GLEE_GLX_EXT_create_context_es2_profile = GL_FALSE; +GLboolean _GLEE_GLX_EXT_create_context_es_profile = GL_FALSE; +GLboolean _GLEE_GLX_EXT_swap_control_tear = GL_FALSE; +GLboolean _GLEE_GLX_EXT_buffer_age = GL_FALSE; GLboolean _GLEE_GLX_NV_video_output = GL_FALSE; -GLboolean _GLEE_GLX_EXT_scene_marker = GL_FALSE; /* GLX Extension names */ -char __GLeeGLXExtensionNames[51][35]={ +char __GLeeGLXExtensionNames[53][35]={ "GLX_VERSION_1_3", "GLX_VERSION_1_4", "GLX_ARB_multisample", @@ -13604,10 +15201,12 @@ char __GLeeGLXExtensionNames[51][35]={ "GLX_NV_multisample_coverage", "GLX_AMD_gpu_association", "GLX_EXT_create_context_es2_profile", - "GLX_NV_video_output", - "GLX_EXT_scene_marker" + "GLX_EXT_create_context_es_profile", + "GLX_EXT_swap_control_tear", + "GLX_EXT_buffer_age", + "GLX_NV_video_output" }; -int __GLeeGLXNumExtensions=51; +int __GLeeGLXNumExtensions=53; /* GLX_VERSION_1_3 */ @@ -13824,12 +15423,12 @@ int __GLeeGLXNumExtensions=51; #endif #ifndef GLEE_C_DEFINED_glXGetContextIDEXT #define GLEE_C_DEFINED_glXGetContextIDEXT - GLXContextID __stdcall GLee_Lazy_glXGetContextIDEXT(const GLXContext context) {if (GLeeInit()) return glXGetContextIDEXT(context); return (GLXContextID)0;} + GLEE_GLXContextID __stdcall GLee_Lazy_glXGetContextIDEXT(const GLXContext context) {if (GLeeInit()) return glXGetContextIDEXT(context); return (GLEE_GLXContextID)0;} GLEEPFNGLXGETCONTEXTIDEXTPROC GLeeFuncPtr_glXGetContextIDEXT=GLee_Lazy_glXGetContextIDEXT; #endif #ifndef GLEE_C_DEFINED_glXImportContextEXT #define GLEE_C_DEFINED_glXImportContextEXT - GLXContext __stdcall GLee_Lazy_glXImportContextEXT(Display * dpy, GLXContextID contextID) {if (GLeeInit()) return glXImportContextEXT(dpy, contextID); return (GLXContext)0;} + GLXContext __stdcall GLee_Lazy_glXImportContextEXT(Display * dpy, GLEE_GLXContextID contextID) {if (GLeeInit()) return glXImportContextEXT(dpy, contextID); return (GLXContext)0;} GLEEPFNGLXIMPORTCONTEXTEXTPROC GLeeFuncPtr_glXImportContextEXT=GLee_Lazy_glXImportContextEXT; #endif #ifndef GLEE_C_DEFINED_glXFreeContextEXT @@ -14249,7 +15848,7 @@ int __GLeeGLXNumExtensions=51; #ifdef __GLEE_GLX_EXT_swap_control #ifndef GLEE_C_DEFINED_glXSwapIntervalEXT #define GLEE_C_DEFINED_glXSwapIntervalEXT - int __stdcall GLee_Lazy_glXSwapIntervalEXT(Display * dpy, GLXDrawable drawable, int interval) {if (GLeeInit()) return glXSwapIntervalEXT(dpy, drawable, interval); return (int)0;} + void __stdcall GLee_Lazy_glXSwapIntervalEXT(Display * dpy, GLXDrawable drawable, int interval) {if (GLeeInit()) glXSwapIntervalEXT(dpy, drawable, interval);} GLEEPFNGLXSWAPINTERVALEXTPROC GLeeFuncPtr_glXSwapIntervalEXT=GLee_Lazy_glXSwapIntervalEXT; #endif #endif @@ -14284,6 +15883,21 @@ int __GLeeGLXNumExtensions=51; #ifdef __GLEE_GLX_EXT_create_context_es2_profile #endif +/* GLX_EXT_create_context_es_profile */ + +#ifdef __GLEE_GLX_EXT_create_context_es_profile +#endif + +/* GLX_EXT_swap_control_tear */ + +#ifdef __GLEE_GLX_EXT_swap_control_tear +#endif + +/* GLX_EXT_buffer_age */ + +#ifdef __GLEE_GLX_EXT_buffer_age +#endif + /* GLX_NV_video_output */ #ifdef __GLEE_GLX_NV_video_output @@ -14318,11 +15932,6 @@ int __GLeeGLXNumExtensions=51; GLEEPFNGLXGETVIDEOINFONVPROC GLeeFuncPtr_glXGetVideoInfoNV=GLee_Lazy_glXGetVideoInfoNV; #endif #endif - -/* GLX_EXT_scene_marker */ - -#ifdef __GLEE_GLX_EXT_scene_marker -#endif #endif /* end GLX */ /***************************************************************** * Extension link functions @@ -14762,6 +16371,8 @@ GLuint __GLeeLink_GL_VERSION_4_1(void) {return GLEE_LINK_COMPLETE;} GLuint __GLeeLink_GL_VERSION_4_2(void) {return GLEE_LINK_COMPLETE;} +GLuint __GLeeLink_GL_VERSION_4_3(void) {return GLEE_LINK_COMPLETE;} + GLuint __GLeeLink_GL_ARB_multitexture(void) { GLint nLinked=0; @@ -15778,6 +17389,20 @@ GLuint __GLeeLink_GL_ARB_cl_event(void) return GLEE_LINK_PARTIAL; } +GLuint __GLeeLink_GL_ARB_debug_output(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_debug_output + if ((GLeeFuncPtr_glDebugMessageControlARB = (GLEEPFNGLDEBUGMESSAGECONTROLARBPROC) __GLeeGetProcAddress("glDebugMessageControlARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDebugMessageInsertARB = (GLEEPFNGLDEBUGMESSAGEINSERTARBPROC) __GLeeGetProcAddress("glDebugMessageInsertARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glDebugMessageCallbackARB = (GLEEPFNGLDEBUGMESSAGECALLBACKARBPROC) __GLeeGetProcAddress("glDebugMessageCallbackARB"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetDebugMessageLogARB = (GLEEPFNGLGETDEBUGMESSAGELOGARBPROC) __GLeeGetProcAddress("glGetDebugMessageLogARB"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + GLuint __GLeeLink_GL_ARB_robustness(void) { GLint nLinked=0; @@ -15895,6 +17520,222 @@ GLuint __GLeeLink_GL_ARB_texture_storage(void) return GLEE_LINK_PARTIAL; } +GLuint __GLeeLink_GL_KHR_texture_compression_astc_ldr(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_KHR_debug(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_KHR_debug + if ((GLeeFuncPtr_glDebugMessageControl = (GLEEPFNGLDEBUGMESSAGECONTROLPROC) __GLeeGetProcAddress("glDebugMessageControl"))!=0) nLinked++; + if ((GLeeFuncPtr_glDebugMessageInsert = (GLEEPFNGLDEBUGMESSAGEINSERTPROC) __GLeeGetProcAddress("glDebugMessageInsert"))!=0) nLinked++; + if ((GLeeFuncPtr_glDebugMessageCallback = (GLEEPFNGLDEBUGMESSAGECALLBACKPROC) __GLeeGetProcAddress("glDebugMessageCallback"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetDebugMessageLog = (GLEEPFNGLGETDEBUGMESSAGELOGPROC) __GLeeGetProcAddress("glGetDebugMessageLog"))!=0) nLinked++; + if ((GLeeFuncPtr_glPushDebugGroup = (GLEEPFNGLPUSHDEBUGGROUPPROC) __GLeeGetProcAddress("glPushDebugGroup"))!=0) nLinked++; + if ((GLeeFuncPtr_glPopDebugGroup = (GLEEPFNGLPOPDEBUGGROUPPROC) __GLeeGetProcAddress("glPopDebugGroup"))!=0) nLinked++; + if ((GLeeFuncPtr_glObjectLabel = (GLEEPFNGLOBJECTLABELPROC) __GLeeGetProcAddress("glObjectLabel"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetObjectLabel = (GLEEPFNGLGETOBJECTLABELPROC) __GLeeGetProcAddress("glGetObjectLabel"))!=0) nLinked++; + if ((GLeeFuncPtr_glObjectPtrLabel = (GLEEPFNGLOBJECTPTRLABELPROC) __GLeeGetProcAddress("glObjectPtrLabel"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetObjectPtrLabel = (GLEEPFNGLGETOBJECTPTRLABELPROC) __GLeeGetProcAddress("glGetObjectPtrLabel"))!=0) nLinked++; +#endif + if (nLinked==10) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_arrays_of_arrays(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_clear_buffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_clear_buffer_object + if ((GLeeFuncPtr_glClearBufferData = (GLEEPFNGLCLEARBUFFERDATAPROC) __GLeeGetProcAddress("glClearBufferData"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearBufferSubData = (GLEEPFNGLCLEARBUFFERSUBDATAPROC) __GLeeGetProcAddress("glClearBufferSubData"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearNamedBufferDataEXT = (GLEEPFNGLCLEARNAMEDBUFFERDATAEXTPROC) __GLeeGetProcAddress("glClearNamedBufferDataEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearNamedBufferSubDataEXT = (GLEEPFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) __GLeeGetProcAddress("glClearNamedBufferSubDataEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_compute_shader(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_compute_shader + if ((GLeeFuncPtr_glDispatchCompute = (GLEEPFNGLDISPATCHCOMPUTEPROC) __GLeeGetProcAddress("glDispatchCompute"))!=0) nLinked++; + if ((GLeeFuncPtr_glDispatchComputeIndirect = (GLEEPFNGLDISPATCHCOMPUTEINDIRECTPROC) __GLeeGetProcAddress("glDispatchComputeIndirect"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_copy_image(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_copy_image + if ((GLeeFuncPtr_glCopyImageSubData = (GLEEPFNGLCOPYIMAGESUBDATAPROC) __GLeeGetProcAddress("glCopyImageSubData"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_view(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_texture_view + if ((GLeeFuncPtr_glTextureView = (GLEEPFNGLTEXTUREVIEWPROC) __GLeeGetProcAddress("glTextureView"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_vertex_attrib_binding(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_vertex_attrib_binding + if ((GLeeFuncPtr_glBindVertexBuffer = (GLEEPFNGLBINDVERTEXBUFFERPROC) __GLeeGetProcAddress("glBindVertexBuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribFormat = (GLEEPFNGLVERTEXATTRIBFORMATPROC) __GLeeGetProcAddress("glVertexAttribFormat"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribIFormat = (GLEEPFNGLVERTEXATTRIBIFORMATPROC) __GLeeGetProcAddress("glVertexAttribIFormat"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribLFormat = (GLEEPFNGLVERTEXATTRIBLFORMATPROC) __GLeeGetProcAddress("glVertexAttribLFormat"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexAttribBinding = (GLEEPFNGLVERTEXATTRIBBINDINGPROC) __GLeeGetProcAddress("glVertexAttribBinding"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexBindingDivisor = (GLEEPFNGLVERTEXBINDINGDIVISORPROC) __GLeeGetProcAddress("glVertexBindingDivisor"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayBindVertexBufferEXT = (GLEEPFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) __GLeeGetProcAddress("glVertexArrayBindVertexBufferEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayVertexAttribFormatEXT = (GLEEPFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) __GLeeGetProcAddress("glVertexArrayVertexAttribFormatEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayVertexAttribIFormatEXT = (GLEEPFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) __GLeeGetProcAddress("glVertexArrayVertexAttribIFormatEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayVertexAttribLFormatEXT = (GLEEPFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) __GLeeGetProcAddress("glVertexArrayVertexAttribLFormatEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayVertexAttribBindingEXT = (GLEEPFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) __GLeeGetProcAddress("glVertexArrayVertexAttribBindingEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertexArrayVertexBindingDivisorEXT = (GLEEPFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) __GLeeGetProcAddress("glVertexArrayVertexBindingDivisorEXT"))!=0) nLinked++; +#endif + if (nLinked==12) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_robustness_isolation(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_ES3_compatibility(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_explicit_uniform_location(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_fragment_layer_viewport(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_framebuffer_no_attachments(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_framebuffer_no_attachments + if ((GLeeFuncPtr_glFramebufferParameteri = (GLEEPFNGLFRAMEBUFFERPARAMETERIPROC) __GLeeGetProcAddress("glFramebufferParameteri"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFramebufferParameteriv = (GLEEPFNGLGETFRAMEBUFFERPARAMETERIVPROC) __GLeeGetProcAddress("glGetFramebufferParameteriv"))!=0) nLinked++; + if ((GLeeFuncPtr_glNamedFramebufferParameteriEXT = (GLEEPFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) __GLeeGetProcAddress("glNamedFramebufferParameteriEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetNamedFramebufferParameterivEXT = (GLEEPFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetNamedFramebufferParameterivEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_internalformat_query2(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_internalformat_query2 + if ((GLeeFuncPtr_glGetInternalformati64v = (GLEEPFNGLGETINTERNALFORMATI64VPROC) __GLeeGetProcAddress("glGetInternalformati64v"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_invalidate_subdata(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_invalidate_subdata + if ((GLeeFuncPtr_glInvalidateTexSubImage = (GLEEPFNGLINVALIDATETEXSUBIMAGEPROC) __GLeeGetProcAddress("glInvalidateTexSubImage"))!=0) nLinked++; + if ((GLeeFuncPtr_glInvalidateTexImage = (GLEEPFNGLINVALIDATETEXIMAGEPROC) __GLeeGetProcAddress("glInvalidateTexImage"))!=0) nLinked++; + if ((GLeeFuncPtr_glInvalidateBufferSubData = (GLEEPFNGLINVALIDATEBUFFERSUBDATAPROC) __GLeeGetProcAddress("glInvalidateBufferSubData"))!=0) nLinked++; + if ((GLeeFuncPtr_glInvalidateBufferData = (GLEEPFNGLINVALIDATEBUFFERDATAPROC) __GLeeGetProcAddress("glInvalidateBufferData"))!=0) nLinked++; + if ((GLeeFuncPtr_glInvalidateFramebuffer = (GLEEPFNGLINVALIDATEFRAMEBUFFERPROC) __GLeeGetProcAddress("glInvalidateFramebuffer"))!=0) nLinked++; + if ((GLeeFuncPtr_glInvalidateSubFramebuffer = (GLEEPFNGLINVALIDATESUBFRAMEBUFFERPROC) __GLeeGetProcAddress("glInvalidateSubFramebuffer"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_multi_draw_indirect(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_multi_draw_indirect + if ((GLeeFuncPtr_glMultiDrawArraysIndirect = (GLEEPFNGLMULTIDRAWARRAYSINDIRECTPROC) __GLeeGetProcAddress("glMultiDrawArraysIndirect"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiDrawElementsIndirect = (GLEEPFNGLMULTIDRAWELEMENTSINDIRECTPROC) __GLeeGetProcAddress("glMultiDrawElementsIndirect"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_program_interface_query(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_program_interface_query + if ((GLeeFuncPtr_glGetProgramInterfaceiv = (GLEEPFNGLGETPROGRAMINTERFACEIVPROC) __GLeeGetProcAddress("glGetProgramInterfaceiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramResourceIndex = (GLEEPFNGLGETPROGRAMRESOURCEINDEXPROC) __GLeeGetProcAddress("glGetProgramResourceIndex"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramResourceName = (GLEEPFNGLGETPROGRAMRESOURCENAMEPROC) __GLeeGetProcAddress("glGetProgramResourceName"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramResourceiv = (GLEEPFNGLGETPROGRAMRESOURCEIVPROC) __GLeeGetProcAddress("glGetProgramResourceiv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramResourceLocation = (GLEEPFNGLGETPROGRAMRESOURCELOCATIONPROC) __GLeeGetProcAddress("glGetProgramResourceLocation"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetProgramResourceLocationIndex = (GLEEPFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) __GLeeGetProcAddress("glGetProgramResourceLocationIndex"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_robust_buffer_access_behavior(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_shader_image_size(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_shader_storage_buffer_object(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_shader_storage_buffer_object + if ((GLeeFuncPtr_glShaderStorageBlockBinding = (GLEEPFNGLSHADERSTORAGEBLOCKBINDINGPROC) __GLeeGetProcAddress("glShaderStorageBlockBinding"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_stencil_texturing(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_buffer_range(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_texture_buffer_range + if ((GLeeFuncPtr_glTexBufferRange = (GLEEPFNGLTEXBUFFERRANGEPROC) __GLeeGetProcAddress("glTexBufferRange"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureBufferRangeEXT = (GLEEPFNGLTEXTUREBUFFERRANGEEXTPROC) __GLeeGetProcAddress("glTextureBufferRangeEXT"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_ARB_texture_query_levels(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_ARB_texture_storage_multisample(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_ARB_texture_storage_multisample + if ((GLeeFuncPtr_glTexStorage2DMultisample = (GLEEPFNGLTEXSTORAGE2DMULTISAMPLEPROC) __GLeeGetProcAddress("glTexStorage2DMultisample"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexStorage3DMultisample = (GLEEPFNGLTEXSTORAGE3DMULTISAMPLEPROC) __GLeeGetProcAddress("glTexStorage3DMultisample"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureStorage2DMultisampleEXT = (GLEEPFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) __GLeeGetProcAddress("glTextureStorage2DMultisampleEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureStorage3DMultisampleEXT = (GLEEPFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) __GLeeGetProcAddress("glTextureStorage3DMultisampleEXT"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + GLuint __GLeeLink_GL_EXT_abgr(void) {return GLEE_LINK_COMPLETE;} GLuint __GLeeLink_GL_EXT_blend_color(void) @@ -16572,8 +18413,10 @@ GLuint __GLeeLink_GL_EXT_pixel_transform(void) if ((GLeeFuncPtr_glPixelTransformParameterfEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERFEXTPROC) __GLeeGetProcAddress("glPixelTransformParameterfEXT"))!=0) nLinked++; if ((GLeeFuncPtr_glPixelTransformParameterivEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) __GLeeGetProcAddress("glPixelTransformParameterivEXT"))!=0) nLinked++; if ((GLeeFuncPtr_glPixelTransformParameterfvEXT = (GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) __GLeeGetProcAddress("glPixelTransformParameterfvEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPixelTransformParameterivEXT = (GLEEPFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) __GLeeGetProcAddress("glGetPixelTransformParameterivEXT"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPixelTransformParameterfvEXT = (GLEEPFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) __GLeeGetProcAddress("glGetPixelTransformParameterfvEXT"))!=0) nLinked++; #endif - if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==6) return GLEE_LINK_COMPLETE; if (nLinked==0) return GLEE_LINK_FAIL; return GLEE_LINK_PARTIAL; } @@ -17508,8 +19351,8 @@ GLuint __GLeeLink_GL_NV_fragment_program(void) GLint nLinked=0; #ifdef __GLEE_GL_NV_fragment_program if ((GLeeFuncPtr_glProgramNamedParameter4fNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4fNV"))!=0) nLinked++; - if ((GLeeFuncPtr_glProgramNamedParameter4dNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4dNV"))!=0) nLinked++; if ((GLeeFuncPtr_glProgramNamedParameter4fvNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4fvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramNamedParameter4dNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4dNV"))!=0) nLinked++; if ((GLeeFuncPtr_glProgramNamedParameter4dvNV = (GLEEPFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) __GLeeGetProcAddress("glProgramNamedParameter4dvNV"))!=0) nLinked++; if ((GLeeFuncPtr_glGetProgramNamedParameterfvNV = (GLEEPFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetProgramNamedParameterfvNV"))!=0) nLinked++; if ((GLeeFuncPtr_glGetProgramNamedParameterdvNV = (GLEEPFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) __GLeeGetProcAddress("glGetProgramNamedParameterdvNV"))!=0) nLinked++; @@ -17640,8 +19483,183 @@ GLuint __GLeeLink_GL_ATI_vertex_attrib_array_object(void) return GLEE_LINK_PARTIAL; } +GLuint __GLeeLink_GL_OES_byte_coordinates(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_OES_byte_coordinates + if ((GLeeFuncPtr_glMultiTexCoord1bOES = (GLEEPFNGLMULTITEXCOORD1BOESPROC) __GLeeGetProcAddress("glMultiTexCoord1bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1bvOES = (GLEEPFNGLMULTITEXCOORD1BVOESPROC) __GLeeGetProcAddress("glMultiTexCoord1bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2bOES = (GLEEPFNGLMULTITEXCOORD2BOESPROC) __GLeeGetProcAddress("glMultiTexCoord2bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2bvOES = (GLEEPFNGLMULTITEXCOORD2BVOESPROC) __GLeeGetProcAddress("glMultiTexCoord2bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3bOES = (GLEEPFNGLMULTITEXCOORD3BOESPROC) __GLeeGetProcAddress("glMultiTexCoord3bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3bvOES = (GLEEPFNGLMULTITEXCOORD3BVOESPROC) __GLeeGetProcAddress("glMultiTexCoord3bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4bOES = (GLEEPFNGLMULTITEXCOORD4BOESPROC) __GLeeGetProcAddress("glMultiTexCoord4bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4bvOES = (GLEEPFNGLMULTITEXCOORD4BVOESPROC) __GLeeGetProcAddress("glMultiTexCoord4bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord1bOES = (GLEEPFNGLTEXCOORD1BOESPROC) __GLeeGetProcAddress("glTexCoord1bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord1bvOES = (GLEEPFNGLTEXCOORD1BVOESPROC) __GLeeGetProcAddress("glTexCoord1bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2bOES = (GLEEPFNGLTEXCOORD2BOESPROC) __GLeeGetProcAddress("glTexCoord2bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2bvOES = (GLEEPFNGLTEXCOORD2BVOESPROC) __GLeeGetProcAddress("glTexCoord2bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord3bOES = (GLEEPFNGLTEXCOORD3BOESPROC) __GLeeGetProcAddress("glTexCoord3bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord3bvOES = (GLEEPFNGLTEXCOORD3BVOESPROC) __GLeeGetProcAddress("glTexCoord3bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4bOES = (GLEEPFNGLTEXCOORD4BOESPROC) __GLeeGetProcAddress("glTexCoord4bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4bvOES = (GLEEPFNGLTEXCOORD4BVOESPROC) __GLeeGetProcAddress("glTexCoord4bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex2bOES = (GLEEPFNGLVERTEX2BOESPROC) __GLeeGetProcAddress("glVertex2bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex2bvOES = (GLEEPFNGLVERTEX2BVOESPROC) __GLeeGetProcAddress("glVertex2bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex3bOES = (GLEEPFNGLVERTEX3BOESPROC) __GLeeGetProcAddress("glVertex3bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex3bvOES = (GLEEPFNGLVERTEX3BVOESPROC) __GLeeGetProcAddress("glVertex3bvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex4bOES = (GLEEPFNGLVERTEX4BOESPROC) __GLeeGetProcAddress("glVertex4bOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex4bvOES = (GLEEPFNGLVERTEX4BVOESPROC) __GLeeGetProcAddress("glVertex4bvOES"))!=0) nLinked++; +#endif + if (nLinked==22) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_OES_fixed_point(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_OES_fixed_point + if ((GLeeFuncPtr_glAccumxOES = (GLEEPFNGLACCUMXOESPROC) __GLeeGetProcAddress("glAccumxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glAlphaFuncxOES = (GLEEPFNGLALPHAFUNCXOESPROC) __GLeeGetProcAddress("glAlphaFuncxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glBitmapxOES = (GLEEPFNGLBITMAPXOESPROC) __GLeeGetProcAddress("glBitmapxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glBlendColorxOES = (GLEEPFNGLBLENDCOLORXOESPROC) __GLeeGetProcAddress("glBlendColorxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearAccumxOES = (GLEEPFNGLCLEARACCUMXOESPROC) __GLeeGetProcAddress("glClearAccumxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearColorxOES = (GLEEPFNGLCLEARCOLORXOESPROC) __GLeeGetProcAddress("glClearColorxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearDepthxOES = (GLEEPFNGLCLEARDEPTHXOESPROC) __GLeeGetProcAddress("glClearDepthxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClipPlanexOES = (GLEEPFNGLCLIPPLANEXOESPROC) __GLeeGetProcAddress("glClipPlanexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor3xOES = (GLEEPFNGLCOLOR3XOESPROC) __GLeeGetProcAddress("glColor3xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4xOES = (GLEEPFNGLCOLOR4XOESPROC) __GLeeGetProcAddress("glColor4xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor3xvOES = (GLEEPFNGLCOLOR3XVOESPROC) __GLeeGetProcAddress("glColor3xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glColor4xvOES = (GLEEPFNGLCOLOR4XVOESPROC) __GLeeGetProcAddress("glColor4xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterxOES = (GLEEPFNGLCONVOLUTIONPARAMETERXOESPROC) __GLeeGetProcAddress("glConvolutionParameterxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glConvolutionParameterxvOES = (GLEEPFNGLCONVOLUTIONPARAMETERXVOESPROC) __GLeeGetProcAddress("glConvolutionParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glDepthRangexOES = (GLEEPFNGLDEPTHRANGEXOESPROC) __GLeeGetProcAddress("glDepthRangexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glEvalCoord1xOES = (GLEEPFNGLEVALCOORD1XOESPROC) __GLeeGetProcAddress("glEvalCoord1xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glEvalCoord2xOES = (GLEEPFNGLEVALCOORD2XOESPROC) __GLeeGetProcAddress("glEvalCoord2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glEvalCoord1xvOES = (GLEEPFNGLEVALCOORD1XVOESPROC) __GLeeGetProcAddress("glEvalCoord1xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glEvalCoord2xvOES = (GLEEPFNGLEVALCOORD2XVOESPROC) __GLeeGetProcAddress("glEvalCoord2xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glFeedbackBufferxOES = (GLEEPFNGLFEEDBACKBUFFERXOESPROC) __GLeeGetProcAddress("glFeedbackBufferxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogxOES = (GLEEPFNGLFOGXOESPROC) __GLeeGetProcAddress("glFogxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glFogxvOES = (GLEEPFNGLFOGXVOESPROC) __GLeeGetProcAddress("glFogxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glFrustumxOES = (GLEEPFNGLFRUSTUMXOESPROC) __GLeeGetProcAddress("glFrustumxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetClipPlanexOES = (GLEEPFNGLGETCLIPPLANEXOESPROC) __GLeeGetProcAddress("glGetClipPlanexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetConvolutionParameterxvOES = (GLEEPFNGLGETCONVOLUTIONPARAMETERXVOESPROC) __GLeeGetProcAddress("glGetConvolutionParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetFixedvOES = (GLEEPFNGLGETFIXEDVOESPROC) __GLeeGetProcAddress("glGetFixedvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetHistogramParameterxvOES = (GLEEPFNGLGETHISTOGRAMPARAMETERXVOESPROC) __GLeeGetProcAddress("glGetHistogramParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetLightxOES = (GLEEPFNGLGETLIGHTXOESPROC) __GLeeGetProcAddress("glGetLightxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMapxvOES = (GLEEPFNGLGETMAPXVOESPROC) __GLeeGetProcAddress("glGetMapxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetMaterialxOES = (GLEEPFNGLGETMATERIALXOESPROC) __GLeeGetProcAddress("glGetMaterialxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPixelMapxv = (GLEEPFNGLGETPIXELMAPXVPROC) __GLeeGetProcAddress("glGetPixelMapxv"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexEnvxvOES = (GLEEPFNGLGETTEXENVXVOESPROC) __GLeeGetProcAddress("glGetTexEnvxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexGenxvOES = (GLEEPFNGLGETTEXGENXVOESPROC) __GLeeGetProcAddress("glGetTexGenxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexLevelParameterxvOES = (GLEEPFNGLGETTEXLEVELPARAMETERXVOESPROC) __GLeeGetProcAddress("glGetTexLevelParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTexParameterxvOES = (GLEEPFNGLGETTEXPARAMETERXVOESPROC) __GLeeGetProcAddress("glGetTexParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glIndexxOES = (GLEEPFNGLINDEXXOESPROC) __GLeeGetProcAddress("glIndexxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glIndexxvOES = (GLEEPFNGLINDEXXVOESPROC) __GLeeGetProcAddress("glIndexxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLightModelxOES = (GLEEPFNGLLIGHTMODELXOESPROC) __GLeeGetProcAddress("glLightModelxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLightModelxvOES = (GLEEPFNGLLIGHTMODELXVOESPROC) __GLeeGetProcAddress("glLightModelxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLightxOES = (GLEEPFNGLLIGHTXOESPROC) __GLeeGetProcAddress("glLightxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLightxvOES = (GLEEPFNGLLIGHTXVOESPROC) __GLeeGetProcAddress("glLightxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLineWidthxOES = (GLEEPFNGLLINEWIDTHXOESPROC) __GLeeGetProcAddress("glLineWidthxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadMatrixxOES = (GLEEPFNGLLOADMATRIXXOESPROC) __GLeeGetProcAddress("glLoadMatrixxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glLoadTransposeMatrixxOES = (GLEEPFNGLLOADTRANSPOSEMATRIXXOESPROC) __GLeeGetProcAddress("glLoadTransposeMatrixxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMap1xOES = (GLEEPFNGLMAP1XOESPROC) __GLeeGetProcAddress("glMap1xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMap2xOES = (GLEEPFNGLMAP2XOESPROC) __GLeeGetProcAddress("glMap2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapGrid1xOES = (GLEEPFNGLMAPGRID1XOESPROC) __GLeeGetProcAddress("glMapGrid1xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapGrid2xOES = (GLEEPFNGLMAPGRID2XOESPROC) __GLeeGetProcAddress("glMapGrid2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMaterialxOES = (GLEEPFNGLMATERIALXOESPROC) __GLeeGetProcAddress("glMaterialxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMaterialxvOES = (GLEEPFNGLMATERIALXVOESPROC) __GLeeGetProcAddress("glMaterialxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultMatrixxOES = (GLEEPFNGLMULTMATRIXXOESPROC) __GLeeGetProcAddress("glMultMatrixxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultTransposeMatrixxOES = (GLEEPFNGLMULTTRANSPOSEMATRIXXOESPROC) __GLeeGetProcAddress("glMultTransposeMatrixxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1xOES = (GLEEPFNGLMULTITEXCOORD1XOESPROC) __GLeeGetProcAddress("glMultiTexCoord1xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2xOES = (GLEEPFNGLMULTITEXCOORD2XOESPROC) __GLeeGetProcAddress("glMultiTexCoord2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3xOES = (GLEEPFNGLMULTITEXCOORD3XOESPROC) __GLeeGetProcAddress("glMultiTexCoord3xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4xOES = (GLEEPFNGLMULTITEXCOORD4XOESPROC) __GLeeGetProcAddress("glMultiTexCoord4xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord1xvOES = (GLEEPFNGLMULTITEXCOORD1XVOESPROC) __GLeeGetProcAddress("glMultiTexCoord1xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord2xvOES = (GLEEPFNGLMULTITEXCOORD2XVOESPROC) __GLeeGetProcAddress("glMultiTexCoord2xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord3xvOES = (GLEEPFNGLMULTITEXCOORD3XVOESPROC) __GLeeGetProcAddress("glMultiTexCoord3xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glMultiTexCoord4xvOES = (GLEEPFNGLMULTITEXCOORD4XVOESPROC) __GLeeGetProcAddress("glMultiTexCoord4xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormal3xOES = (GLEEPFNGLNORMAL3XOESPROC) __GLeeGetProcAddress("glNormal3xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glNormal3xvOES = (GLEEPFNGLNORMAL3XVOESPROC) __GLeeGetProcAddress("glNormal3xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glOrthoxOES = (GLEEPFNGLORTHOXOESPROC) __GLeeGetProcAddress("glOrthoxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPassThroughxOES = (GLEEPFNGLPASSTHROUGHXOESPROC) __GLeeGetProcAddress("glPassThroughxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelMapx = (GLEEPFNGLPIXELMAPXPROC) __GLeeGetProcAddress("glPixelMapx"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelStorex = (GLEEPFNGLPIXELSTOREXPROC) __GLeeGetProcAddress("glPixelStorex"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelTransferxOES = (GLEEPFNGLPIXELTRANSFERXOESPROC) __GLeeGetProcAddress("glPixelTransferxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPixelZoomxOES = (GLEEPFNGLPIXELZOOMXOESPROC) __GLeeGetProcAddress("glPixelZoomxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointParameterxvOES = (GLEEPFNGLPOINTPARAMETERXVOESPROC) __GLeeGetProcAddress("glPointParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointSizexOES = (GLEEPFNGLPOINTSIZEXOESPROC) __GLeeGetProcAddress("glPointSizexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPolygonOffsetxOES = (GLEEPFNGLPOLYGONOFFSETXOESPROC) __GLeeGetProcAddress("glPolygonOffsetxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glPrioritizeTexturesxOES = (GLEEPFNGLPRIORITIZETEXTURESXOESPROC) __GLeeGetProcAddress("glPrioritizeTexturesxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRasterPos2xOES = (GLEEPFNGLRASTERPOS2XOESPROC) __GLeeGetProcAddress("glRasterPos2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRasterPos3xOES = (GLEEPFNGLRASTERPOS3XOESPROC) __GLeeGetProcAddress("glRasterPos3xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRasterPos4xOES = (GLEEPFNGLRASTERPOS4XOESPROC) __GLeeGetProcAddress("glRasterPos4xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRasterPos2xvOES = (GLEEPFNGLRASTERPOS2XVOESPROC) __GLeeGetProcAddress("glRasterPos2xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRasterPos3xvOES = (GLEEPFNGLRASTERPOS3XVOESPROC) __GLeeGetProcAddress("glRasterPos3xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRasterPos4xvOES = (GLEEPFNGLRASTERPOS4XVOESPROC) __GLeeGetProcAddress("glRasterPos4xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRectxOES = (GLEEPFNGLRECTXOESPROC) __GLeeGetProcAddress("glRectxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRectxvOES = (GLEEPFNGLRECTXVOESPROC) __GLeeGetProcAddress("glRectxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glRotatexOES = (GLEEPFNGLROTATEXOESPROC) __GLeeGetProcAddress("glRotatexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glSampleCoverageOES = (GLEEPFNGLSAMPLECOVERAGEOESPROC) __GLeeGetProcAddress("glSampleCoverageOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glScalexOES = (GLEEPFNGLSCALEXOESPROC) __GLeeGetProcAddress("glScalexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord1xOES = (GLEEPFNGLTEXCOORD1XOESPROC) __GLeeGetProcAddress("glTexCoord1xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2xOES = (GLEEPFNGLTEXCOORD2XOESPROC) __GLeeGetProcAddress("glTexCoord2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord3xOES = (GLEEPFNGLTEXCOORD3XOESPROC) __GLeeGetProcAddress("glTexCoord3xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4xOES = (GLEEPFNGLTEXCOORD4XOESPROC) __GLeeGetProcAddress("glTexCoord4xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord1xvOES = (GLEEPFNGLTEXCOORD1XVOESPROC) __GLeeGetProcAddress("glTexCoord1xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord2xvOES = (GLEEPFNGLTEXCOORD2XVOESPROC) __GLeeGetProcAddress("glTexCoord2xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord3xvOES = (GLEEPFNGLTEXCOORD3XVOESPROC) __GLeeGetProcAddress("glTexCoord3xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexCoord4xvOES = (GLEEPFNGLTEXCOORD4XVOESPROC) __GLeeGetProcAddress("glTexCoord4xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexEnvxOES = (GLEEPFNGLTEXENVXOESPROC) __GLeeGetProcAddress("glTexEnvxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexEnvxvOES = (GLEEPFNGLTEXENVXVOESPROC) __GLeeGetProcAddress("glTexEnvxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexGenxOES = (GLEEPFNGLTEXGENXOESPROC) __GLeeGetProcAddress("glTexGenxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexGenxvOES = (GLEEPFNGLTEXGENXVOESPROC) __GLeeGetProcAddress("glTexGenxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexParameterxOES = (GLEEPFNGLTEXPARAMETERXOESPROC) __GLeeGetProcAddress("glTexParameterxOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTexParameterxvOES = (GLEEPFNGLTEXPARAMETERXVOESPROC) __GLeeGetProcAddress("glTexParameterxvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glTranslatexOES = (GLEEPFNGLTRANSLATEXOESPROC) __GLeeGetProcAddress("glTranslatexOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex2xOES = (GLEEPFNGLVERTEX2XOESPROC) __GLeeGetProcAddress("glVertex2xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex3xOES = (GLEEPFNGLVERTEX3XOESPROC) __GLeeGetProcAddress("glVertex3xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex4xOES = (GLEEPFNGLVERTEX4XOESPROC) __GLeeGetProcAddress("glVertex4xOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex2xvOES = (GLEEPFNGLVERTEX2XVOESPROC) __GLeeGetProcAddress("glVertex2xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex3xvOES = (GLEEPFNGLVERTEX3XVOESPROC) __GLeeGetProcAddress("glVertex3xvOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glVertex4xvOES = (GLEEPFNGLVERTEX4XVOESPROC) __GLeeGetProcAddress("glVertex4xvOES"))!=0) nLinked++; +#endif + if (nLinked==104) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_OES_single_precision(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_OES_single_precision + if ((GLeeFuncPtr_glDepthRangefOES = (GLEEPFNGLDEPTHRANGEFOESPROC) __GLeeGetProcAddress("glDepthRangefOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glFrustumfOES = (GLEEPFNGLFRUSTUMFOESPROC) __GLeeGetProcAddress("glFrustumfOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glOrthofOES = (GLEEPFNGLORTHOFOESPROC) __GLeeGetProcAddress("glOrthofOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClipPlanefOES = (GLEEPFNGLCLIPPLANEFOESPROC) __GLeeGetProcAddress("glClipPlanefOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glClearDepthfOES = (GLEEPFNGLCLEARDEPTHFOESPROC) __GLeeGetProcAddress("glClearDepthfOES"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetClipPlanefOES = (GLEEPFNGLGETCLIPPLANEFOESPROC) __GLeeGetProcAddress("glGetClipPlanefOES"))!=0) nLinked++; +#endif + if (nLinked==6) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_OES_compressed_paletted_texture(void) {return GLEE_LINK_COMPLETE;} + GLuint __GLeeLink_GL_OES_read_format(void) {return GLEE_LINK_COMPLETE;} +GLuint __GLeeLink_GL_OES_query_matrix(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_OES_query_matrix + if ((GLeeFuncPtr_glQueryMatrixxOES = (GLEEPFNGLQUERYMATRIXXOESPROC) __GLeeGetProcAddress("glQueryMatrixxOES"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + GLuint __GLeeLink_GL_EXT_depth_bounds_test(void) { GLint nLinked=0; @@ -18622,6 +20640,20 @@ GLuint __GLeeLink_GL_AMD_name_gen_delete(void) return GLEE_LINK_PARTIAL; } +GLuint __GLeeLink_GL_AMD_debug_output(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_AMD_debug_output + if ((GLeeFuncPtr_glDebugMessageEnableAMD = (GLEEPFNGLDEBUGMESSAGEENABLEAMDPROC) __GLeeGetProcAddress("glDebugMessageEnableAMD"))!=0) nLinked++; + if ((GLeeFuncPtr_glDebugMessageInsertAMD = (GLEEPFNGLDEBUGMESSAGEINSERTAMDPROC) __GLeeGetProcAddress("glDebugMessageInsertAMD"))!=0) nLinked++; + if ((GLeeFuncPtr_glDebugMessageCallbackAMD = (GLEEPFNGLDEBUGMESSAGECALLBACKAMDPROC) __GLeeGetProcAddress("glDebugMessageCallbackAMD"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetDebugMessageLogAMD = (GLEEPFNGLGETDEBUGMESSAGELOGAMDPROC) __GLeeGetProcAddress("glGetDebugMessageLogAMD"))!=0) nLinked++; +#endif + if (nLinked==4) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + GLuint __GLeeLink_GL_AMD_transform_feedback3_lines_triangles(void) {return GLEE_LINK_COMPLETE;} GLuint __GLeeLink_GL_AMD_depth_clamp_separate(void) {return GLEE_LINK_COMPLETE;} @@ -18682,6 +20714,167 @@ GLuint __GLeeLink_GL_AMD_multi_draw_indirect(void) GLuint __GLeeLink_GL_EXT_framebuffer_multisample_blit_scaled(void) {return GLEE_LINK_COMPLETE;} +GLuint __GLeeLink_GL_NV_path_rendering(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_path_rendering + if ((GLeeFuncPtr_glGenPathsNV = (GLEEPFNGLGENPATHSNVPROC) __GLeeGetProcAddress("glGenPathsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glDeletePathsNV = (GLEEPFNGLDELETEPATHSNVPROC) __GLeeGetProcAddress("glDeletePathsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsPathNV = (GLEEPFNGLISPATHNVPROC) __GLeeGetProcAddress("glIsPathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathCommandsNV = (GLEEPFNGLPATHCOMMANDSNVPROC) __GLeeGetProcAddress("glPathCommandsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathCoordsNV = (GLEEPFNGLPATHCOORDSNVPROC) __GLeeGetProcAddress("glPathCoordsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathSubCommandsNV = (GLEEPFNGLPATHSUBCOMMANDSNVPROC) __GLeeGetProcAddress("glPathSubCommandsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathSubCoordsNV = (GLEEPFNGLPATHSUBCOORDSNVPROC) __GLeeGetProcAddress("glPathSubCoordsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathStringNV = (GLEEPFNGLPATHSTRINGNVPROC) __GLeeGetProcAddress("glPathStringNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathGlyphsNV = (GLEEPFNGLPATHGLYPHSNVPROC) __GLeeGetProcAddress("glPathGlyphsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathGlyphRangeNV = (GLEEPFNGLPATHGLYPHRANGENVPROC) __GLeeGetProcAddress("glPathGlyphRangeNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glWeightPathsNV = (GLEEPFNGLWEIGHTPATHSNVPROC) __GLeeGetProcAddress("glWeightPathsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCopyPathNV = (GLEEPFNGLCOPYPATHNVPROC) __GLeeGetProcAddress("glCopyPathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glInterpolatePathsNV = (GLEEPFNGLINTERPOLATEPATHSNVPROC) __GLeeGetProcAddress("glInterpolatePathsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glTransformPathNV = (GLEEPFNGLTRANSFORMPATHNVPROC) __GLeeGetProcAddress("glTransformPathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathParameterivNV = (GLEEPFNGLPATHPARAMETERIVNVPROC) __GLeeGetProcAddress("glPathParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathParameteriNV = (GLEEPFNGLPATHPARAMETERINVPROC) __GLeeGetProcAddress("glPathParameteriNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathParameterfvNV = (GLEEPFNGLPATHPARAMETERFVNVPROC) __GLeeGetProcAddress("glPathParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathParameterfNV = (GLEEPFNGLPATHPARAMETERFNVPROC) __GLeeGetProcAddress("glPathParameterfNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathDashArrayNV = (GLEEPFNGLPATHDASHARRAYNVPROC) __GLeeGetProcAddress("glPathDashArrayNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathStencilFuncNV = (GLEEPFNGLPATHSTENCILFUNCNVPROC) __GLeeGetProcAddress("glPathStencilFuncNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathStencilDepthOffsetNV = (GLEEPFNGLPATHSTENCILDEPTHOFFSETNVPROC) __GLeeGetProcAddress("glPathStencilDepthOffsetNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilFillPathNV = (GLEEPFNGLSTENCILFILLPATHNVPROC) __GLeeGetProcAddress("glStencilFillPathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilStrokePathNV = (GLEEPFNGLSTENCILSTROKEPATHNVPROC) __GLeeGetProcAddress("glStencilStrokePathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilFillPathInstancedNV = (GLEEPFNGLSTENCILFILLPATHINSTANCEDNVPROC) __GLeeGetProcAddress("glStencilFillPathInstancedNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glStencilStrokePathInstancedNV = (GLEEPFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) __GLeeGetProcAddress("glStencilStrokePathInstancedNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathCoverDepthFuncNV = (GLEEPFNGLPATHCOVERDEPTHFUNCNVPROC) __GLeeGetProcAddress("glPathCoverDepthFuncNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathColorGenNV = (GLEEPFNGLPATHCOLORGENNVPROC) __GLeeGetProcAddress("glPathColorGenNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathTexGenNV = (GLEEPFNGLPATHTEXGENNVPROC) __GLeeGetProcAddress("glPathTexGenNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPathFogGenNV = (GLEEPFNGLPATHFOGGENNVPROC) __GLeeGetProcAddress("glPathFogGenNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCoverFillPathNV = (GLEEPFNGLCOVERFILLPATHNVPROC) __GLeeGetProcAddress("glCoverFillPathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCoverStrokePathNV = (GLEEPFNGLCOVERSTROKEPATHNVPROC) __GLeeGetProcAddress("glCoverStrokePathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCoverFillPathInstancedNV = (GLEEPFNGLCOVERFILLPATHINSTANCEDNVPROC) __GLeeGetProcAddress("glCoverFillPathInstancedNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glCoverStrokePathInstancedNV = (GLEEPFNGLCOVERSTROKEPATHINSTANCEDNVPROC) __GLeeGetProcAddress("glCoverStrokePathInstancedNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathParameterivNV = (GLEEPFNGLGETPATHPARAMETERIVNVPROC) __GLeeGetProcAddress("glGetPathParameterivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathParameterfvNV = (GLEEPFNGLGETPATHPARAMETERFVNVPROC) __GLeeGetProcAddress("glGetPathParameterfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathCommandsNV = (GLEEPFNGLGETPATHCOMMANDSNVPROC) __GLeeGetProcAddress("glGetPathCommandsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathCoordsNV = (GLEEPFNGLGETPATHCOORDSNVPROC) __GLeeGetProcAddress("glGetPathCoordsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathDashArrayNV = (GLEEPFNGLGETPATHDASHARRAYNVPROC) __GLeeGetProcAddress("glGetPathDashArrayNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathMetricsNV = (GLEEPFNGLGETPATHMETRICSNVPROC) __GLeeGetProcAddress("glGetPathMetricsNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathMetricRangeNV = (GLEEPFNGLGETPATHMETRICRANGENVPROC) __GLeeGetProcAddress("glGetPathMetricRangeNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathSpacingNV = (GLEEPFNGLGETPATHSPACINGNVPROC) __GLeeGetProcAddress("glGetPathSpacingNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathColorGenivNV = (GLEEPFNGLGETPATHCOLORGENIVNVPROC) __GLeeGetProcAddress("glGetPathColorGenivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathColorGenfvNV = (GLEEPFNGLGETPATHCOLORGENFVNVPROC) __GLeeGetProcAddress("glGetPathColorGenfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathTexGenivNV = (GLEEPFNGLGETPATHTEXGENIVNVPROC) __GLeeGetProcAddress("glGetPathTexGenivNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathTexGenfvNV = (GLEEPFNGLGETPATHTEXGENFVNVPROC) __GLeeGetProcAddress("glGetPathTexGenfvNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsPointInFillPathNV = (GLEEPFNGLISPOINTINFILLPATHNVPROC) __GLeeGetProcAddress("glIsPointInFillPathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsPointInStrokePathNV = (GLEEPFNGLISPOINTINSTROKEPATHNVPROC) __GLeeGetProcAddress("glIsPointInStrokePathNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetPathLengthNV = (GLEEPFNGLGETPATHLENGTHNVPROC) __GLeeGetProcAddress("glGetPathLengthNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glPointAlongPathNV = (GLEEPFNGLPOINTALONGPATHNVPROC) __GLeeGetProcAddress("glPointAlongPathNV"))!=0) nLinked++; +#endif + if (nLinked==49) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_AMD_pinned_memory(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_AMD_stencil_operation_extended(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_AMD_stencil_operation_extended + if ((GLeeFuncPtr_glStencilOpValueAMD = (GLEEPFNGLSTENCILOPVALUEAMDPROC) __GLeeGetProcAddress("glStencilOpValueAMD"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_AMD_vertex_shader_viewport_index(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_AMD_vertex_shader_layer(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_bindless_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_bindless_texture + if ((GLeeFuncPtr_glGetTextureHandleNV = (GLEEPFNGLGETTEXTUREHANDLENVPROC) __GLeeGetProcAddress("glGetTextureHandleNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetTextureSamplerHandleNV = (GLEEPFNGLGETTEXTURESAMPLERHANDLENVPROC) __GLeeGetProcAddress("glGetTextureSamplerHandleNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMakeTextureHandleResidentNV = (GLEEPFNGLMAKETEXTUREHANDLERESIDENTNVPROC) __GLeeGetProcAddress("glMakeTextureHandleResidentNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMakeTextureHandleNonResidentNV = (GLEEPFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) __GLeeGetProcAddress("glMakeTextureHandleNonResidentNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glGetImageHandleNV = (GLEEPFNGLGETIMAGEHANDLENVPROC) __GLeeGetProcAddress("glGetImageHandleNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMakeImageHandleResidentNV = (GLEEPFNGLMAKEIMAGEHANDLERESIDENTNVPROC) __GLeeGetProcAddress("glMakeImageHandleResidentNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glMakeImageHandleNonResidentNV = (GLEEPFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) __GLeeGetProcAddress("glMakeImageHandleNonResidentNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformHandleui64NV = (GLEEPFNGLUNIFORMHANDLEUI64NVPROC) __GLeeGetProcAddress("glUniformHandleui64NV"))!=0) nLinked++; + if ((GLeeFuncPtr_glUniformHandleui64vNV = (GLEEPFNGLUNIFORMHANDLEUI64VNVPROC) __GLeeGetProcAddress("glUniformHandleui64vNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformHandleui64NV = (GLEEPFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) __GLeeGetProcAddress("glProgramUniformHandleui64NV"))!=0) nLinked++; + if ((GLeeFuncPtr_glProgramUniformHandleui64vNV = (GLEEPFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) __GLeeGetProcAddress("glProgramUniformHandleui64vNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsTextureHandleResidentNV = (GLEEPFNGLISTEXTUREHANDLERESIDENTNVPROC) __GLeeGetProcAddress("glIsTextureHandleResidentNV"))!=0) nLinked++; + if ((GLeeFuncPtr_glIsImageHandleResidentNV = (GLEEPFNGLISIMAGEHANDLERESIDENTNVPROC) __GLeeGetProcAddress("glIsImageHandleResidentNV"))!=0) nLinked++; +#endif + if (nLinked==13) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_shader_atomic_float(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_AMD_query_buffer_object(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_compute_program5(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_shader_storage_buffer_object(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_shader_atomic_counters(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NV_deep_texture3D(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_NVX_conditional_render(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NVX_conditional_render + if ((GLeeFuncPtr_glBeginConditionalRenderNVX = (GLEEPFNGLBEGINCONDITIONALRENDERNVXPROC) __GLeeGetProcAddress("glBeginConditionalRenderNVX"))!=0) nLinked++; + if ((GLeeFuncPtr_glEndConditionalRenderNVX = (GLEEPFNGLENDCONDITIONALRENDERNVXPROC) __GLeeGetProcAddress("glEndConditionalRenderNVX"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_AMD_sparse_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_AMD_sparse_texture + if ((GLeeFuncPtr_glTexStorageSparseAMD = (GLEEPFNGLTEXSTORAGESPARSEAMDPROC) __GLeeGetProcAddress("glTexStorageSparseAMD"))!=0) nLinked++; + if ((GLeeFuncPtr_glTextureStorageSparseAMD = (GLEEPFNGLTEXTURESTORAGESPARSEAMDPROC) __GLeeGetProcAddress("glTextureStorageSparseAMD"))!=0) nLinked++; +#endif + if (nLinked==2) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_AMD_shader_trinary_minmax(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GL_INTEL_map_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_INTEL_map_texture + if ((GLeeFuncPtr_glSyncTextureINTEL = (GLEEPFNGLSYNCTEXTUREINTELPROC) __GLeeGetProcAddress("glSyncTextureINTEL"))!=0) nLinked++; + if ((GLeeFuncPtr_glUnmapTexture2DINTEL = (GLEEPFNGLUNMAPTEXTURE2DINTELPROC) __GLeeGetProcAddress("glUnmapTexture2DINTEL"))!=0) nLinked++; + if ((GLeeFuncPtr_glMapTexture2DINTEL = (GLEEPFNGLMAPTEXTURE2DINTELPROC) __GLeeGetProcAddress("glMapTexture2DINTEL"))!=0) nLinked++; +#endif + if (nLinked==3) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + +GLuint __GLeeLink_GL_NV_draw_texture(void) +{ + GLint nLinked=0; +#ifdef __GLEE_GL_NV_draw_texture + if ((GLeeFuncPtr_glDrawTextureNV = (GLEEPFNGLDRAWTEXTURENVPROC) __GLeeGetProcAddress("glDrawTextureNV"))!=0) nLinked++; +#endif + if (nLinked==1) return GLEE_LINK_COMPLETE; + if (nLinked==0) return GLEE_LINK_FAIL; + return GLEE_LINK_PARTIAL; +} + GLuint __GLeeLink_GL_SGIX_texture_select(void) {return GLEE_LINK_COMPLETE;} GLuint __GLeeLink_GL_INGR_blend_func_separate(void) @@ -18708,66 +20901,7 @@ GLuint __GLeeLink_GL_SGIX_igloo_interface(void) return GLEE_LINK_PARTIAL; } -GLuint __GLeeLink_GL_OES_compressed_paletted_texture(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_OES_fixed_point(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_OES_single_precision(void) -{ - GLint nLinked=0; -#ifdef __GLEE_GL_OES_single_precision - if ((GLeeFuncPtr_glClearDepthfOES = (GLEEPFNGLCLEARDEPTHFOESPROC) __GLeeGetProcAddress("glClearDepthfOES"))!=0) nLinked++; -#endif - if (nLinked==1) return GLEE_LINK_COMPLETE; - if (nLinked==0) return GLEE_LINK_FAIL; - return GLEE_LINK_PARTIAL; -} - -GLuint __GLeeLink_GL_OES_query_matrix(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_OES_byte_coordinates(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_NV_gpu_program4(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_NV_path_rendering(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_AMD_vertex_shader_tessellator(void) -{ - GLint nLinked=0; -#ifdef __GLEE_GL_AMD_vertex_shader_tessellator - if ((GLeeFuncPtr_glTessellationModeAMD = (GLEEPFNGLTESSELLATIONMODEAMDPROC) __GLeeGetProcAddress("glTessellationModeAMD"))!=0) nLinked++; -#endif - if (nLinked==1) return GLEE_LINK_COMPLETE; - if (nLinked==0) return GLEE_LINK_FAIL; - return GLEE_LINK_PARTIAL; -} - -GLuint __GLeeLink_GL_EXT_fragment_lighting(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_EXT_texture_compression_dxt1(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_EXT_scene_marker(void) -{ - GLint nLinked=0; -#ifdef __GLEE_GL_EXT_scene_marker - if ((GLeeFuncPtr_glEndSceneEXT = (GLEEPFNGLENDSCENEEXTPROC) __GLeeGetProcAddress("glEndSceneEXT"))!=0) nLinked++; -#endif - if (nLinked==1) return GLEE_LINK_COMPLETE; - if (nLinked==0) return GLEE_LINK_FAIL; - return GLEE_LINK_PARTIAL; -} - -GLuint __GLeeLink_GL_EXT_geometry_shader4(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_EXT_texture_env(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_SGIX_texture_range(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_SGIX_pixel_texture_bits(void) {return GLEE_LINK_COMPLETE;} - -GLuint __GLeeLink_GL_IBM_static_data(void) {return GLEE_LINK_COMPLETE;} - -GLEE_LINK_FUNCTION __GLeeGLLoadFunction[430]; +GLEE_LINK_FUNCTION __GLeeGLLoadFunction[463]; void initGLLoadFunctions(void) { @@ -18785,422 +20919,455 @@ void initGLLoadFunctions(void) __GLeeGLLoadFunction[11]=__GLeeLink_GL_VERSION_4_0; __GLeeGLLoadFunction[12]=__GLeeLink_GL_VERSION_4_1; __GLeeGLLoadFunction[13]=__GLeeLink_GL_VERSION_4_2; - __GLeeGLLoadFunction[14]=__GLeeLink_GL_ARB_multitexture; - __GLeeGLLoadFunction[15]=__GLeeLink_GL_ARB_transpose_matrix; - __GLeeGLLoadFunction[16]=__GLeeLink_GL_ARB_multisample; - __GLeeGLLoadFunction[17]=__GLeeLink_GL_ARB_texture_env_add; - __GLeeGLLoadFunction[18]=__GLeeLink_GL_ARB_texture_cube_map; - __GLeeGLLoadFunction[19]=__GLeeLink_GL_ARB_texture_compression; - __GLeeGLLoadFunction[20]=__GLeeLink_GL_ARB_texture_border_clamp; - __GLeeGLLoadFunction[21]=__GLeeLink_GL_ARB_point_parameters; - __GLeeGLLoadFunction[22]=__GLeeLink_GL_ARB_vertex_blend; - __GLeeGLLoadFunction[23]=__GLeeLink_GL_ARB_matrix_palette; - __GLeeGLLoadFunction[24]=__GLeeLink_GL_ARB_texture_env_combine; - __GLeeGLLoadFunction[25]=__GLeeLink_GL_ARB_texture_env_crossbar; - __GLeeGLLoadFunction[26]=__GLeeLink_GL_ARB_texture_env_dot3; - __GLeeGLLoadFunction[27]=__GLeeLink_GL_ARB_texture_mirrored_repeat; - __GLeeGLLoadFunction[28]=__GLeeLink_GL_ARB_depth_texture; - __GLeeGLLoadFunction[29]=__GLeeLink_GL_ARB_shadow; - __GLeeGLLoadFunction[30]=__GLeeLink_GL_ARB_shadow_ambient; - __GLeeGLLoadFunction[31]=__GLeeLink_GL_ARB_window_pos; - __GLeeGLLoadFunction[32]=__GLeeLink_GL_ARB_vertex_program; - __GLeeGLLoadFunction[33]=__GLeeLink_GL_ARB_fragment_program; - __GLeeGLLoadFunction[34]=__GLeeLink_GL_ARB_vertex_buffer_object; - __GLeeGLLoadFunction[35]=__GLeeLink_GL_ARB_occlusion_query; - __GLeeGLLoadFunction[36]=__GLeeLink_GL_ARB_shader_objects; - __GLeeGLLoadFunction[37]=__GLeeLink_GL_ARB_vertex_shader; - __GLeeGLLoadFunction[38]=__GLeeLink_GL_ARB_fragment_shader; - __GLeeGLLoadFunction[39]=__GLeeLink_GL_ARB_shading_language_100; - __GLeeGLLoadFunction[40]=__GLeeLink_GL_ARB_texture_non_power_of_two; - __GLeeGLLoadFunction[41]=__GLeeLink_GL_ARB_point_sprite; - __GLeeGLLoadFunction[42]=__GLeeLink_GL_ARB_fragment_program_shadow; - __GLeeGLLoadFunction[43]=__GLeeLink_GL_ARB_draw_buffers; - __GLeeGLLoadFunction[44]=__GLeeLink_GL_ARB_texture_rectangle; - __GLeeGLLoadFunction[45]=__GLeeLink_GL_ARB_color_buffer_float; - __GLeeGLLoadFunction[46]=__GLeeLink_GL_ARB_half_float_pixel; - __GLeeGLLoadFunction[47]=__GLeeLink_GL_ARB_texture_float; - __GLeeGLLoadFunction[48]=__GLeeLink_GL_ARB_pixel_buffer_object; - __GLeeGLLoadFunction[49]=__GLeeLink_GL_ARB_depth_buffer_float; - __GLeeGLLoadFunction[50]=__GLeeLink_GL_ARB_draw_instanced; - __GLeeGLLoadFunction[51]=__GLeeLink_GL_ARB_framebuffer_object; - __GLeeGLLoadFunction[52]=__GLeeLink_GL_ARB_framebuffer_sRGB; - __GLeeGLLoadFunction[53]=__GLeeLink_GL_ARB_geometry_shader4; - __GLeeGLLoadFunction[54]=__GLeeLink_GL_ARB_half_float_vertex; - __GLeeGLLoadFunction[55]=__GLeeLink_GL_ARB_instanced_arrays; - __GLeeGLLoadFunction[56]=__GLeeLink_GL_ARB_map_buffer_range; - __GLeeGLLoadFunction[57]=__GLeeLink_GL_ARB_texture_buffer_object; - __GLeeGLLoadFunction[58]=__GLeeLink_GL_ARB_texture_compression_rgtc; - __GLeeGLLoadFunction[59]=__GLeeLink_GL_ARB_texture_rg; - __GLeeGLLoadFunction[60]=__GLeeLink_GL_ARB_vertex_array_object; - __GLeeGLLoadFunction[61]=__GLeeLink_GL_ARB_uniform_buffer_object; - __GLeeGLLoadFunction[62]=__GLeeLink_GL_ARB_compatibility; - __GLeeGLLoadFunction[63]=__GLeeLink_GL_ARB_copy_buffer; - __GLeeGLLoadFunction[64]=__GLeeLink_GL_ARB_shader_texture_lod; - __GLeeGLLoadFunction[65]=__GLeeLink_GL_ARB_depth_clamp; - __GLeeGLLoadFunction[66]=__GLeeLink_GL_ARB_draw_elements_base_vertex; - __GLeeGLLoadFunction[67]=__GLeeLink_GL_ARB_fragment_coord_conventions; - __GLeeGLLoadFunction[68]=__GLeeLink_GL_ARB_provoking_vertex; - __GLeeGLLoadFunction[69]=__GLeeLink_GL_ARB_seamless_cube_map; - __GLeeGLLoadFunction[70]=__GLeeLink_GL_ARB_sync; - __GLeeGLLoadFunction[71]=__GLeeLink_GL_ARB_texture_multisample; - __GLeeGLLoadFunction[72]=__GLeeLink_GL_ARB_vertex_array_bgra; - __GLeeGLLoadFunction[73]=__GLeeLink_GL_ARB_draw_buffers_blend; - __GLeeGLLoadFunction[74]=__GLeeLink_GL_ARB_sample_shading; - __GLeeGLLoadFunction[75]=__GLeeLink_GL_ARB_texture_cube_map_array; - __GLeeGLLoadFunction[76]=__GLeeLink_GL_ARB_texture_gather; - __GLeeGLLoadFunction[77]=__GLeeLink_GL_ARB_texture_query_lod; - __GLeeGLLoadFunction[78]=__GLeeLink_GL_ARB_shading_language_include; - __GLeeGLLoadFunction[79]=__GLeeLink_GL_ARB_texture_compression_bptc; - __GLeeGLLoadFunction[80]=__GLeeLink_GL_ARB_blend_func_extended; - __GLeeGLLoadFunction[81]=__GLeeLink_GL_ARB_explicit_attrib_location; - __GLeeGLLoadFunction[82]=__GLeeLink_GL_ARB_occlusion_query2; - __GLeeGLLoadFunction[83]=__GLeeLink_GL_ARB_sampler_objects; - __GLeeGLLoadFunction[84]=__GLeeLink_GL_ARB_shader_bit_encoding; - __GLeeGLLoadFunction[85]=__GLeeLink_GL_ARB_texture_rgb10_a2ui; - __GLeeGLLoadFunction[86]=__GLeeLink_GL_ARB_texture_swizzle; - __GLeeGLLoadFunction[87]=__GLeeLink_GL_ARB_timer_query; - __GLeeGLLoadFunction[88]=__GLeeLink_GL_ARB_vertex_type_2_10_10_10_rev; - __GLeeGLLoadFunction[89]=__GLeeLink_GL_ARB_draw_indirect; - __GLeeGLLoadFunction[90]=__GLeeLink_GL_ARB_gpu_shader5; - __GLeeGLLoadFunction[91]=__GLeeLink_GL_ARB_gpu_shader_fp64; - __GLeeGLLoadFunction[92]=__GLeeLink_GL_ARB_shader_subroutine; - __GLeeGLLoadFunction[93]=__GLeeLink_GL_ARB_tessellation_shader; - __GLeeGLLoadFunction[94]=__GLeeLink_GL_ARB_texture_buffer_object_rgb32; - __GLeeGLLoadFunction[95]=__GLeeLink_GL_ARB_transform_feedback2; - __GLeeGLLoadFunction[96]=__GLeeLink_GL_ARB_transform_feedback3; - __GLeeGLLoadFunction[97]=__GLeeLink_GL_ARB_ES2_compatibility; - __GLeeGLLoadFunction[98]=__GLeeLink_GL_ARB_get_program_binary; - __GLeeGLLoadFunction[99]=__GLeeLink_GL_ARB_separate_shader_objects; - __GLeeGLLoadFunction[100]=__GLeeLink_GL_ARB_shader_precision; - __GLeeGLLoadFunction[101]=__GLeeLink_GL_ARB_vertex_attrib_64bit; - __GLeeGLLoadFunction[102]=__GLeeLink_GL_ARB_viewport_array; - __GLeeGLLoadFunction[103]=__GLeeLink_GL_ARB_cl_event; - __GLeeGLLoadFunction[104]=__GLeeLink_GL_ARB_robustness; - __GLeeGLLoadFunction[105]=__GLeeLink_GL_ARB_shader_stencil_export; - __GLeeGLLoadFunction[106]=__GLeeLink_GL_ARB_base_instance; - __GLeeGLLoadFunction[107]=__GLeeLink_GL_ARB_shading_language_420pack; - __GLeeGLLoadFunction[108]=__GLeeLink_GL_ARB_transform_feedback_instanced; - __GLeeGLLoadFunction[109]=__GLeeLink_GL_ARB_compressed_texture_pixel_storage; - __GLeeGLLoadFunction[110]=__GLeeLink_GL_ARB_conservative_depth; - __GLeeGLLoadFunction[111]=__GLeeLink_GL_ARB_internalformat_query; - __GLeeGLLoadFunction[112]=__GLeeLink_GL_ARB_map_buffer_alignment; - __GLeeGLLoadFunction[113]=__GLeeLink_GL_ARB_shader_atomic_counters; - __GLeeGLLoadFunction[114]=__GLeeLink_GL_ARB_shader_image_load_store; - __GLeeGLLoadFunction[115]=__GLeeLink_GL_ARB_shading_language_packing; - __GLeeGLLoadFunction[116]=__GLeeLink_GL_ARB_texture_storage; - __GLeeGLLoadFunction[117]=__GLeeLink_GL_EXT_abgr; - __GLeeGLLoadFunction[118]=__GLeeLink_GL_EXT_blend_color; - __GLeeGLLoadFunction[119]=__GLeeLink_GL_EXT_polygon_offset; - __GLeeGLLoadFunction[120]=__GLeeLink_GL_EXT_texture; - __GLeeGLLoadFunction[121]=__GLeeLink_GL_EXT_texture3D; - __GLeeGLLoadFunction[122]=__GLeeLink_GL_SGIS_texture_filter4; - __GLeeGLLoadFunction[123]=__GLeeLink_GL_EXT_subtexture; - __GLeeGLLoadFunction[124]=__GLeeLink_GL_EXT_copy_texture; - __GLeeGLLoadFunction[125]=__GLeeLink_GL_EXT_histogram; - __GLeeGLLoadFunction[126]=__GLeeLink_GL_EXT_convolution; - __GLeeGLLoadFunction[127]=__GLeeLink_GL_SGI_color_matrix; - __GLeeGLLoadFunction[128]=__GLeeLink_GL_SGI_color_table; - __GLeeGLLoadFunction[129]=__GLeeLink_GL_SGIS_pixel_texture; - __GLeeGLLoadFunction[130]=__GLeeLink_GL_SGIX_pixel_texture; - __GLeeGLLoadFunction[131]=__GLeeLink_GL_SGIS_texture4D; - __GLeeGLLoadFunction[132]=__GLeeLink_GL_SGI_texture_color_table; - __GLeeGLLoadFunction[133]=__GLeeLink_GL_EXT_cmyka; - __GLeeGLLoadFunction[134]=__GLeeLink_GL_EXT_texture_object; - __GLeeGLLoadFunction[135]=__GLeeLink_GL_SGIS_detail_texture; - __GLeeGLLoadFunction[136]=__GLeeLink_GL_SGIS_sharpen_texture; - __GLeeGLLoadFunction[137]=__GLeeLink_GL_EXT_packed_pixels; - __GLeeGLLoadFunction[138]=__GLeeLink_GL_SGIS_texture_lod; - __GLeeGLLoadFunction[139]=__GLeeLink_GL_SGIS_multisample; - __GLeeGLLoadFunction[140]=__GLeeLink_GL_EXT_rescale_normal; - __GLeeGLLoadFunction[141]=__GLeeLink_GL_EXT_vertex_array; - __GLeeGLLoadFunction[142]=__GLeeLink_GL_EXT_misc_attribute; - __GLeeGLLoadFunction[143]=__GLeeLink_GL_SGIS_generate_mipmap; - __GLeeGLLoadFunction[144]=__GLeeLink_GL_SGIX_clipmap; - __GLeeGLLoadFunction[145]=__GLeeLink_GL_SGIX_shadow; - __GLeeGLLoadFunction[146]=__GLeeLink_GL_SGIS_texture_edge_clamp; - __GLeeGLLoadFunction[147]=__GLeeLink_GL_SGIS_texture_border_clamp; - __GLeeGLLoadFunction[148]=__GLeeLink_GL_EXT_blend_minmax; - __GLeeGLLoadFunction[149]=__GLeeLink_GL_EXT_blend_subtract; - __GLeeGLLoadFunction[150]=__GLeeLink_GL_EXT_blend_logic_op; - __GLeeGLLoadFunction[151]=__GLeeLink_GL_SGIX_interlace; - __GLeeGLLoadFunction[152]=__GLeeLink_GL_SGIX_pixel_tiles; - __GLeeGLLoadFunction[153]=__GLeeLink_GL_SGIS_texture_select; - __GLeeGLLoadFunction[154]=__GLeeLink_GL_SGIX_sprite; - __GLeeGLLoadFunction[155]=__GLeeLink_GL_SGIX_texture_multi_buffer; - __GLeeGLLoadFunction[156]=__GLeeLink_GL_EXT_point_parameters; - __GLeeGLLoadFunction[157]=__GLeeLink_GL_SGIS_point_parameters; - __GLeeGLLoadFunction[158]=__GLeeLink_GL_SGIX_instruments; - __GLeeGLLoadFunction[159]=__GLeeLink_GL_SGIX_texture_scale_bias; - __GLeeGLLoadFunction[160]=__GLeeLink_GL_SGIX_framezoom; - __GLeeGLLoadFunction[161]=__GLeeLink_GL_SGIX_tag_sample_buffer; - __GLeeGLLoadFunction[162]=__GLeeLink_GL_FfdMaskSGIX; - __GLeeGLLoadFunction[163]=__GLeeLink_GL_SGIX_polynomial_ffd; - __GLeeGLLoadFunction[164]=__GLeeLink_GL_SGIX_reference_plane; - __GLeeGLLoadFunction[165]=__GLeeLink_GL_SGIX_flush_raster; - __GLeeGLLoadFunction[166]=__GLeeLink_GL_SGIX_depth_texture; - __GLeeGLLoadFunction[167]=__GLeeLink_GL_SGIS_fog_function; - __GLeeGLLoadFunction[168]=__GLeeLink_GL_SGIX_fog_offset; - __GLeeGLLoadFunction[169]=__GLeeLink_GL_HP_image_transform; - __GLeeGLLoadFunction[170]=__GLeeLink_GL_HP_convolution_border_modes; - __GLeeGLLoadFunction[171]=__GLeeLink_GL_INGR_palette_buffer; - __GLeeGLLoadFunction[172]=__GLeeLink_GL_SGIX_texture_add_env; - __GLeeGLLoadFunction[173]=__GLeeLink_GL_EXT_color_subtable; - __GLeeGLLoadFunction[174]=__GLeeLink_GL_PGI_vertex_hints; - __GLeeGLLoadFunction[175]=__GLeeLink_GL_PGI_misc_hints; - __GLeeGLLoadFunction[176]=__GLeeLink_GL_EXT_paletted_texture; - __GLeeGLLoadFunction[177]=__GLeeLink_GL_EXT_clip_volume_hint; - __GLeeGLLoadFunction[178]=__GLeeLink_GL_SGIX_list_priority; - __GLeeGLLoadFunction[179]=__GLeeLink_GL_SGIX_ir_instrument1; - __GLeeGLLoadFunction[180]=__GLeeLink_GL_SGIX_calligraphic_fragment; - __GLeeGLLoadFunction[181]=__GLeeLink_GL_SGIX_texture_lod_bias; - __GLeeGLLoadFunction[182]=__GLeeLink_GL_SGIX_shadow_ambient; - __GLeeGLLoadFunction[183]=__GLeeLink_GL_EXT_index_texture; - __GLeeGLLoadFunction[184]=__GLeeLink_GL_EXT_index_material; - __GLeeGLLoadFunction[185]=__GLeeLink_GL_EXT_index_func; - __GLeeGLLoadFunction[186]=__GLeeLink_GL_EXT_index_array_formats; - __GLeeGLLoadFunction[187]=__GLeeLink_GL_EXT_compiled_vertex_array; - __GLeeGLLoadFunction[188]=__GLeeLink_GL_EXT_cull_vertex; - __GLeeGLLoadFunction[189]=__GLeeLink_GL_SGIX_ycrcb; - __GLeeGLLoadFunction[190]=__GLeeLink_GL_SGIX_fragment_lighting; - __GLeeGLLoadFunction[191]=__GLeeLink_GL_IBM_rasterpos_clip; - __GLeeGLLoadFunction[192]=__GLeeLink_GL_HP_texture_lighting; - __GLeeGLLoadFunction[193]=__GLeeLink_GL_EXT_draw_range_elements; - __GLeeGLLoadFunction[194]=__GLeeLink_GL_WIN_phong_shading; - __GLeeGLLoadFunction[195]=__GLeeLink_GL_WIN_specular_fog; - __GLeeGLLoadFunction[196]=__GLeeLink_GL_EXT_light_texture; - __GLeeGLLoadFunction[197]=__GLeeLink_GL_SGIX_blend_alpha_minmax; - __GLeeGLLoadFunction[198]=__GLeeLink_GL_SGIX_impact_pixel_texture; - __GLeeGLLoadFunction[199]=__GLeeLink_GL_EXT_bgra; - __GLeeGLLoadFunction[200]=__GLeeLink_GL_SGIX_async; - __GLeeGLLoadFunction[201]=__GLeeLink_GL_SGIX_async_pixel; - __GLeeGLLoadFunction[202]=__GLeeLink_GL_SGIX_async_histogram; - __GLeeGLLoadFunction[203]=__GLeeLink_GL_INTEL_texture_scissor; - __GLeeGLLoadFunction[204]=__GLeeLink_GL_INTEL_parallel_arrays; - __GLeeGLLoadFunction[205]=__GLeeLink_GL_HP_occlusion_test; - __GLeeGLLoadFunction[206]=__GLeeLink_GL_EXT_pixel_transform; - __GLeeGLLoadFunction[207]=__GLeeLink_GL_EXT_pixel_transform_color_table; - __GLeeGLLoadFunction[208]=__GLeeLink_GL_EXT_shared_texture_palette; - __GLeeGLLoadFunction[209]=__GLeeLink_GL_EXT_separate_specular_color; - __GLeeGLLoadFunction[210]=__GLeeLink_GL_EXT_secondary_color; - __GLeeGLLoadFunction[211]=__GLeeLink_GL_EXT_texture_perturb_normal; - __GLeeGLLoadFunction[212]=__GLeeLink_GL_EXT_multi_draw_arrays; - __GLeeGLLoadFunction[213]=__GLeeLink_GL_EXT_fog_coord; - __GLeeGLLoadFunction[214]=__GLeeLink_GL_REND_screen_coordinates; - __GLeeGLLoadFunction[215]=__GLeeLink_GL_EXT_coordinate_frame; - __GLeeGLLoadFunction[216]=__GLeeLink_GL_EXT_texture_env_combine; - __GLeeGLLoadFunction[217]=__GLeeLink_GL_APPLE_specular_vector; - __GLeeGLLoadFunction[218]=__GLeeLink_GL_APPLE_transform_hint; - __GLeeGLLoadFunction[219]=__GLeeLink_GL_SGIX_fog_scale; - __GLeeGLLoadFunction[220]=__GLeeLink_GL_SUNX_constant_data; - __GLeeGLLoadFunction[221]=__GLeeLink_GL_SUN_global_alpha; - __GLeeGLLoadFunction[222]=__GLeeLink_GL_SUN_triangle_list; - __GLeeGLLoadFunction[223]=__GLeeLink_GL_SUN_vertex; - __GLeeGLLoadFunction[224]=__GLeeLink_GL_EXT_blend_func_separate; - __GLeeGLLoadFunction[225]=__GLeeLink_GL_INGR_color_clamp; - __GLeeGLLoadFunction[226]=__GLeeLink_GL_INGR_interlace_read; - __GLeeGLLoadFunction[227]=__GLeeLink_GL_EXT_stencil_wrap; - __GLeeGLLoadFunction[228]=__GLeeLink_GL_EXT_422_pixels; - __GLeeGLLoadFunction[229]=__GLeeLink_GL_NV_texgen_reflection; - __GLeeGLLoadFunction[230]=__GLeeLink_GL_EXT_texture_cube_map; - __GLeeGLLoadFunction[231]=__GLeeLink_GL_SUN_convolution_border_modes; - __GLeeGLLoadFunction[232]=__GLeeLink_GL_EXT_texture_env_add; - __GLeeGLLoadFunction[233]=__GLeeLink_GL_EXT_texture_lod_bias; - __GLeeGLLoadFunction[234]=__GLeeLink_GL_EXT_texture_filter_anisotropic; - __GLeeGLLoadFunction[235]=__GLeeLink_GL_EXT_vertex_weighting; - __GLeeGLLoadFunction[236]=__GLeeLink_GL_NV_light_max_exponent; - __GLeeGLLoadFunction[237]=__GLeeLink_GL_NV_vertex_array_range; - __GLeeGLLoadFunction[238]=__GLeeLink_GL_NV_register_combiners; - __GLeeGLLoadFunction[239]=__GLeeLink_GL_NV_fog_distance; - __GLeeGLLoadFunction[240]=__GLeeLink_GL_NV_texgen_emboss; - __GLeeGLLoadFunction[241]=__GLeeLink_GL_NV_blend_square; - __GLeeGLLoadFunction[242]=__GLeeLink_GL_NV_texture_env_combine4; - __GLeeGLLoadFunction[243]=__GLeeLink_GL_MESA_resize_buffers; - __GLeeGLLoadFunction[244]=__GLeeLink_GL_MESA_window_pos; - __GLeeGLLoadFunction[245]=__GLeeLink_GL_EXT_texture_compression_s3tc; - __GLeeGLLoadFunction[246]=__GLeeLink_GL_IBM_cull_vertex; - __GLeeGLLoadFunction[247]=__GLeeLink_GL_IBM_multimode_draw_arrays; - __GLeeGLLoadFunction[248]=__GLeeLink_GL_IBM_vertex_array_lists; - __GLeeGLLoadFunction[249]=__GLeeLink_GL_SGIX_subsample; - __GLeeGLLoadFunction[250]=__GLeeLink_GL_SGIX_ycrcb_subsample; - __GLeeGLLoadFunction[251]=__GLeeLink_GL_SGIX_ycrcba; - __GLeeGLLoadFunction[252]=__GLeeLink_GL_SGI_depth_pass_instrument; - __GLeeGLLoadFunction[253]=__GLeeLink_GL_3DFX_texture_compression_FXT1; - __GLeeGLLoadFunction[254]=__GLeeLink_GL_3DFX_multisample; - __GLeeGLLoadFunction[255]=__GLeeLink_GL_3DFX_tbuffer; - __GLeeGLLoadFunction[256]=__GLeeLink_GL_EXT_multisample; - __GLeeGLLoadFunction[257]=__GLeeLink_GL_SGIX_vertex_preclip; - __GLeeGLLoadFunction[258]=__GLeeLink_GL_SGIX_convolution_accuracy; - __GLeeGLLoadFunction[259]=__GLeeLink_GL_SGIX_resample; - __GLeeGLLoadFunction[260]=__GLeeLink_GL_SGIS_point_line_texgen; - __GLeeGLLoadFunction[261]=__GLeeLink_GL_SGIS_texture_color_mask; - __GLeeGLLoadFunction[262]=__GLeeLink_GL_EXT_texture_env_dot3; - __GLeeGLLoadFunction[263]=__GLeeLink_GL_ATI_texture_mirror_once; - __GLeeGLLoadFunction[264]=__GLeeLink_GL_NV_fence; - __GLeeGLLoadFunction[265]=__GLeeLink_GL_IBM_texture_mirrored_repeat; - __GLeeGLLoadFunction[266]=__GLeeLink_GL_NV_evaluators; - __GLeeGLLoadFunction[267]=__GLeeLink_GL_NV_packed_depth_stencil; - __GLeeGLLoadFunction[268]=__GLeeLink_GL_NV_register_combiners2; - __GLeeGLLoadFunction[269]=__GLeeLink_GL_NV_texture_compression_vtc; - __GLeeGLLoadFunction[270]=__GLeeLink_GL_NV_texture_rectangle; - __GLeeGLLoadFunction[271]=__GLeeLink_GL_NV_texture_shader; - __GLeeGLLoadFunction[272]=__GLeeLink_GL_NV_texture_shader2; - __GLeeGLLoadFunction[273]=__GLeeLink_GL_NV_vertex_array_range2; - __GLeeGLLoadFunction[274]=__GLeeLink_GL_NV_vertex_program; - __GLeeGLLoadFunction[275]=__GLeeLink_GL_SGIX_texture_coordinate_clamp; - __GLeeGLLoadFunction[276]=__GLeeLink_GL_SGIX_scalebias_hint; - __GLeeGLLoadFunction[277]=__GLeeLink_GL_OML_interlace; - __GLeeGLLoadFunction[278]=__GLeeLink_GL_OML_subsample; - __GLeeGLLoadFunction[279]=__GLeeLink_GL_OML_resample; - __GLeeGLLoadFunction[280]=__GLeeLink_GL_NV_copy_depth_to_color; - __GLeeGLLoadFunction[281]=__GLeeLink_GL_ATI_envmap_bumpmap; - __GLeeGLLoadFunction[282]=__GLeeLink_GL_ATI_fragment_shader; - __GLeeGLLoadFunction[283]=__GLeeLink_GL_ATI_pn_triangles; - __GLeeGLLoadFunction[284]=__GLeeLink_GL_ATI_vertex_array_object; - __GLeeGLLoadFunction[285]=__GLeeLink_GL_EXT_vertex_shader; - __GLeeGLLoadFunction[286]=__GLeeLink_GL_ATI_vertex_streams; - __GLeeGLLoadFunction[287]=__GLeeLink_GL_ATI_element_array; - __GLeeGLLoadFunction[288]=__GLeeLink_GL_SUN_mesh_array; - __GLeeGLLoadFunction[289]=__GLeeLink_GL_SUN_slice_accum; - __GLeeGLLoadFunction[290]=__GLeeLink_GL_NV_multisample_filter_hint; - __GLeeGLLoadFunction[291]=__GLeeLink_GL_NV_depth_clamp; - __GLeeGLLoadFunction[292]=__GLeeLink_GL_NV_occlusion_query; - __GLeeGLLoadFunction[293]=__GLeeLink_GL_NV_point_sprite; - __GLeeGLLoadFunction[294]=__GLeeLink_GL_NV_texture_shader3; - __GLeeGLLoadFunction[295]=__GLeeLink_GL_NV_vertex_program1_1; - __GLeeGLLoadFunction[296]=__GLeeLink_GL_EXT_shadow_funcs; - __GLeeGLLoadFunction[297]=__GLeeLink_GL_EXT_stencil_two_side; - __GLeeGLLoadFunction[298]=__GLeeLink_GL_ATI_text_fragment_shader; - __GLeeGLLoadFunction[299]=__GLeeLink_GL_APPLE_client_storage; - __GLeeGLLoadFunction[300]=__GLeeLink_GL_APPLE_element_array; - __GLeeGLLoadFunction[301]=__GLeeLink_GL_APPLE_fence; - __GLeeGLLoadFunction[302]=__GLeeLink_GL_APPLE_vertex_array_object; - __GLeeGLLoadFunction[303]=__GLeeLink_GL_APPLE_vertex_array_range; - __GLeeGLLoadFunction[304]=__GLeeLink_GL_APPLE_ycbcr_422; - __GLeeGLLoadFunction[305]=__GLeeLink_GL_S3_s3tc; - __GLeeGLLoadFunction[306]=__GLeeLink_GL_ATI_draw_buffers; - __GLeeGLLoadFunction[307]=__GLeeLink_GL_ATI_pixel_format_float; - __GLeeGLLoadFunction[308]=__GLeeLink_GL_ATI_texture_env_combine3; - __GLeeGLLoadFunction[309]=__GLeeLink_GL_ATI_texture_float; - __GLeeGLLoadFunction[310]=__GLeeLink_GL_NV_float_buffer; - __GLeeGLLoadFunction[311]=__GLeeLink_GL_NV_fragment_program; - __GLeeGLLoadFunction[312]=__GLeeLink_GL_NV_half_float; - __GLeeGLLoadFunction[313]=__GLeeLink_GL_NV_pixel_data_range; - __GLeeGLLoadFunction[314]=__GLeeLink_GL_NV_primitive_restart; - __GLeeGLLoadFunction[315]=__GLeeLink_GL_NV_texture_expand_normal; - __GLeeGLLoadFunction[316]=__GLeeLink_GL_NV_vertex_program2; - __GLeeGLLoadFunction[317]=__GLeeLink_GL_ATI_map_object_buffer; - __GLeeGLLoadFunction[318]=__GLeeLink_GL_ATI_separate_stencil; - __GLeeGLLoadFunction[319]=__GLeeLink_GL_ATI_vertex_attrib_array_object; - __GLeeGLLoadFunction[320]=__GLeeLink_GL_OES_read_format; - __GLeeGLLoadFunction[321]=__GLeeLink_GL_EXT_depth_bounds_test; - __GLeeGLLoadFunction[322]=__GLeeLink_GL_EXT_texture_mirror_clamp; - __GLeeGLLoadFunction[323]=__GLeeLink_GL_EXT_blend_equation_separate; - __GLeeGLLoadFunction[324]=__GLeeLink_GL_MESA_pack_invert; - __GLeeGLLoadFunction[325]=__GLeeLink_GL_MESA_ycbcr_texture; - __GLeeGLLoadFunction[326]=__GLeeLink_GL_EXT_pixel_buffer_object; - __GLeeGLLoadFunction[327]=__GLeeLink_GL_NV_fragment_program_option; - __GLeeGLLoadFunction[328]=__GLeeLink_GL_NV_fragment_program2; - __GLeeGLLoadFunction[329]=__GLeeLink_GL_NV_vertex_program2_option; - __GLeeGLLoadFunction[330]=__GLeeLink_GL_NV_vertex_program3; - __GLeeGLLoadFunction[331]=__GLeeLink_GL_EXT_framebuffer_object; - __GLeeGLLoadFunction[332]=__GLeeLink_GL_GREMEDY_string_marker; - __GLeeGLLoadFunction[333]=__GLeeLink_GL_EXT_packed_depth_stencil; - __GLeeGLLoadFunction[334]=__GLeeLink_GL_EXT_stencil_clear_tag; - __GLeeGLLoadFunction[335]=__GLeeLink_GL_EXT_texture_sRGB; - __GLeeGLLoadFunction[336]=__GLeeLink_GL_EXT_framebuffer_blit; - __GLeeGLLoadFunction[337]=__GLeeLink_GL_EXT_framebuffer_multisample; - __GLeeGLLoadFunction[338]=__GLeeLink_GL_MESAX_texture_stack; - __GLeeGLLoadFunction[339]=__GLeeLink_GL_EXT_timer_query; - __GLeeGLLoadFunction[340]=__GLeeLink_GL_EXT_gpu_program_parameters; - __GLeeGLLoadFunction[341]=__GLeeLink_GL_APPLE_flush_buffer_range; - __GLeeGLLoadFunction[342]=__GLeeLink_GL_EXT_gpu_shader4; - __GLeeGLLoadFunction[343]=__GLeeLink_GL_EXT_draw_instanced; - __GLeeGLLoadFunction[344]=__GLeeLink_GL_EXT_packed_float; - __GLeeGLLoadFunction[345]=__GLeeLink_GL_EXT_texture_array; - __GLeeGLLoadFunction[346]=__GLeeLink_GL_EXT_texture_buffer_object; - __GLeeGLLoadFunction[347]=__GLeeLink_GL_EXT_texture_compression_latc; - __GLeeGLLoadFunction[348]=__GLeeLink_GL_EXT_texture_compression_rgtc; - __GLeeGLLoadFunction[349]=__GLeeLink_GL_EXT_texture_shared_exponent; - __GLeeGLLoadFunction[350]=__GLeeLink_GL_NV_depth_buffer_float; - __GLeeGLLoadFunction[351]=__GLeeLink_GL_NV_framebuffer_multisample_coverage; - __GLeeGLLoadFunction[352]=__GLeeLink_GL_EXT_framebuffer_sRGB; - __GLeeGLLoadFunction[353]=__GLeeLink_GL_NV_geometry_shader4; - __GLeeGLLoadFunction[354]=__GLeeLink_GL_NV_parameter_buffer_object; - __GLeeGLLoadFunction[355]=__GLeeLink_GL_EXT_draw_buffers2; - __GLeeGLLoadFunction[356]=__GLeeLink_GL_NV_transform_feedback; - __GLeeGLLoadFunction[357]=__GLeeLink_GL_EXT_bindable_uniform; - __GLeeGLLoadFunction[358]=__GLeeLink_GL_EXT_texture_integer; - __GLeeGLLoadFunction[359]=__GLeeLink_GL_GREMEDY_frame_terminator; - __GLeeGLLoadFunction[360]=__GLeeLink_GL_NV_conditional_render; - __GLeeGLLoadFunction[361]=__GLeeLink_GL_NV_present_video; - __GLeeGLLoadFunction[362]=__GLeeLink_GL_EXT_transform_feedback; - __GLeeGLLoadFunction[363]=__GLeeLink_GL_EXT_direct_state_access; - __GLeeGLLoadFunction[364]=__GLeeLink_GL_EXT_vertex_array_bgra; - __GLeeGLLoadFunction[365]=__GLeeLink_GL_EXT_texture_swizzle; - __GLeeGLLoadFunction[366]=__GLeeLink_GL_NV_explicit_multisample; - __GLeeGLLoadFunction[367]=__GLeeLink_GL_NV_transform_feedback2; - __GLeeGLLoadFunction[368]=__GLeeLink_GL_ATI_meminfo; - __GLeeGLLoadFunction[369]=__GLeeLink_GL_AMD_performance_monitor; - __GLeeGLLoadFunction[370]=__GLeeLink_GL_AMD_texture_texture4; - __GLeeGLLoadFunction[371]=__GLeeLink_GL_AMD_vertex_shader_tesselator; - __GLeeGLLoadFunction[372]=__GLeeLink_GL_EXT_provoking_vertex; - __GLeeGLLoadFunction[373]=__GLeeLink_GL_EXT_texture_snorm; - __GLeeGLLoadFunction[374]=__GLeeLink_GL_AMD_draw_buffers_blend; - __GLeeGLLoadFunction[375]=__GLeeLink_GL_APPLE_texture_range; - __GLeeGLLoadFunction[376]=__GLeeLink_GL_APPLE_float_pixels; - __GLeeGLLoadFunction[377]=__GLeeLink_GL_APPLE_vertex_program_evaluators; - __GLeeGLLoadFunction[378]=__GLeeLink_GL_APPLE_aux_depth_stencil; - __GLeeGLLoadFunction[379]=__GLeeLink_GL_APPLE_object_purgeable; - __GLeeGLLoadFunction[380]=__GLeeLink_GL_APPLE_row_bytes; - __GLeeGLLoadFunction[381]=__GLeeLink_GL_APPLE_rgb_422; - __GLeeGLLoadFunction[382]=__GLeeLink_GL_NV_video_capture; - __GLeeGLLoadFunction[383]=__GLeeLink_GL_NV_copy_image; - __GLeeGLLoadFunction[384]=__GLeeLink_GL_EXT_separate_shader_objects; - __GLeeGLLoadFunction[385]=__GLeeLink_GL_NV_parameter_buffer_object2; - __GLeeGLLoadFunction[386]=__GLeeLink_GL_NV_shader_buffer_load; - __GLeeGLLoadFunction[387]=__GLeeLink_GL_NV_vertex_buffer_unified_memory; - __GLeeGLLoadFunction[388]=__GLeeLink_GL_NV_texture_barrier; - __GLeeGLLoadFunction[389]=__GLeeLink_GL_AMD_shader_stencil_export; - __GLeeGLLoadFunction[390]=__GLeeLink_GL_AMD_seamless_cubemap_per_texture; - __GLeeGLLoadFunction[391]=__GLeeLink_GL_AMD_conservative_depth; - __GLeeGLLoadFunction[392]=__GLeeLink_GL_EXT_shader_image_load_store; - __GLeeGLLoadFunction[393]=__GLeeLink_GL_EXT_vertex_attrib_64bit; - __GLeeGLLoadFunction[394]=__GLeeLink_GL_NV_gpu_program5; - __GLeeGLLoadFunction[395]=__GLeeLink_GL_NV_gpu_shader5; - __GLeeGLLoadFunction[396]=__GLeeLink_GL_NV_shader_buffer_store; - __GLeeGLLoadFunction[397]=__GLeeLink_GL_NV_tessellation_program5; - __GLeeGLLoadFunction[398]=__GLeeLink_GL_NV_vertex_attrib_integer_64bit; - __GLeeGLLoadFunction[399]=__GLeeLink_GL_NV_multisample_coverage; - __GLeeGLLoadFunction[400]=__GLeeLink_GL_AMD_name_gen_delete; - __GLeeGLLoadFunction[401]=__GLeeLink_GL_AMD_transform_feedback3_lines_triangles; - __GLeeGLLoadFunction[402]=__GLeeLink_GL_AMD_depth_clamp_separate; - __GLeeGLLoadFunction[403]=__GLeeLink_GL_EXT_texture_sRGB_decode; - __GLeeGLLoadFunction[404]=__GLeeLink_GL_NV_texture_multisample; - __GLeeGLLoadFunction[405]=__GLeeLink_GL_AMD_blend_minmax_factor; - __GLeeGLLoadFunction[406]=__GLeeLink_GL_AMD_sample_positions; - __GLeeGLLoadFunction[407]=__GLeeLink_GL_EXT_x11_sync_object; - __GLeeGLLoadFunction[408]=__GLeeLink_GL_AMD_multi_draw_indirect; - __GLeeGLLoadFunction[409]=__GLeeLink_GL_EXT_framebuffer_multisample_blit_scaled; - __GLeeGLLoadFunction[410]=__GLeeLink_GL_SGIX_texture_select; - __GLeeGLLoadFunction[411]=__GLeeLink_GL_INGR_blend_func_separate; - __GLeeGLLoadFunction[412]=__GLeeLink_GL_SGIX_depth_pass_instrument; - __GLeeGLLoadFunction[413]=__GLeeLink_GL_SGIX_igloo_interface; - __GLeeGLLoadFunction[414]=__GLeeLink_GL_OES_compressed_paletted_texture; - __GLeeGLLoadFunction[415]=__GLeeLink_GL_OES_fixed_point; - __GLeeGLLoadFunction[416]=__GLeeLink_GL_OES_single_precision; - __GLeeGLLoadFunction[417]=__GLeeLink_GL_OES_query_matrix; - __GLeeGLLoadFunction[418]=__GLeeLink_GL_OES_byte_coordinates; - __GLeeGLLoadFunction[419]=__GLeeLink_GL_NV_gpu_program4; - __GLeeGLLoadFunction[420]=__GLeeLink_GL_NV_path_rendering; - __GLeeGLLoadFunction[421]=__GLeeLink_GL_AMD_vertex_shader_tessellator; - __GLeeGLLoadFunction[422]=__GLeeLink_GL_EXT_fragment_lighting; - __GLeeGLLoadFunction[423]=__GLeeLink_GL_EXT_texture_compression_dxt1; - __GLeeGLLoadFunction[424]=__GLeeLink_GL_EXT_scene_marker; - __GLeeGLLoadFunction[425]=__GLeeLink_GL_EXT_geometry_shader4; - __GLeeGLLoadFunction[426]=__GLeeLink_GL_EXT_texture_env; - __GLeeGLLoadFunction[427]=__GLeeLink_GL_SGIX_texture_range; - __GLeeGLLoadFunction[428]=__GLeeLink_GL_SGIX_pixel_texture_bits; - __GLeeGLLoadFunction[429]=__GLeeLink_GL_IBM_static_data; + __GLeeGLLoadFunction[14]=__GLeeLink_GL_VERSION_4_3; + __GLeeGLLoadFunction[15]=__GLeeLink_GL_ARB_multitexture; + __GLeeGLLoadFunction[16]=__GLeeLink_GL_ARB_transpose_matrix; + __GLeeGLLoadFunction[17]=__GLeeLink_GL_ARB_multisample; + __GLeeGLLoadFunction[18]=__GLeeLink_GL_ARB_texture_env_add; + __GLeeGLLoadFunction[19]=__GLeeLink_GL_ARB_texture_cube_map; + __GLeeGLLoadFunction[20]=__GLeeLink_GL_ARB_texture_compression; + __GLeeGLLoadFunction[21]=__GLeeLink_GL_ARB_texture_border_clamp; + __GLeeGLLoadFunction[22]=__GLeeLink_GL_ARB_point_parameters; + __GLeeGLLoadFunction[23]=__GLeeLink_GL_ARB_vertex_blend; + __GLeeGLLoadFunction[24]=__GLeeLink_GL_ARB_matrix_palette; + __GLeeGLLoadFunction[25]=__GLeeLink_GL_ARB_texture_env_combine; + __GLeeGLLoadFunction[26]=__GLeeLink_GL_ARB_texture_env_crossbar; + __GLeeGLLoadFunction[27]=__GLeeLink_GL_ARB_texture_env_dot3; + __GLeeGLLoadFunction[28]=__GLeeLink_GL_ARB_texture_mirrored_repeat; + __GLeeGLLoadFunction[29]=__GLeeLink_GL_ARB_depth_texture; + __GLeeGLLoadFunction[30]=__GLeeLink_GL_ARB_shadow; + __GLeeGLLoadFunction[31]=__GLeeLink_GL_ARB_shadow_ambient; + __GLeeGLLoadFunction[32]=__GLeeLink_GL_ARB_window_pos; + __GLeeGLLoadFunction[33]=__GLeeLink_GL_ARB_vertex_program; + __GLeeGLLoadFunction[34]=__GLeeLink_GL_ARB_fragment_program; + __GLeeGLLoadFunction[35]=__GLeeLink_GL_ARB_vertex_buffer_object; + __GLeeGLLoadFunction[36]=__GLeeLink_GL_ARB_occlusion_query; + __GLeeGLLoadFunction[37]=__GLeeLink_GL_ARB_shader_objects; + __GLeeGLLoadFunction[38]=__GLeeLink_GL_ARB_vertex_shader; + __GLeeGLLoadFunction[39]=__GLeeLink_GL_ARB_fragment_shader; + __GLeeGLLoadFunction[40]=__GLeeLink_GL_ARB_shading_language_100; + __GLeeGLLoadFunction[41]=__GLeeLink_GL_ARB_texture_non_power_of_two; + __GLeeGLLoadFunction[42]=__GLeeLink_GL_ARB_point_sprite; + __GLeeGLLoadFunction[43]=__GLeeLink_GL_ARB_fragment_program_shadow; + __GLeeGLLoadFunction[44]=__GLeeLink_GL_ARB_draw_buffers; + __GLeeGLLoadFunction[45]=__GLeeLink_GL_ARB_texture_rectangle; + __GLeeGLLoadFunction[46]=__GLeeLink_GL_ARB_color_buffer_float; + __GLeeGLLoadFunction[47]=__GLeeLink_GL_ARB_half_float_pixel; + __GLeeGLLoadFunction[48]=__GLeeLink_GL_ARB_texture_float; + __GLeeGLLoadFunction[49]=__GLeeLink_GL_ARB_pixel_buffer_object; + __GLeeGLLoadFunction[50]=__GLeeLink_GL_ARB_depth_buffer_float; + __GLeeGLLoadFunction[51]=__GLeeLink_GL_ARB_draw_instanced; + __GLeeGLLoadFunction[52]=__GLeeLink_GL_ARB_framebuffer_object; + __GLeeGLLoadFunction[53]=__GLeeLink_GL_ARB_framebuffer_sRGB; + __GLeeGLLoadFunction[54]=__GLeeLink_GL_ARB_geometry_shader4; + __GLeeGLLoadFunction[55]=__GLeeLink_GL_ARB_half_float_vertex; + __GLeeGLLoadFunction[56]=__GLeeLink_GL_ARB_instanced_arrays; + __GLeeGLLoadFunction[57]=__GLeeLink_GL_ARB_map_buffer_range; + __GLeeGLLoadFunction[58]=__GLeeLink_GL_ARB_texture_buffer_object; + __GLeeGLLoadFunction[59]=__GLeeLink_GL_ARB_texture_compression_rgtc; + __GLeeGLLoadFunction[60]=__GLeeLink_GL_ARB_texture_rg; + __GLeeGLLoadFunction[61]=__GLeeLink_GL_ARB_vertex_array_object; + __GLeeGLLoadFunction[62]=__GLeeLink_GL_ARB_uniform_buffer_object; + __GLeeGLLoadFunction[63]=__GLeeLink_GL_ARB_compatibility; + __GLeeGLLoadFunction[64]=__GLeeLink_GL_ARB_copy_buffer; + __GLeeGLLoadFunction[65]=__GLeeLink_GL_ARB_shader_texture_lod; + __GLeeGLLoadFunction[66]=__GLeeLink_GL_ARB_depth_clamp; + __GLeeGLLoadFunction[67]=__GLeeLink_GL_ARB_draw_elements_base_vertex; + __GLeeGLLoadFunction[68]=__GLeeLink_GL_ARB_fragment_coord_conventions; + __GLeeGLLoadFunction[69]=__GLeeLink_GL_ARB_provoking_vertex; + __GLeeGLLoadFunction[70]=__GLeeLink_GL_ARB_seamless_cube_map; + __GLeeGLLoadFunction[71]=__GLeeLink_GL_ARB_sync; + __GLeeGLLoadFunction[72]=__GLeeLink_GL_ARB_texture_multisample; + __GLeeGLLoadFunction[73]=__GLeeLink_GL_ARB_vertex_array_bgra; + __GLeeGLLoadFunction[74]=__GLeeLink_GL_ARB_draw_buffers_blend; + __GLeeGLLoadFunction[75]=__GLeeLink_GL_ARB_sample_shading; + __GLeeGLLoadFunction[76]=__GLeeLink_GL_ARB_texture_cube_map_array; + __GLeeGLLoadFunction[77]=__GLeeLink_GL_ARB_texture_gather; + __GLeeGLLoadFunction[78]=__GLeeLink_GL_ARB_texture_query_lod; + __GLeeGLLoadFunction[79]=__GLeeLink_GL_ARB_shading_language_include; + __GLeeGLLoadFunction[80]=__GLeeLink_GL_ARB_texture_compression_bptc; + __GLeeGLLoadFunction[81]=__GLeeLink_GL_ARB_blend_func_extended; + __GLeeGLLoadFunction[82]=__GLeeLink_GL_ARB_explicit_attrib_location; + __GLeeGLLoadFunction[83]=__GLeeLink_GL_ARB_occlusion_query2; + __GLeeGLLoadFunction[84]=__GLeeLink_GL_ARB_sampler_objects; + __GLeeGLLoadFunction[85]=__GLeeLink_GL_ARB_shader_bit_encoding; + __GLeeGLLoadFunction[86]=__GLeeLink_GL_ARB_texture_rgb10_a2ui; + __GLeeGLLoadFunction[87]=__GLeeLink_GL_ARB_texture_swizzle; + __GLeeGLLoadFunction[88]=__GLeeLink_GL_ARB_timer_query; + __GLeeGLLoadFunction[89]=__GLeeLink_GL_ARB_vertex_type_2_10_10_10_rev; + __GLeeGLLoadFunction[90]=__GLeeLink_GL_ARB_draw_indirect; + __GLeeGLLoadFunction[91]=__GLeeLink_GL_ARB_gpu_shader5; + __GLeeGLLoadFunction[92]=__GLeeLink_GL_ARB_gpu_shader_fp64; + __GLeeGLLoadFunction[93]=__GLeeLink_GL_ARB_shader_subroutine; + __GLeeGLLoadFunction[94]=__GLeeLink_GL_ARB_tessellation_shader; + __GLeeGLLoadFunction[95]=__GLeeLink_GL_ARB_texture_buffer_object_rgb32; + __GLeeGLLoadFunction[96]=__GLeeLink_GL_ARB_transform_feedback2; + __GLeeGLLoadFunction[97]=__GLeeLink_GL_ARB_transform_feedback3; + __GLeeGLLoadFunction[98]=__GLeeLink_GL_ARB_ES2_compatibility; + __GLeeGLLoadFunction[99]=__GLeeLink_GL_ARB_get_program_binary; + __GLeeGLLoadFunction[100]=__GLeeLink_GL_ARB_separate_shader_objects; + __GLeeGLLoadFunction[101]=__GLeeLink_GL_ARB_shader_precision; + __GLeeGLLoadFunction[102]=__GLeeLink_GL_ARB_vertex_attrib_64bit; + __GLeeGLLoadFunction[103]=__GLeeLink_GL_ARB_viewport_array; + __GLeeGLLoadFunction[104]=__GLeeLink_GL_ARB_cl_event; + __GLeeGLLoadFunction[105]=__GLeeLink_GL_ARB_debug_output; + __GLeeGLLoadFunction[106]=__GLeeLink_GL_ARB_robustness; + __GLeeGLLoadFunction[107]=__GLeeLink_GL_ARB_shader_stencil_export; + __GLeeGLLoadFunction[108]=__GLeeLink_GL_ARB_base_instance; + __GLeeGLLoadFunction[109]=__GLeeLink_GL_ARB_shading_language_420pack; + __GLeeGLLoadFunction[110]=__GLeeLink_GL_ARB_transform_feedback_instanced; + __GLeeGLLoadFunction[111]=__GLeeLink_GL_ARB_compressed_texture_pixel_storage; + __GLeeGLLoadFunction[112]=__GLeeLink_GL_ARB_conservative_depth; + __GLeeGLLoadFunction[113]=__GLeeLink_GL_ARB_internalformat_query; + __GLeeGLLoadFunction[114]=__GLeeLink_GL_ARB_map_buffer_alignment; + __GLeeGLLoadFunction[115]=__GLeeLink_GL_ARB_shader_atomic_counters; + __GLeeGLLoadFunction[116]=__GLeeLink_GL_ARB_shader_image_load_store; + __GLeeGLLoadFunction[117]=__GLeeLink_GL_ARB_shading_language_packing; + __GLeeGLLoadFunction[118]=__GLeeLink_GL_ARB_texture_storage; + __GLeeGLLoadFunction[119]=__GLeeLink_GL_KHR_texture_compression_astc_ldr; + __GLeeGLLoadFunction[120]=__GLeeLink_GL_KHR_debug; + __GLeeGLLoadFunction[121]=__GLeeLink_GL_ARB_arrays_of_arrays; + __GLeeGLLoadFunction[122]=__GLeeLink_GL_ARB_clear_buffer_object; + __GLeeGLLoadFunction[123]=__GLeeLink_GL_ARB_compute_shader; + __GLeeGLLoadFunction[124]=__GLeeLink_GL_ARB_copy_image; + __GLeeGLLoadFunction[125]=__GLeeLink_GL_ARB_texture_view; + __GLeeGLLoadFunction[126]=__GLeeLink_GL_ARB_vertex_attrib_binding; + __GLeeGLLoadFunction[127]=__GLeeLink_GL_ARB_robustness_isolation; + __GLeeGLLoadFunction[128]=__GLeeLink_GL_ARB_ES3_compatibility; + __GLeeGLLoadFunction[129]=__GLeeLink_GL_ARB_explicit_uniform_location; + __GLeeGLLoadFunction[130]=__GLeeLink_GL_ARB_fragment_layer_viewport; + __GLeeGLLoadFunction[131]=__GLeeLink_GL_ARB_framebuffer_no_attachments; + __GLeeGLLoadFunction[132]=__GLeeLink_GL_ARB_internalformat_query2; + __GLeeGLLoadFunction[133]=__GLeeLink_GL_ARB_invalidate_subdata; + __GLeeGLLoadFunction[134]=__GLeeLink_GL_ARB_multi_draw_indirect; + __GLeeGLLoadFunction[135]=__GLeeLink_GL_ARB_program_interface_query; + __GLeeGLLoadFunction[136]=__GLeeLink_GL_ARB_robust_buffer_access_behavior; + __GLeeGLLoadFunction[137]=__GLeeLink_GL_ARB_shader_image_size; + __GLeeGLLoadFunction[138]=__GLeeLink_GL_ARB_shader_storage_buffer_object; + __GLeeGLLoadFunction[139]=__GLeeLink_GL_ARB_stencil_texturing; + __GLeeGLLoadFunction[140]=__GLeeLink_GL_ARB_texture_buffer_range; + __GLeeGLLoadFunction[141]=__GLeeLink_GL_ARB_texture_query_levels; + __GLeeGLLoadFunction[142]=__GLeeLink_GL_ARB_texture_storage_multisample; + __GLeeGLLoadFunction[143]=__GLeeLink_GL_EXT_abgr; + __GLeeGLLoadFunction[144]=__GLeeLink_GL_EXT_blend_color; + __GLeeGLLoadFunction[145]=__GLeeLink_GL_EXT_polygon_offset; + __GLeeGLLoadFunction[146]=__GLeeLink_GL_EXT_texture; + __GLeeGLLoadFunction[147]=__GLeeLink_GL_EXT_texture3D; + __GLeeGLLoadFunction[148]=__GLeeLink_GL_SGIS_texture_filter4; + __GLeeGLLoadFunction[149]=__GLeeLink_GL_EXT_subtexture; + __GLeeGLLoadFunction[150]=__GLeeLink_GL_EXT_copy_texture; + __GLeeGLLoadFunction[151]=__GLeeLink_GL_EXT_histogram; + __GLeeGLLoadFunction[152]=__GLeeLink_GL_EXT_convolution; + __GLeeGLLoadFunction[153]=__GLeeLink_GL_SGI_color_matrix; + __GLeeGLLoadFunction[154]=__GLeeLink_GL_SGI_color_table; + __GLeeGLLoadFunction[155]=__GLeeLink_GL_SGIS_pixel_texture; + __GLeeGLLoadFunction[156]=__GLeeLink_GL_SGIX_pixel_texture; + __GLeeGLLoadFunction[157]=__GLeeLink_GL_SGIS_texture4D; + __GLeeGLLoadFunction[158]=__GLeeLink_GL_SGI_texture_color_table; + __GLeeGLLoadFunction[159]=__GLeeLink_GL_EXT_cmyka; + __GLeeGLLoadFunction[160]=__GLeeLink_GL_EXT_texture_object; + __GLeeGLLoadFunction[161]=__GLeeLink_GL_SGIS_detail_texture; + __GLeeGLLoadFunction[162]=__GLeeLink_GL_SGIS_sharpen_texture; + __GLeeGLLoadFunction[163]=__GLeeLink_GL_EXT_packed_pixels; + __GLeeGLLoadFunction[164]=__GLeeLink_GL_SGIS_texture_lod; + __GLeeGLLoadFunction[165]=__GLeeLink_GL_SGIS_multisample; + __GLeeGLLoadFunction[166]=__GLeeLink_GL_EXT_rescale_normal; + __GLeeGLLoadFunction[167]=__GLeeLink_GL_EXT_vertex_array; + __GLeeGLLoadFunction[168]=__GLeeLink_GL_EXT_misc_attribute; + __GLeeGLLoadFunction[169]=__GLeeLink_GL_SGIS_generate_mipmap; + __GLeeGLLoadFunction[170]=__GLeeLink_GL_SGIX_clipmap; + __GLeeGLLoadFunction[171]=__GLeeLink_GL_SGIX_shadow; + __GLeeGLLoadFunction[172]=__GLeeLink_GL_SGIS_texture_edge_clamp; + __GLeeGLLoadFunction[173]=__GLeeLink_GL_SGIS_texture_border_clamp; + __GLeeGLLoadFunction[174]=__GLeeLink_GL_EXT_blend_minmax; + __GLeeGLLoadFunction[175]=__GLeeLink_GL_EXT_blend_subtract; + __GLeeGLLoadFunction[176]=__GLeeLink_GL_EXT_blend_logic_op; + __GLeeGLLoadFunction[177]=__GLeeLink_GL_SGIX_interlace; + __GLeeGLLoadFunction[178]=__GLeeLink_GL_SGIX_pixel_tiles; + __GLeeGLLoadFunction[179]=__GLeeLink_GL_SGIS_texture_select; + __GLeeGLLoadFunction[180]=__GLeeLink_GL_SGIX_sprite; + __GLeeGLLoadFunction[181]=__GLeeLink_GL_SGIX_texture_multi_buffer; + __GLeeGLLoadFunction[182]=__GLeeLink_GL_EXT_point_parameters; + __GLeeGLLoadFunction[183]=__GLeeLink_GL_SGIS_point_parameters; + __GLeeGLLoadFunction[184]=__GLeeLink_GL_SGIX_instruments; + __GLeeGLLoadFunction[185]=__GLeeLink_GL_SGIX_texture_scale_bias; + __GLeeGLLoadFunction[186]=__GLeeLink_GL_SGIX_framezoom; + __GLeeGLLoadFunction[187]=__GLeeLink_GL_SGIX_tag_sample_buffer; + __GLeeGLLoadFunction[188]=__GLeeLink_GL_FfdMaskSGIX; + __GLeeGLLoadFunction[189]=__GLeeLink_GL_SGIX_polynomial_ffd; + __GLeeGLLoadFunction[190]=__GLeeLink_GL_SGIX_reference_plane; + __GLeeGLLoadFunction[191]=__GLeeLink_GL_SGIX_flush_raster; + __GLeeGLLoadFunction[192]=__GLeeLink_GL_SGIX_depth_texture; + __GLeeGLLoadFunction[193]=__GLeeLink_GL_SGIS_fog_function; + __GLeeGLLoadFunction[194]=__GLeeLink_GL_SGIX_fog_offset; + __GLeeGLLoadFunction[195]=__GLeeLink_GL_HP_image_transform; + __GLeeGLLoadFunction[196]=__GLeeLink_GL_HP_convolution_border_modes; + __GLeeGLLoadFunction[197]=__GLeeLink_GL_INGR_palette_buffer; + __GLeeGLLoadFunction[198]=__GLeeLink_GL_SGIX_texture_add_env; + __GLeeGLLoadFunction[199]=__GLeeLink_GL_EXT_color_subtable; + __GLeeGLLoadFunction[200]=__GLeeLink_GL_PGI_vertex_hints; + __GLeeGLLoadFunction[201]=__GLeeLink_GL_PGI_misc_hints; + __GLeeGLLoadFunction[202]=__GLeeLink_GL_EXT_paletted_texture; + __GLeeGLLoadFunction[203]=__GLeeLink_GL_EXT_clip_volume_hint; + __GLeeGLLoadFunction[204]=__GLeeLink_GL_SGIX_list_priority; + __GLeeGLLoadFunction[205]=__GLeeLink_GL_SGIX_ir_instrument1; + __GLeeGLLoadFunction[206]=__GLeeLink_GL_SGIX_calligraphic_fragment; + __GLeeGLLoadFunction[207]=__GLeeLink_GL_SGIX_texture_lod_bias; + __GLeeGLLoadFunction[208]=__GLeeLink_GL_SGIX_shadow_ambient; + __GLeeGLLoadFunction[209]=__GLeeLink_GL_EXT_index_texture; + __GLeeGLLoadFunction[210]=__GLeeLink_GL_EXT_index_material; + __GLeeGLLoadFunction[211]=__GLeeLink_GL_EXT_index_func; + __GLeeGLLoadFunction[212]=__GLeeLink_GL_EXT_index_array_formats; + __GLeeGLLoadFunction[213]=__GLeeLink_GL_EXT_compiled_vertex_array; + __GLeeGLLoadFunction[214]=__GLeeLink_GL_EXT_cull_vertex; + __GLeeGLLoadFunction[215]=__GLeeLink_GL_SGIX_ycrcb; + __GLeeGLLoadFunction[216]=__GLeeLink_GL_SGIX_fragment_lighting; + __GLeeGLLoadFunction[217]=__GLeeLink_GL_IBM_rasterpos_clip; + __GLeeGLLoadFunction[218]=__GLeeLink_GL_HP_texture_lighting; + __GLeeGLLoadFunction[219]=__GLeeLink_GL_EXT_draw_range_elements; + __GLeeGLLoadFunction[220]=__GLeeLink_GL_WIN_phong_shading; + __GLeeGLLoadFunction[221]=__GLeeLink_GL_WIN_specular_fog; + __GLeeGLLoadFunction[222]=__GLeeLink_GL_EXT_light_texture; + __GLeeGLLoadFunction[223]=__GLeeLink_GL_SGIX_blend_alpha_minmax; + __GLeeGLLoadFunction[224]=__GLeeLink_GL_SGIX_impact_pixel_texture; + __GLeeGLLoadFunction[225]=__GLeeLink_GL_EXT_bgra; + __GLeeGLLoadFunction[226]=__GLeeLink_GL_SGIX_async; + __GLeeGLLoadFunction[227]=__GLeeLink_GL_SGIX_async_pixel; + __GLeeGLLoadFunction[228]=__GLeeLink_GL_SGIX_async_histogram; + __GLeeGLLoadFunction[229]=__GLeeLink_GL_INTEL_texture_scissor; + __GLeeGLLoadFunction[230]=__GLeeLink_GL_INTEL_parallel_arrays; + __GLeeGLLoadFunction[231]=__GLeeLink_GL_HP_occlusion_test; + __GLeeGLLoadFunction[232]=__GLeeLink_GL_EXT_pixel_transform; + __GLeeGLLoadFunction[233]=__GLeeLink_GL_EXT_pixel_transform_color_table; + __GLeeGLLoadFunction[234]=__GLeeLink_GL_EXT_shared_texture_palette; + __GLeeGLLoadFunction[235]=__GLeeLink_GL_EXT_separate_specular_color; + __GLeeGLLoadFunction[236]=__GLeeLink_GL_EXT_secondary_color; + __GLeeGLLoadFunction[237]=__GLeeLink_GL_EXT_texture_perturb_normal; + __GLeeGLLoadFunction[238]=__GLeeLink_GL_EXT_multi_draw_arrays; + __GLeeGLLoadFunction[239]=__GLeeLink_GL_EXT_fog_coord; + __GLeeGLLoadFunction[240]=__GLeeLink_GL_REND_screen_coordinates; + __GLeeGLLoadFunction[241]=__GLeeLink_GL_EXT_coordinate_frame; + __GLeeGLLoadFunction[242]=__GLeeLink_GL_EXT_texture_env_combine; + __GLeeGLLoadFunction[243]=__GLeeLink_GL_APPLE_specular_vector; + __GLeeGLLoadFunction[244]=__GLeeLink_GL_APPLE_transform_hint; + __GLeeGLLoadFunction[245]=__GLeeLink_GL_SGIX_fog_scale; + __GLeeGLLoadFunction[246]=__GLeeLink_GL_SUNX_constant_data; + __GLeeGLLoadFunction[247]=__GLeeLink_GL_SUN_global_alpha; + __GLeeGLLoadFunction[248]=__GLeeLink_GL_SUN_triangle_list; + __GLeeGLLoadFunction[249]=__GLeeLink_GL_SUN_vertex; + __GLeeGLLoadFunction[250]=__GLeeLink_GL_EXT_blend_func_separate; + __GLeeGLLoadFunction[251]=__GLeeLink_GL_INGR_color_clamp; + __GLeeGLLoadFunction[252]=__GLeeLink_GL_INGR_interlace_read; + __GLeeGLLoadFunction[253]=__GLeeLink_GL_EXT_stencil_wrap; + __GLeeGLLoadFunction[254]=__GLeeLink_GL_EXT_422_pixels; + __GLeeGLLoadFunction[255]=__GLeeLink_GL_NV_texgen_reflection; + __GLeeGLLoadFunction[256]=__GLeeLink_GL_EXT_texture_cube_map; + __GLeeGLLoadFunction[257]=__GLeeLink_GL_SUN_convolution_border_modes; + __GLeeGLLoadFunction[258]=__GLeeLink_GL_EXT_texture_env_add; + __GLeeGLLoadFunction[259]=__GLeeLink_GL_EXT_texture_lod_bias; + __GLeeGLLoadFunction[260]=__GLeeLink_GL_EXT_texture_filter_anisotropic; + __GLeeGLLoadFunction[261]=__GLeeLink_GL_EXT_vertex_weighting; + __GLeeGLLoadFunction[262]=__GLeeLink_GL_NV_light_max_exponent; + __GLeeGLLoadFunction[263]=__GLeeLink_GL_NV_vertex_array_range; + __GLeeGLLoadFunction[264]=__GLeeLink_GL_NV_register_combiners; + __GLeeGLLoadFunction[265]=__GLeeLink_GL_NV_fog_distance; + __GLeeGLLoadFunction[266]=__GLeeLink_GL_NV_texgen_emboss; + __GLeeGLLoadFunction[267]=__GLeeLink_GL_NV_blend_square; + __GLeeGLLoadFunction[268]=__GLeeLink_GL_NV_texture_env_combine4; + __GLeeGLLoadFunction[269]=__GLeeLink_GL_MESA_resize_buffers; + __GLeeGLLoadFunction[270]=__GLeeLink_GL_MESA_window_pos; + __GLeeGLLoadFunction[271]=__GLeeLink_GL_EXT_texture_compression_s3tc; + __GLeeGLLoadFunction[272]=__GLeeLink_GL_IBM_cull_vertex; + __GLeeGLLoadFunction[273]=__GLeeLink_GL_IBM_multimode_draw_arrays; + __GLeeGLLoadFunction[274]=__GLeeLink_GL_IBM_vertex_array_lists; + __GLeeGLLoadFunction[275]=__GLeeLink_GL_SGIX_subsample; + __GLeeGLLoadFunction[276]=__GLeeLink_GL_SGIX_ycrcb_subsample; + __GLeeGLLoadFunction[277]=__GLeeLink_GL_SGIX_ycrcba; + __GLeeGLLoadFunction[278]=__GLeeLink_GL_SGI_depth_pass_instrument; + __GLeeGLLoadFunction[279]=__GLeeLink_GL_3DFX_texture_compression_FXT1; + __GLeeGLLoadFunction[280]=__GLeeLink_GL_3DFX_multisample; + __GLeeGLLoadFunction[281]=__GLeeLink_GL_3DFX_tbuffer; + __GLeeGLLoadFunction[282]=__GLeeLink_GL_EXT_multisample; + __GLeeGLLoadFunction[283]=__GLeeLink_GL_SGIX_vertex_preclip; + __GLeeGLLoadFunction[284]=__GLeeLink_GL_SGIX_convolution_accuracy; + __GLeeGLLoadFunction[285]=__GLeeLink_GL_SGIX_resample; + __GLeeGLLoadFunction[286]=__GLeeLink_GL_SGIS_point_line_texgen; + __GLeeGLLoadFunction[287]=__GLeeLink_GL_SGIS_texture_color_mask; + __GLeeGLLoadFunction[288]=__GLeeLink_GL_EXT_texture_env_dot3; + __GLeeGLLoadFunction[289]=__GLeeLink_GL_ATI_texture_mirror_once; + __GLeeGLLoadFunction[290]=__GLeeLink_GL_NV_fence; + __GLeeGLLoadFunction[291]=__GLeeLink_GL_IBM_texture_mirrored_repeat; + __GLeeGLLoadFunction[292]=__GLeeLink_GL_NV_evaluators; + __GLeeGLLoadFunction[293]=__GLeeLink_GL_NV_packed_depth_stencil; + __GLeeGLLoadFunction[294]=__GLeeLink_GL_NV_register_combiners2; + __GLeeGLLoadFunction[295]=__GLeeLink_GL_NV_texture_compression_vtc; + __GLeeGLLoadFunction[296]=__GLeeLink_GL_NV_texture_rectangle; + __GLeeGLLoadFunction[297]=__GLeeLink_GL_NV_texture_shader; + __GLeeGLLoadFunction[298]=__GLeeLink_GL_NV_texture_shader2; + __GLeeGLLoadFunction[299]=__GLeeLink_GL_NV_vertex_array_range2; + __GLeeGLLoadFunction[300]=__GLeeLink_GL_NV_vertex_program; + __GLeeGLLoadFunction[301]=__GLeeLink_GL_SGIX_texture_coordinate_clamp; + __GLeeGLLoadFunction[302]=__GLeeLink_GL_SGIX_scalebias_hint; + __GLeeGLLoadFunction[303]=__GLeeLink_GL_OML_interlace; + __GLeeGLLoadFunction[304]=__GLeeLink_GL_OML_subsample; + __GLeeGLLoadFunction[305]=__GLeeLink_GL_OML_resample; + __GLeeGLLoadFunction[306]=__GLeeLink_GL_NV_copy_depth_to_color; + __GLeeGLLoadFunction[307]=__GLeeLink_GL_ATI_envmap_bumpmap; + __GLeeGLLoadFunction[308]=__GLeeLink_GL_ATI_fragment_shader; + __GLeeGLLoadFunction[309]=__GLeeLink_GL_ATI_pn_triangles; + __GLeeGLLoadFunction[310]=__GLeeLink_GL_ATI_vertex_array_object; + __GLeeGLLoadFunction[311]=__GLeeLink_GL_EXT_vertex_shader; + __GLeeGLLoadFunction[312]=__GLeeLink_GL_ATI_vertex_streams; + __GLeeGLLoadFunction[313]=__GLeeLink_GL_ATI_element_array; + __GLeeGLLoadFunction[314]=__GLeeLink_GL_SUN_mesh_array; + __GLeeGLLoadFunction[315]=__GLeeLink_GL_SUN_slice_accum; + __GLeeGLLoadFunction[316]=__GLeeLink_GL_NV_multisample_filter_hint; + __GLeeGLLoadFunction[317]=__GLeeLink_GL_NV_depth_clamp; + __GLeeGLLoadFunction[318]=__GLeeLink_GL_NV_occlusion_query; + __GLeeGLLoadFunction[319]=__GLeeLink_GL_NV_point_sprite; + __GLeeGLLoadFunction[320]=__GLeeLink_GL_NV_texture_shader3; + __GLeeGLLoadFunction[321]=__GLeeLink_GL_NV_vertex_program1_1; + __GLeeGLLoadFunction[322]=__GLeeLink_GL_EXT_shadow_funcs; + __GLeeGLLoadFunction[323]=__GLeeLink_GL_EXT_stencil_two_side; + __GLeeGLLoadFunction[324]=__GLeeLink_GL_ATI_text_fragment_shader; + __GLeeGLLoadFunction[325]=__GLeeLink_GL_APPLE_client_storage; + __GLeeGLLoadFunction[326]=__GLeeLink_GL_APPLE_element_array; + __GLeeGLLoadFunction[327]=__GLeeLink_GL_APPLE_fence; + __GLeeGLLoadFunction[328]=__GLeeLink_GL_APPLE_vertex_array_object; + __GLeeGLLoadFunction[329]=__GLeeLink_GL_APPLE_vertex_array_range; + __GLeeGLLoadFunction[330]=__GLeeLink_GL_APPLE_ycbcr_422; + __GLeeGLLoadFunction[331]=__GLeeLink_GL_S3_s3tc; + __GLeeGLLoadFunction[332]=__GLeeLink_GL_ATI_draw_buffers; + __GLeeGLLoadFunction[333]=__GLeeLink_GL_ATI_pixel_format_float; + __GLeeGLLoadFunction[334]=__GLeeLink_GL_ATI_texture_env_combine3; + __GLeeGLLoadFunction[335]=__GLeeLink_GL_ATI_texture_float; + __GLeeGLLoadFunction[336]=__GLeeLink_GL_NV_float_buffer; + __GLeeGLLoadFunction[337]=__GLeeLink_GL_NV_fragment_program; + __GLeeGLLoadFunction[338]=__GLeeLink_GL_NV_half_float; + __GLeeGLLoadFunction[339]=__GLeeLink_GL_NV_pixel_data_range; + __GLeeGLLoadFunction[340]=__GLeeLink_GL_NV_primitive_restart; + __GLeeGLLoadFunction[341]=__GLeeLink_GL_NV_texture_expand_normal; + __GLeeGLLoadFunction[342]=__GLeeLink_GL_NV_vertex_program2; + __GLeeGLLoadFunction[343]=__GLeeLink_GL_ATI_map_object_buffer; + __GLeeGLLoadFunction[344]=__GLeeLink_GL_ATI_separate_stencil; + __GLeeGLLoadFunction[345]=__GLeeLink_GL_ATI_vertex_attrib_array_object; + __GLeeGLLoadFunction[346]=__GLeeLink_GL_OES_byte_coordinates; + __GLeeGLLoadFunction[347]=__GLeeLink_GL_OES_fixed_point; + __GLeeGLLoadFunction[348]=__GLeeLink_GL_OES_single_precision; + __GLeeGLLoadFunction[349]=__GLeeLink_GL_OES_compressed_paletted_texture; + __GLeeGLLoadFunction[350]=__GLeeLink_GL_OES_read_format; + __GLeeGLLoadFunction[351]=__GLeeLink_GL_OES_query_matrix; + __GLeeGLLoadFunction[352]=__GLeeLink_GL_EXT_depth_bounds_test; + __GLeeGLLoadFunction[353]=__GLeeLink_GL_EXT_texture_mirror_clamp; + __GLeeGLLoadFunction[354]=__GLeeLink_GL_EXT_blend_equation_separate; + __GLeeGLLoadFunction[355]=__GLeeLink_GL_MESA_pack_invert; + __GLeeGLLoadFunction[356]=__GLeeLink_GL_MESA_ycbcr_texture; + __GLeeGLLoadFunction[357]=__GLeeLink_GL_EXT_pixel_buffer_object; + __GLeeGLLoadFunction[358]=__GLeeLink_GL_NV_fragment_program_option; + __GLeeGLLoadFunction[359]=__GLeeLink_GL_NV_fragment_program2; + __GLeeGLLoadFunction[360]=__GLeeLink_GL_NV_vertex_program2_option; + __GLeeGLLoadFunction[361]=__GLeeLink_GL_NV_vertex_program3; + __GLeeGLLoadFunction[362]=__GLeeLink_GL_EXT_framebuffer_object; + __GLeeGLLoadFunction[363]=__GLeeLink_GL_GREMEDY_string_marker; + __GLeeGLLoadFunction[364]=__GLeeLink_GL_EXT_packed_depth_stencil; + __GLeeGLLoadFunction[365]=__GLeeLink_GL_EXT_stencil_clear_tag; + __GLeeGLLoadFunction[366]=__GLeeLink_GL_EXT_texture_sRGB; + __GLeeGLLoadFunction[367]=__GLeeLink_GL_EXT_framebuffer_blit; + __GLeeGLLoadFunction[368]=__GLeeLink_GL_EXT_framebuffer_multisample; + __GLeeGLLoadFunction[369]=__GLeeLink_GL_MESAX_texture_stack; + __GLeeGLLoadFunction[370]=__GLeeLink_GL_EXT_timer_query; + __GLeeGLLoadFunction[371]=__GLeeLink_GL_EXT_gpu_program_parameters; + __GLeeGLLoadFunction[372]=__GLeeLink_GL_APPLE_flush_buffer_range; + __GLeeGLLoadFunction[373]=__GLeeLink_GL_EXT_gpu_shader4; + __GLeeGLLoadFunction[374]=__GLeeLink_GL_EXT_draw_instanced; + __GLeeGLLoadFunction[375]=__GLeeLink_GL_EXT_packed_float; + __GLeeGLLoadFunction[376]=__GLeeLink_GL_EXT_texture_array; + __GLeeGLLoadFunction[377]=__GLeeLink_GL_EXT_texture_buffer_object; + __GLeeGLLoadFunction[378]=__GLeeLink_GL_EXT_texture_compression_latc; + __GLeeGLLoadFunction[379]=__GLeeLink_GL_EXT_texture_compression_rgtc; + __GLeeGLLoadFunction[380]=__GLeeLink_GL_EXT_texture_shared_exponent; + __GLeeGLLoadFunction[381]=__GLeeLink_GL_NV_depth_buffer_float; + __GLeeGLLoadFunction[382]=__GLeeLink_GL_NV_framebuffer_multisample_coverage; + __GLeeGLLoadFunction[383]=__GLeeLink_GL_EXT_framebuffer_sRGB; + __GLeeGLLoadFunction[384]=__GLeeLink_GL_NV_geometry_shader4; + __GLeeGLLoadFunction[385]=__GLeeLink_GL_NV_parameter_buffer_object; + __GLeeGLLoadFunction[386]=__GLeeLink_GL_EXT_draw_buffers2; + __GLeeGLLoadFunction[387]=__GLeeLink_GL_NV_transform_feedback; + __GLeeGLLoadFunction[388]=__GLeeLink_GL_EXT_bindable_uniform; + __GLeeGLLoadFunction[389]=__GLeeLink_GL_EXT_texture_integer; + __GLeeGLLoadFunction[390]=__GLeeLink_GL_GREMEDY_frame_terminator; + __GLeeGLLoadFunction[391]=__GLeeLink_GL_NV_conditional_render; + __GLeeGLLoadFunction[392]=__GLeeLink_GL_NV_present_video; + __GLeeGLLoadFunction[393]=__GLeeLink_GL_EXT_transform_feedback; + __GLeeGLLoadFunction[394]=__GLeeLink_GL_EXT_direct_state_access; + __GLeeGLLoadFunction[395]=__GLeeLink_GL_EXT_vertex_array_bgra; + __GLeeGLLoadFunction[396]=__GLeeLink_GL_EXT_texture_swizzle; + __GLeeGLLoadFunction[397]=__GLeeLink_GL_NV_explicit_multisample; + __GLeeGLLoadFunction[398]=__GLeeLink_GL_NV_transform_feedback2; + __GLeeGLLoadFunction[399]=__GLeeLink_GL_ATI_meminfo; + __GLeeGLLoadFunction[400]=__GLeeLink_GL_AMD_performance_monitor; + __GLeeGLLoadFunction[401]=__GLeeLink_GL_AMD_texture_texture4; + __GLeeGLLoadFunction[402]=__GLeeLink_GL_AMD_vertex_shader_tesselator; + __GLeeGLLoadFunction[403]=__GLeeLink_GL_EXT_provoking_vertex; + __GLeeGLLoadFunction[404]=__GLeeLink_GL_EXT_texture_snorm; + __GLeeGLLoadFunction[405]=__GLeeLink_GL_AMD_draw_buffers_blend; + __GLeeGLLoadFunction[406]=__GLeeLink_GL_APPLE_texture_range; + __GLeeGLLoadFunction[407]=__GLeeLink_GL_APPLE_float_pixels; + __GLeeGLLoadFunction[408]=__GLeeLink_GL_APPLE_vertex_program_evaluators; + __GLeeGLLoadFunction[409]=__GLeeLink_GL_APPLE_aux_depth_stencil; + __GLeeGLLoadFunction[410]=__GLeeLink_GL_APPLE_object_purgeable; + __GLeeGLLoadFunction[411]=__GLeeLink_GL_APPLE_row_bytes; + __GLeeGLLoadFunction[412]=__GLeeLink_GL_APPLE_rgb_422; + __GLeeGLLoadFunction[413]=__GLeeLink_GL_NV_video_capture; + __GLeeGLLoadFunction[414]=__GLeeLink_GL_NV_copy_image; + __GLeeGLLoadFunction[415]=__GLeeLink_GL_EXT_separate_shader_objects; + __GLeeGLLoadFunction[416]=__GLeeLink_GL_NV_parameter_buffer_object2; + __GLeeGLLoadFunction[417]=__GLeeLink_GL_NV_shader_buffer_load; + __GLeeGLLoadFunction[418]=__GLeeLink_GL_NV_vertex_buffer_unified_memory; + __GLeeGLLoadFunction[419]=__GLeeLink_GL_NV_texture_barrier; + __GLeeGLLoadFunction[420]=__GLeeLink_GL_AMD_shader_stencil_export; + __GLeeGLLoadFunction[421]=__GLeeLink_GL_AMD_seamless_cubemap_per_texture; + __GLeeGLLoadFunction[422]=__GLeeLink_GL_AMD_conservative_depth; + __GLeeGLLoadFunction[423]=__GLeeLink_GL_EXT_shader_image_load_store; + __GLeeGLLoadFunction[424]=__GLeeLink_GL_EXT_vertex_attrib_64bit; + __GLeeGLLoadFunction[425]=__GLeeLink_GL_NV_gpu_program5; + __GLeeGLLoadFunction[426]=__GLeeLink_GL_NV_gpu_shader5; + __GLeeGLLoadFunction[427]=__GLeeLink_GL_NV_shader_buffer_store; + __GLeeGLLoadFunction[428]=__GLeeLink_GL_NV_tessellation_program5; + __GLeeGLLoadFunction[429]=__GLeeLink_GL_NV_vertex_attrib_integer_64bit; + __GLeeGLLoadFunction[430]=__GLeeLink_GL_NV_multisample_coverage; + __GLeeGLLoadFunction[431]=__GLeeLink_GL_AMD_name_gen_delete; + __GLeeGLLoadFunction[432]=__GLeeLink_GL_AMD_debug_output; + __GLeeGLLoadFunction[433]=__GLeeLink_GL_AMD_transform_feedback3_lines_triangles; + __GLeeGLLoadFunction[434]=__GLeeLink_GL_AMD_depth_clamp_separate; + __GLeeGLLoadFunction[435]=__GLeeLink_GL_EXT_texture_sRGB_decode; + __GLeeGLLoadFunction[436]=__GLeeLink_GL_NV_texture_multisample; + __GLeeGLLoadFunction[437]=__GLeeLink_GL_AMD_blend_minmax_factor; + __GLeeGLLoadFunction[438]=__GLeeLink_GL_AMD_sample_positions; + __GLeeGLLoadFunction[439]=__GLeeLink_GL_EXT_x11_sync_object; + __GLeeGLLoadFunction[440]=__GLeeLink_GL_AMD_multi_draw_indirect; + __GLeeGLLoadFunction[441]=__GLeeLink_GL_EXT_framebuffer_multisample_blit_scaled; + __GLeeGLLoadFunction[442]=__GLeeLink_GL_NV_path_rendering; + __GLeeGLLoadFunction[443]=__GLeeLink_GL_AMD_pinned_memory; + __GLeeGLLoadFunction[444]=__GLeeLink_GL_AMD_stencil_operation_extended; + __GLeeGLLoadFunction[445]=__GLeeLink_GL_AMD_vertex_shader_viewport_index; + __GLeeGLLoadFunction[446]=__GLeeLink_GL_AMD_vertex_shader_layer; + __GLeeGLLoadFunction[447]=__GLeeLink_GL_NV_bindless_texture; + __GLeeGLLoadFunction[448]=__GLeeLink_GL_NV_shader_atomic_float; + __GLeeGLLoadFunction[449]=__GLeeLink_GL_AMD_query_buffer_object; + __GLeeGLLoadFunction[450]=__GLeeLink_GL_NV_compute_program5; + __GLeeGLLoadFunction[451]=__GLeeLink_GL_NV_shader_storage_buffer_object; + __GLeeGLLoadFunction[452]=__GLeeLink_GL_NV_shader_atomic_counters; + __GLeeGLLoadFunction[453]=__GLeeLink_GL_NV_deep_texture3D; + __GLeeGLLoadFunction[454]=__GLeeLink_GL_NVX_conditional_render; + __GLeeGLLoadFunction[455]=__GLeeLink_GL_AMD_sparse_texture; + __GLeeGLLoadFunction[456]=__GLeeLink_GL_AMD_shader_trinary_minmax; + __GLeeGLLoadFunction[457]=__GLeeLink_GL_INTEL_map_texture; + __GLeeGLLoadFunction[458]=__GLeeLink_GL_NV_draw_texture; + __GLeeGLLoadFunction[459]=__GLeeLink_GL_SGIX_texture_select; + __GLeeGLLoadFunction[460]=__GLeeLink_GL_INGR_blend_func_separate; + __GLeeGLLoadFunction[461]=__GLeeLink_GL_SGIX_depth_pass_instrument; + __GLeeGLLoadFunction[462]=__GLeeLink_GL_SGIX_igloo_interface; } #ifdef _WIN32 @@ -19544,6 +21711,10 @@ GLuint __GLeeLink_WGL_NV_DX_interop(void) return GLEE_LINK_PARTIAL; } +GLuint __GLeeLink_WGL_NV_DX_interop2(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_WGL_EXT_swap_control_tear(void) {return GLEE_LINK_COMPLETE;} + GLuint __GLeeLink_WGL_EXT_display_color_table(void) { GLint nLinked=0; @@ -19639,7 +21810,7 @@ GLuint __GLeeLink_WGL_NV_video_output(void) return GLEE_LINK_PARTIAL; } -GLEE_LINK_FUNCTION __GLeeWGLLoadFunction[45]; +GLEE_LINK_FUNCTION __GLeeWGLLoadFunction[47]; void initWGLLoadFunctions(void) { @@ -19681,13 +21852,15 @@ void initWGLLoadFunctions(void) __GLeeWGLLoadFunction[35]=__GLeeLink_WGL_NV_multisample_coverage; __GLeeWGLLoadFunction[36]=__GLeeLink_WGL_EXT_create_context_es2_profile; __GLeeWGLLoadFunction[37]=__GLeeLink_WGL_NV_DX_interop; - __GLeeWGLLoadFunction[38]=__GLeeLink_WGL_EXT_display_color_table; - __GLeeWGLLoadFunction[39]=__GLeeLink_WGL_EXT_extensions_string; - __GLeeWGLLoadFunction[40]=__GLeeLink_WGL_EXT_swap_control; - __GLeeWGLLoadFunction[41]=__GLeeLink_WGL_NV_vertex_array_range; - __GLeeWGLLoadFunction[42]=__GLeeLink_WGL_OML_sync_control; - __GLeeWGLLoadFunction[43]=__GLeeLink_WGL_I3D_swap_frame_usage; - __GLeeWGLLoadFunction[44]=__GLeeLink_WGL_NV_video_output; + __GLeeWGLLoadFunction[38]=__GLeeLink_WGL_NV_DX_interop2; + __GLeeWGLLoadFunction[39]=__GLeeLink_WGL_EXT_swap_control_tear; + __GLeeWGLLoadFunction[40]=__GLeeLink_WGL_EXT_display_color_table; + __GLeeWGLLoadFunction[41]=__GLeeLink_WGL_EXT_extensions_string; + __GLeeWGLLoadFunction[42]=__GLeeLink_WGL_EXT_swap_control; + __GLeeWGLLoadFunction[43]=__GLeeLink_WGL_NV_vertex_array_range; + __GLeeWGLLoadFunction[44]=__GLeeLink_WGL_OML_sync_control; + __GLeeWGLLoadFunction[45]=__GLeeLink_WGL_I3D_swap_frame_usage; + __GLeeWGLLoadFunction[46]=__GLeeLink_WGL_NV_video_output; } #elif defined(__APPLE__) || defined(__APPLE_CC__) @@ -20092,6 +22265,12 @@ GLuint __GLeeLink_GLX_AMD_gpu_association(void) {return GLEE_LINK_COMPLETE;} GLuint __GLeeLink_GLX_EXT_create_context_es2_profile(void) {return GLEE_LINK_COMPLETE;} +GLuint __GLeeLink_GLX_EXT_create_context_es_profile(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_swap_control_tear(void) {return GLEE_LINK_COMPLETE;} + +GLuint __GLeeLink_GLX_EXT_buffer_age(void) {return GLEE_LINK_COMPLETE;} + GLuint __GLeeLink_GLX_NV_video_output(void) { GLint nLinked=0; @@ -20108,9 +22287,7 @@ GLuint __GLeeLink_GLX_NV_video_output(void) return GLEE_LINK_PARTIAL; } -GLuint __GLeeLink_GLX_EXT_scene_marker(void) {return GLEE_LINK_COMPLETE;} - -GLEE_LINK_FUNCTION __GLeeGLXLoadFunction[51]; +GLEE_LINK_FUNCTION __GLeeGLXLoadFunction[53]; void initGLXLoadFunctions(void) { @@ -20163,8 +22340,10 @@ void initGLXLoadFunctions(void) __GLeeGLXLoadFunction[46]=__GLeeLink_GLX_NV_multisample_coverage; __GLeeGLXLoadFunction[47]=__GLeeLink_GLX_AMD_gpu_association; __GLeeGLXLoadFunction[48]=__GLeeLink_GLX_EXT_create_context_es2_profile; - __GLeeGLXLoadFunction[49]=__GLeeLink_GLX_NV_video_output; - __GLeeGLXLoadFunction[50]=__GLeeLink_GLX_EXT_scene_marker; + __GLeeGLXLoadFunction[49]=__GLeeLink_GLX_EXT_create_context_es_profile; + __GLeeGLXLoadFunction[50]=__GLeeLink_GLX_EXT_swap_control_tear; + __GLeeGLXLoadFunction[51]=__GLeeLink_GLX_EXT_buffer_age; + __GLeeGLXLoadFunction[52]=__GLeeLink_GLX_NV_video_output; } #endif /* end Linux */ @@ -20520,6 +22699,11 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_VERSION_4_2 = GL_TRUE; __GLeeLink_GL_VERSION_4_2(); } + if (version>=1027) + { + _GLEE_VERSION_4_3 = GL_TRUE; + __GLeeLink_GL_VERSION_4_3(); + } if (__GLeeCheckExtension("GL_ARB_multitexture", &extensionNames) ) { _GLEE_ARB_multitexture = GL_TRUE; @@ -20970,6 +23154,11 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_ARB_cl_event = GL_TRUE; __GLeeLink_GL_ARB_cl_event(); } + if (__GLeeCheckExtension("GL_ARB_debug_output", &extensionNames) ) + { + _GLEE_ARB_debug_output = GL_TRUE; + __GLeeLink_GL_ARB_debug_output(); + } if (__GLeeCheckExtension("GL_ARB_robustness", &extensionNames) ) { _GLEE_ARB_robustness = GL_TRUE; @@ -21035,6 +23224,126 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_ARB_texture_storage = GL_TRUE; __GLeeLink_GL_ARB_texture_storage(); } + if (__GLeeCheckExtension("GL_KHR_texture_compression_astc_ldr", &extensionNames) ) + { + _GLEE_KHR_texture_compression_astc_ldr = GL_TRUE; + __GLeeLink_GL_KHR_texture_compression_astc_ldr(); + } + if (__GLeeCheckExtension("GL_KHR_debug", &extensionNames) ) + { + _GLEE_KHR_debug = GL_TRUE; + __GLeeLink_GL_KHR_debug(); + } + if (__GLeeCheckExtension("GL_ARB_arrays_of_arrays", &extensionNames) ) + { + _GLEE_ARB_arrays_of_arrays = GL_TRUE; + __GLeeLink_GL_ARB_arrays_of_arrays(); + } + if (__GLeeCheckExtension("GL_ARB_clear_buffer_object", &extensionNames) ) + { + _GLEE_ARB_clear_buffer_object = GL_TRUE; + __GLeeLink_GL_ARB_clear_buffer_object(); + } + if (__GLeeCheckExtension("GL_ARB_compute_shader", &extensionNames) ) + { + _GLEE_ARB_compute_shader = GL_TRUE; + __GLeeLink_GL_ARB_compute_shader(); + } + if (__GLeeCheckExtension("GL_ARB_copy_image", &extensionNames) ) + { + _GLEE_ARB_copy_image = GL_TRUE; + __GLeeLink_GL_ARB_copy_image(); + } + if (__GLeeCheckExtension("GL_ARB_texture_view", &extensionNames) ) + { + _GLEE_ARB_texture_view = GL_TRUE; + __GLeeLink_GL_ARB_texture_view(); + } + if (__GLeeCheckExtension("GL_ARB_vertex_attrib_binding", &extensionNames) ) + { + _GLEE_ARB_vertex_attrib_binding = GL_TRUE; + __GLeeLink_GL_ARB_vertex_attrib_binding(); + } + if (__GLeeCheckExtension("GL_ARB_robustness_isolation", &extensionNames) ) + { + _GLEE_ARB_robustness_isolation = GL_TRUE; + __GLeeLink_GL_ARB_robustness_isolation(); + } + if (__GLeeCheckExtension("GL_ARB_ES3_compatibility", &extensionNames) ) + { + _GLEE_ARB_ES3_compatibility = GL_TRUE; + __GLeeLink_GL_ARB_ES3_compatibility(); + } + if (__GLeeCheckExtension("GL_ARB_explicit_uniform_location", &extensionNames) ) + { + _GLEE_ARB_explicit_uniform_location = GL_TRUE; + __GLeeLink_GL_ARB_explicit_uniform_location(); + } + if (__GLeeCheckExtension("GL_ARB_fragment_layer_viewport", &extensionNames) ) + { + _GLEE_ARB_fragment_layer_viewport = GL_TRUE; + __GLeeLink_GL_ARB_fragment_layer_viewport(); + } + if (__GLeeCheckExtension("GL_ARB_framebuffer_no_attachments", &extensionNames) ) + { + _GLEE_ARB_framebuffer_no_attachments = GL_TRUE; + __GLeeLink_GL_ARB_framebuffer_no_attachments(); + } + if (__GLeeCheckExtension("GL_ARB_internalformat_query2", &extensionNames) ) + { + _GLEE_ARB_internalformat_query2 = GL_TRUE; + __GLeeLink_GL_ARB_internalformat_query2(); + } + if (__GLeeCheckExtension("GL_ARB_invalidate_subdata", &extensionNames) ) + { + _GLEE_ARB_invalidate_subdata = GL_TRUE; + __GLeeLink_GL_ARB_invalidate_subdata(); + } + if (__GLeeCheckExtension("GL_ARB_multi_draw_indirect", &extensionNames) ) + { + _GLEE_ARB_multi_draw_indirect = GL_TRUE; + __GLeeLink_GL_ARB_multi_draw_indirect(); + } + if (__GLeeCheckExtension("GL_ARB_program_interface_query", &extensionNames) ) + { + _GLEE_ARB_program_interface_query = GL_TRUE; + __GLeeLink_GL_ARB_program_interface_query(); + } + if (__GLeeCheckExtension("GL_ARB_robust_buffer_access_behavior", &extensionNames) ) + { + _GLEE_ARB_robust_buffer_access_behavior = GL_TRUE; + __GLeeLink_GL_ARB_robust_buffer_access_behavior(); + } + if (__GLeeCheckExtension("GL_ARB_shader_image_size", &extensionNames) ) + { + _GLEE_ARB_shader_image_size = GL_TRUE; + __GLeeLink_GL_ARB_shader_image_size(); + } + if (__GLeeCheckExtension("GL_ARB_shader_storage_buffer_object", &extensionNames) ) + { + _GLEE_ARB_shader_storage_buffer_object = GL_TRUE; + __GLeeLink_GL_ARB_shader_storage_buffer_object(); + } + if (__GLeeCheckExtension("GL_ARB_stencil_texturing", &extensionNames) ) + { + _GLEE_ARB_stencil_texturing = GL_TRUE; + __GLeeLink_GL_ARB_stencil_texturing(); + } + if (__GLeeCheckExtension("GL_ARB_texture_buffer_range", &extensionNames) ) + { + _GLEE_ARB_texture_buffer_range = GL_TRUE; + __GLeeLink_GL_ARB_texture_buffer_range(); + } + if (__GLeeCheckExtension("GL_ARB_texture_query_levels", &extensionNames) ) + { + _GLEE_ARB_texture_query_levels = GL_TRUE; + __GLeeLink_GL_ARB_texture_query_levels(); + } + if (__GLeeCheckExtension("GL_ARB_texture_storage_multisample", &extensionNames) ) + { + _GLEE_ARB_texture_storage_multisample = GL_TRUE; + __GLeeLink_GL_ARB_texture_storage_multisample(); + } if (__GLeeCheckExtension("GL_EXT_abgr", &extensionNames) ) { _GLEE_EXT_abgr = GL_TRUE; @@ -22050,11 +24359,36 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_ATI_vertex_attrib_array_object = GL_TRUE; __GLeeLink_GL_ATI_vertex_attrib_array_object(); } + if (__GLeeCheckExtension("GL_OES_byte_coordinates", &extensionNames) ) + { + _GLEE_OES_byte_coordinates = GL_TRUE; + __GLeeLink_GL_OES_byte_coordinates(); + } + if (__GLeeCheckExtension("GL_OES_fixed_point", &extensionNames) ) + { + _GLEE_OES_fixed_point = GL_TRUE; + __GLeeLink_GL_OES_fixed_point(); + } + if (__GLeeCheckExtension("GL_OES_single_precision", &extensionNames) ) + { + _GLEE_OES_single_precision = GL_TRUE; + __GLeeLink_GL_OES_single_precision(); + } + if (__GLeeCheckExtension("GL_OES_compressed_paletted_texture", &extensionNames) ) + { + _GLEE_OES_compressed_paletted_texture = GL_TRUE; + __GLeeLink_GL_OES_compressed_paletted_texture(); + } if (__GLeeCheckExtension("GL_OES_read_format", &extensionNames) ) { _GLEE_OES_read_format = GL_TRUE; __GLeeLink_GL_OES_read_format(); } + if (__GLeeCheckExtension("GL_OES_query_matrix", &extensionNames) ) + { + _GLEE_OES_query_matrix = GL_TRUE; + __GLeeLink_GL_OES_query_matrix(); + } if (__GLeeCheckExtension("GL_EXT_depth_bounds_test", &extensionNames) ) { _GLEE_EXT_depth_bounds_test = GL_TRUE; @@ -22455,6 +24789,11 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_AMD_name_gen_delete = GL_TRUE; __GLeeLink_GL_AMD_name_gen_delete(); } + if (__GLeeCheckExtension("GL_AMD_debug_output", &extensionNames) ) + { + _GLEE_AMD_debug_output = GL_TRUE; + __GLeeLink_GL_AMD_debug_output(); + } if (__GLeeCheckExtension("GL_AMD_transform_feedback3_lines_triangles", &extensionNames) ) { _GLEE_AMD_transform_feedback3_lines_triangles = GL_TRUE; @@ -22500,6 +24839,91 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_EXT_framebuffer_multisample_blit_scaled = GL_TRUE; __GLeeLink_GL_EXT_framebuffer_multisample_blit_scaled(); } + if (__GLeeCheckExtension("GL_NV_path_rendering", &extensionNames) ) + { + _GLEE_NV_path_rendering = GL_TRUE; + __GLeeLink_GL_NV_path_rendering(); + } + if (__GLeeCheckExtension("GL_AMD_pinned_memory", &extensionNames) ) + { + _GLEE_AMD_pinned_memory = GL_TRUE; + __GLeeLink_GL_AMD_pinned_memory(); + } + if (__GLeeCheckExtension("GL_AMD_stencil_operation_extended", &extensionNames) ) + { + _GLEE_AMD_stencil_operation_extended = GL_TRUE; + __GLeeLink_GL_AMD_stencil_operation_extended(); + } + if (__GLeeCheckExtension("GL_AMD_vertex_shader_viewport_index", &extensionNames) ) + { + _GLEE_AMD_vertex_shader_viewport_index = GL_TRUE; + __GLeeLink_GL_AMD_vertex_shader_viewport_index(); + } + if (__GLeeCheckExtension("GL_AMD_vertex_shader_layer", &extensionNames) ) + { + _GLEE_AMD_vertex_shader_layer = GL_TRUE; + __GLeeLink_GL_AMD_vertex_shader_layer(); + } + if (__GLeeCheckExtension("GL_NV_bindless_texture", &extensionNames) ) + { + _GLEE_NV_bindless_texture = GL_TRUE; + __GLeeLink_GL_NV_bindless_texture(); + } + if (__GLeeCheckExtension("GL_NV_shader_atomic_float", &extensionNames) ) + { + _GLEE_NV_shader_atomic_float = GL_TRUE; + __GLeeLink_GL_NV_shader_atomic_float(); + } + if (__GLeeCheckExtension("GL_AMD_query_buffer_object", &extensionNames) ) + { + _GLEE_AMD_query_buffer_object = GL_TRUE; + __GLeeLink_GL_AMD_query_buffer_object(); + } + if (__GLeeCheckExtension("GL_NV_compute_program5", &extensionNames) ) + { + _GLEE_NV_compute_program5 = GL_TRUE; + __GLeeLink_GL_NV_compute_program5(); + } + if (__GLeeCheckExtension("GL_NV_shader_storage_buffer_object", &extensionNames) ) + { + _GLEE_NV_shader_storage_buffer_object = GL_TRUE; + __GLeeLink_GL_NV_shader_storage_buffer_object(); + } + if (__GLeeCheckExtension("GL_NV_shader_atomic_counters", &extensionNames) ) + { + _GLEE_NV_shader_atomic_counters = GL_TRUE; + __GLeeLink_GL_NV_shader_atomic_counters(); + } + if (__GLeeCheckExtension("GL_NV_deep_texture3D", &extensionNames) ) + { + _GLEE_NV_deep_texture3D = GL_TRUE; + __GLeeLink_GL_NV_deep_texture3D(); + } + if (__GLeeCheckExtension("GL_NVX_conditional_render", &extensionNames) ) + { + _GLEE_NVX_conditional_render = GL_TRUE; + __GLeeLink_GL_NVX_conditional_render(); + } + if (__GLeeCheckExtension("GL_AMD_sparse_texture", &extensionNames) ) + { + _GLEE_AMD_sparse_texture = GL_TRUE; + __GLeeLink_GL_AMD_sparse_texture(); + } + if (__GLeeCheckExtension("GL_AMD_shader_trinary_minmax", &extensionNames) ) + { + _GLEE_AMD_shader_trinary_minmax = GL_TRUE; + __GLeeLink_GL_AMD_shader_trinary_minmax(); + } + if (__GLeeCheckExtension("GL_INTEL_map_texture", &extensionNames) ) + { + _GLEE_INTEL_map_texture = GL_TRUE; + __GLeeLink_GL_INTEL_map_texture(); + } + if (__GLeeCheckExtension("GL_NV_draw_texture", &extensionNames) ) + { + _GLEE_NV_draw_texture = GL_TRUE; + __GLeeLink_GL_NV_draw_texture(); + } if (__GLeeCheckExtension("GL_SGIX_texture_select", &extensionNames) ) { _GLEE_SGIX_texture_select = GL_TRUE; @@ -22520,86 +24944,6 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_SGIX_igloo_interface = GL_TRUE; __GLeeLink_GL_SGIX_igloo_interface(); } - if (__GLeeCheckExtension("GL_OES_compressed_paletted_texture", &extensionNames) ) - { - _GLEE_OES_compressed_paletted_texture = GL_TRUE; - __GLeeLink_GL_OES_compressed_paletted_texture(); - } - if (__GLeeCheckExtension("GL_OES_fixed_point", &extensionNames) ) - { - _GLEE_OES_fixed_point = GL_TRUE; - __GLeeLink_GL_OES_fixed_point(); - } - if (__GLeeCheckExtension("GL_OES_single_precision", &extensionNames) ) - { - _GLEE_OES_single_precision = GL_TRUE; - __GLeeLink_GL_OES_single_precision(); - } - if (__GLeeCheckExtension("GL_OES_query_matrix", &extensionNames) ) - { - _GLEE_OES_query_matrix = GL_TRUE; - __GLeeLink_GL_OES_query_matrix(); - } - if (__GLeeCheckExtension("GL_OES_byte_coordinates", &extensionNames) ) - { - _GLEE_OES_byte_coordinates = GL_TRUE; - __GLeeLink_GL_OES_byte_coordinates(); - } - if (__GLeeCheckExtension("GL_NV_gpu_program4", &extensionNames) ) - { - _GLEE_NV_gpu_program4 = GL_TRUE; - __GLeeLink_GL_NV_gpu_program4(); - } - if (__GLeeCheckExtension("GL_NV_path_rendering", &extensionNames) ) - { - _GLEE_NV_path_rendering = GL_TRUE; - __GLeeLink_GL_NV_path_rendering(); - } - if (__GLeeCheckExtension("GL_AMD_vertex_shader_tessellator", &extensionNames) ) - { - _GLEE_AMD_vertex_shader_tessellator = GL_TRUE; - __GLeeLink_GL_AMD_vertex_shader_tessellator(); - } - if (__GLeeCheckExtension("GL_EXT_fragment_lighting", &extensionNames) ) - { - _GLEE_EXT_fragment_lighting = GL_TRUE; - __GLeeLink_GL_EXT_fragment_lighting(); - } - if (__GLeeCheckExtension("GL_EXT_texture_compression_dxt1", &extensionNames) ) - { - _GLEE_EXT_texture_compression_dxt1 = GL_TRUE; - __GLeeLink_GL_EXT_texture_compression_dxt1(); - } - if (__GLeeCheckExtension("GL_EXT_scene_marker", &extensionNames) ) - { - _GLEE_EXT_scene_marker = GL_TRUE; - __GLeeLink_GL_EXT_scene_marker(); - } - if (__GLeeCheckExtension("GL_EXT_geometry_shader4", &extensionNames) ) - { - _GLEE_EXT_geometry_shader4 = GL_TRUE; - __GLeeLink_GL_EXT_geometry_shader4(); - } - if (__GLeeCheckExtension("GL_EXT_texture_env", &extensionNames) ) - { - _GLEE_EXT_texture_env = GL_TRUE; - __GLeeLink_GL_EXT_texture_env(); - } - if (__GLeeCheckExtension("GL_SGIX_texture_range", &extensionNames) ) - { - _GLEE_SGIX_texture_range = GL_TRUE; - __GLeeLink_GL_SGIX_texture_range(); - } - if (__GLeeCheckExtension("GL_SGIX_pixel_texture_bits", &extensionNames) ) - { - _GLEE_SGIX_pixel_texture_bits = GL_TRUE; - __GLeeLink_GL_SGIX_pixel_texture_bits(); - } - if (__GLeeCheckExtension("GL_IBM_static_data", &extensionNames) ) - { - _GLEE_IBM_static_data = GL_TRUE; - __GLeeLink_GL_IBM_static_data(); - } #ifdef _WIN32 if (__GLeeCheckExtension("WGL_ARB_buffer_region", &extensionNames) ) { @@ -22791,6 +25135,16 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_WGL_NV_DX_interop = GL_TRUE; __GLeeLink_WGL_NV_DX_interop(); } + if (__GLeeCheckExtension("WGL_NV_DX_interop2", &extensionNames) ) + { + _GLEE_WGL_NV_DX_interop2 = GL_TRUE; + __GLeeLink_WGL_NV_DX_interop2(); + } + if (__GLeeCheckExtension("WGL_EXT_swap_control_tear", &extensionNames) ) + { + _GLEE_WGL_EXT_swap_control_tear = GL_TRUE; + __GLeeLink_WGL_EXT_swap_control_tear(); + } if (__GLeeCheckExtension("WGL_EXT_display_color_table", &extensionNames) ) { _GLEE_WGL_EXT_display_color_table = GL_TRUE; @@ -23073,16 +25427,26 @@ GLEE_EXTERN GLboolean GLeeInit( void ) _GLEE_GLX_EXT_create_context_es2_profile = GL_TRUE; __GLeeLink_GLX_EXT_create_context_es2_profile(); } + if (__GLeeCheckExtension("GLX_EXT_create_context_es_profile", &extensionNames) ) + { + _GLEE_GLX_EXT_create_context_es_profile = GL_TRUE; + __GLeeLink_GLX_EXT_create_context_es_profile(); + } + if (__GLeeCheckExtension("GLX_EXT_swap_control_tear", &extensionNames) ) + { + _GLEE_GLX_EXT_swap_control_tear = GL_TRUE; + __GLeeLink_GLX_EXT_swap_control_tear(); + } + if (__GLeeCheckExtension("GLX_EXT_buffer_age", &extensionNames) ) + { + _GLEE_GLX_EXT_buffer_age = GL_TRUE; + __GLeeLink_GLX_EXT_buffer_age(); + } if (__GLeeCheckExtension("GLX_NV_video_output", &extensionNames) ) { _GLEE_GLX_NV_video_output = GL_TRUE; __GLeeLink_GLX_NV_video_output(); } - if (__GLeeCheckExtension("GLX_EXT_scene_marker", &extensionNames) ) - { - _GLEE_GLX_EXT_scene_marker = GL_TRUE; - __GLeeLink_GLX_EXT_scene_marker(); - } #endif /* end GLX */ __GLeeExtList_clean(&extensionNames); diff --git a/src/modules/graphics/opengl/GLee.h b/src/modules/graphics/opengl/GLee.h index 87fd352d9..35c101a6a 100644 --- a/src/modules/graphics/opengl/GLee.h +++ b/src/modules/graphics/opengl/GLee.h @@ -65,6 +65,8 @@ #define GLX_GLXEXT_PROTOTYPES #include #include + + typedef XID GLEE_GLXContextID; #endif #ifndef APIENTRY @@ -106,6 +108,7 @@ GLEE_EXTERN GLboolean _GLEE_VERSION_3_3; GLEE_EXTERN GLboolean _GLEE_VERSION_4_0; GLEE_EXTERN GLboolean _GLEE_VERSION_4_1; GLEE_EXTERN GLboolean _GLEE_VERSION_4_2; +GLEE_EXTERN GLboolean _GLEE_VERSION_4_3; GLEE_EXTERN GLboolean _GLEE_ARB_multitexture; GLEE_EXTERN GLboolean _GLEE_ARB_transpose_matrix; GLEE_EXTERN GLboolean _GLEE_ARB_multisample; @@ -196,6 +199,7 @@ GLEE_EXTERN GLboolean _GLEE_ARB_shader_precision; GLEE_EXTERN GLboolean _GLEE_ARB_vertex_attrib_64bit; GLEE_EXTERN GLboolean _GLEE_ARB_viewport_array; GLEE_EXTERN GLboolean _GLEE_ARB_cl_event; +GLEE_EXTERN GLboolean _GLEE_ARB_debug_output; GLEE_EXTERN GLboolean _GLEE_ARB_robustness; GLEE_EXTERN GLboolean _GLEE_ARB_shader_stencil_export; GLEE_EXTERN GLboolean _GLEE_ARB_base_instance; @@ -209,6 +213,30 @@ GLEE_EXTERN GLboolean _GLEE_ARB_shader_atomic_counters; GLEE_EXTERN GLboolean _GLEE_ARB_shader_image_load_store; GLEE_EXTERN GLboolean _GLEE_ARB_shading_language_packing; GLEE_EXTERN GLboolean _GLEE_ARB_texture_storage; +GLEE_EXTERN GLboolean _GLEE_KHR_texture_compression_astc_ldr; +GLEE_EXTERN GLboolean _GLEE_KHR_debug; +GLEE_EXTERN GLboolean _GLEE_ARB_arrays_of_arrays; +GLEE_EXTERN GLboolean _GLEE_ARB_clear_buffer_object; +GLEE_EXTERN GLboolean _GLEE_ARB_compute_shader; +GLEE_EXTERN GLboolean _GLEE_ARB_copy_image; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_view; +GLEE_EXTERN GLboolean _GLEE_ARB_vertex_attrib_binding; +GLEE_EXTERN GLboolean _GLEE_ARB_robustness_isolation; +GLEE_EXTERN GLboolean _GLEE_ARB_ES3_compatibility; +GLEE_EXTERN GLboolean _GLEE_ARB_explicit_uniform_location; +GLEE_EXTERN GLboolean _GLEE_ARB_fragment_layer_viewport; +GLEE_EXTERN GLboolean _GLEE_ARB_framebuffer_no_attachments; +GLEE_EXTERN GLboolean _GLEE_ARB_internalformat_query2; +GLEE_EXTERN GLboolean _GLEE_ARB_invalidate_subdata; +GLEE_EXTERN GLboolean _GLEE_ARB_multi_draw_indirect; +GLEE_EXTERN GLboolean _GLEE_ARB_program_interface_query; +GLEE_EXTERN GLboolean _GLEE_ARB_robust_buffer_access_behavior; +GLEE_EXTERN GLboolean _GLEE_ARB_shader_image_size; +GLEE_EXTERN GLboolean _GLEE_ARB_shader_storage_buffer_object; +GLEE_EXTERN GLboolean _GLEE_ARB_stencil_texturing; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_buffer_range; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_query_levels; +GLEE_EXTERN GLboolean _GLEE_ARB_texture_storage_multisample; GLEE_EXTERN GLboolean _GLEE_EXT_abgr; GLEE_EXTERN GLboolean _GLEE_EXT_blend_color; GLEE_EXTERN GLboolean _GLEE_EXT_polygon_offset; @@ -412,7 +440,12 @@ GLEE_EXTERN GLboolean _GLEE_NV_vertex_program2; GLEE_EXTERN GLboolean _GLEE_ATI_map_object_buffer; GLEE_EXTERN GLboolean _GLEE_ATI_separate_stencil; GLEE_EXTERN GLboolean _GLEE_ATI_vertex_attrib_array_object; +GLEE_EXTERN GLboolean _GLEE_OES_byte_coordinates; +GLEE_EXTERN GLboolean _GLEE_OES_fixed_point; +GLEE_EXTERN GLboolean _GLEE_OES_single_precision; +GLEE_EXTERN GLboolean _GLEE_OES_compressed_paletted_texture; GLEE_EXTERN GLboolean _GLEE_OES_read_format; +GLEE_EXTERN GLboolean _GLEE_OES_query_matrix; GLEE_EXTERN GLboolean _GLEE_EXT_depth_bounds_test; GLEE_EXTERN GLboolean _GLEE_EXT_texture_mirror_clamp; GLEE_EXTERN GLboolean _GLEE_EXT_blend_equation_separate; @@ -493,6 +526,7 @@ GLEE_EXTERN GLboolean _GLEE_NV_tessellation_program5; GLEE_EXTERN GLboolean _GLEE_NV_vertex_attrib_integer_64bit; GLEE_EXTERN GLboolean _GLEE_NV_multisample_coverage; GLEE_EXTERN GLboolean _GLEE_AMD_name_gen_delete; +GLEE_EXTERN GLboolean _GLEE_AMD_debug_output; GLEE_EXTERN GLboolean _GLEE_AMD_transform_feedback3_lines_triangles; GLEE_EXTERN GLboolean _GLEE_AMD_depth_clamp_separate; GLEE_EXTERN GLboolean _GLEE_EXT_texture_sRGB_decode; @@ -502,26 +536,27 @@ GLEE_EXTERN GLboolean _GLEE_AMD_sample_positions; GLEE_EXTERN GLboolean _GLEE_EXT_x11_sync_object; GLEE_EXTERN GLboolean _GLEE_AMD_multi_draw_indirect; GLEE_EXTERN GLboolean _GLEE_EXT_framebuffer_multisample_blit_scaled; +GLEE_EXTERN GLboolean _GLEE_NV_path_rendering; +GLEE_EXTERN GLboolean _GLEE_AMD_pinned_memory; +GLEE_EXTERN GLboolean _GLEE_AMD_stencil_operation_extended; +GLEE_EXTERN GLboolean _GLEE_AMD_vertex_shader_viewport_index; +GLEE_EXTERN GLboolean _GLEE_AMD_vertex_shader_layer; +GLEE_EXTERN GLboolean _GLEE_NV_bindless_texture; +GLEE_EXTERN GLboolean _GLEE_NV_shader_atomic_float; +GLEE_EXTERN GLboolean _GLEE_AMD_query_buffer_object; +GLEE_EXTERN GLboolean _GLEE_NV_compute_program5; +GLEE_EXTERN GLboolean _GLEE_NV_shader_storage_buffer_object; +GLEE_EXTERN GLboolean _GLEE_NV_shader_atomic_counters; +GLEE_EXTERN GLboolean _GLEE_NV_deep_texture3D; +GLEE_EXTERN GLboolean _GLEE_NVX_conditional_render; +GLEE_EXTERN GLboolean _GLEE_AMD_sparse_texture; +GLEE_EXTERN GLboolean _GLEE_AMD_shader_trinary_minmax; +GLEE_EXTERN GLboolean _GLEE_INTEL_map_texture; +GLEE_EXTERN GLboolean _GLEE_NV_draw_texture; GLEE_EXTERN GLboolean _GLEE_SGIX_texture_select; GLEE_EXTERN GLboolean _GLEE_INGR_blend_func_separate; GLEE_EXTERN GLboolean _GLEE_SGIX_depth_pass_instrument; GLEE_EXTERN GLboolean _GLEE_SGIX_igloo_interface; -GLEE_EXTERN GLboolean _GLEE_OES_compressed_paletted_texture; -GLEE_EXTERN GLboolean _GLEE_OES_fixed_point; -GLEE_EXTERN GLboolean _GLEE_OES_single_precision; -GLEE_EXTERN GLboolean _GLEE_OES_query_matrix; -GLEE_EXTERN GLboolean _GLEE_OES_byte_coordinates; -GLEE_EXTERN GLboolean _GLEE_NV_gpu_program4; -GLEE_EXTERN GLboolean _GLEE_NV_path_rendering; -GLEE_EXTERN GLboolean _GLEE_AMD_vertex_shader_tessellator; -GLEE_EXTERN GLboolean _GLEE_EXT_fragment_lighting; -GLEE_EXTERN GLboolean _GLEE_EXT_texture_compression_dxt1; -GLEE_EXTERN GLboolean _GLEE_EXT_scene_marker; -GLEE_EXTERN GLboolean _GLEE_EXT_geometry_shader4; -GLEE_EXTERN GLboolean _GLEE_EXT_texture_env; -GLEE_EXTERN GLboolean _GLEE_SGIX_texture_range; -GLEE_EXTERN GLboolean _GLEE_SGIX_pixel_texture_bits; -GLEE_EXTERN GLboolean _GLEE_IBM_static_data; /* Aliases for extension querying variables */ @@ -539,6 +574,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GLEE_VERSION_4_0 GLeeEnabled(&_GLEE_VERSION_4_0) #define GLEE_VERSION_4_1 GLeeEnabled(&_GLEE_VERSION_4_1) #define GLEE_VERSION_4_2 GLeeEnabled(&_GLEE_VERSION_4_2) +#define GLEE_VERSION_4_3 GLeeEnabled(&_GLEE_VERSION_4_3) #define GLEE_ARB_multitexture GLeeEnabled(&_GLEE_ARB_multitexture) #define GLEE_ARB_transpose_matrix GLeeEnabled(&_GLEE_ARB_transpose_matrix) #define GLEE_ARB_multisample GLeeEnabled(&_GLEE_ARB_multisample) @@ -629,6 +665,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GLEE_ARB_vertex_attrib_64bit GLeeEnabled(&_GLEE_ARB_vertex_attrib_64bit) #define GLEE_ARB_viewport_array GLeeEnabled(&_GLEE_ARB_viewport_array) #define GLEE_ARB_cl_event GLeeEnabled(&_GLEE_ARB_cl_event) +#define GLEE_ARB_debug_output GLeeEnabled(&_GLEE_ARB_debug_output) #define GLEE_ARB_robustness GLeeEnabled(&_GLEE_ARB_robustness) #define GLEE_ARB_shader_stencil_export GLeeEnabled(&_GLEE_ARB_shader_stencil_export) #define GLEE_ARB_base_instance GLeeEnabled(&_GLEE_ARB_base_instance) @@ -642,6 +679,30 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GLEE_ARB_shader_image_load_store GLeeEnabled(&_GLEE_ARB_shader_image_load_store) #define GLEE_ARB_shading_language_packing GLeeEnabled(&_GLEE_ARB_shading_language_packing) #define GLEE_ARB_texture_storage GLeeEnabled(&_GLEE_ARB_texture_storage) +#define GLEE_KHR_texture_compression_astc_ldr GLeeEnabled(&_GLEE_KHR_texture_compression_astc_ldr) +#define GLEE_KHR_debug GLeeEnabled(&_GLEE_KHR_debug) +#define GLEE_ARB_arrays_of_arrays GLeeEnabled(&_GLEE_ARB_arrays_of_arrays) +#define GLEE_ARB_clear_buffer_object GLeeEnabled(&_GLEE_ARB_clear_buffer_object) +#define GLEE_ARB_compute_shader GLeeEnabled(&_GLEE_ARB_compute_shader) +#define GLEE_ARB_copy_image GLeeEnabled(&_GLEE_ARB_copy_image) +#define GLEE_ARB_texture_view GLeeEnabled(&_GLEE_ARB_texture_view) +#define GLEE_ARB_vertex_attrib_binding GLeeEnabled(&_GLEE_ARB_vertex_attrib_binding) +#define GLEE_ARB_robustness_isolation GLeeEnabled(&_GLEE_ARB_robustness_isolation) +#define GLEE_ARB_ES3_compatibility GLeeEnabled(&_GLEE_ARB_ES3_compatibility) +#define GLEE_ARB_explicit_uniform_location GLeeEnabled(&_GLEE_ARB_explicit_uniform_location) +#define GLEE_ARB_fragment_layer_viewport GLeeEnabled(&_GLEE_ARB_fragment_layer_viewport) +#define GLEE_ARB_framebuffer_no_attachments GLeeEnabled(&_GLEE_ARB_framebuffer_no_attachments) +#define GLEE_ARB_internalformat_query2 GLeeEnabled(&_GLEE_ARB_internalformat_query2) +#define GLEE_ARB_invalidate_subdata GLeeEnabled(&_GLEE_ARB_invalidate_subdata) +#define GLEE_ARB_multi_draw_indirect GLeeEnabled(&_GLEE_ARB_multi_draw_indirect) +#define GLEE_ARB_program_interface_query GLeeEnabled(&_GLEE_ARB_program_interface_query) +#define GLEE_ARB_robust_buffer_access_behavior GLeeEnabled(&_GLEE_ARB_robust_buffer_access_behavior) +#define GLEE_ARB_shader_image_size GLeeEnabled(&_GLEE_ARB_shader_image_size) +#define GLEE_ARB_shader_storage_buffer_object GLeeEnabled(&_GLEE_ARB_shader_storage_buffer_object) +#define GLEE_ARB_stencil_texturing GLeeEnabled(&_GLEE_ARB_stencil_texturing) +#define GLEE_ARB_texture_buffer_range GLeeEnabled(&_GLEE_ARB_texture_buffer_range) +#define GLEE_ARB_texture_query_levels GLeeEnabled(&_GLEE_ARB_texture_query_levels) +#define GLEE_ARB_texture_storage_multisample GLeeEnabled(&_GLEE_ARB_texture_storage_multisample) #define GLEE_EXT_abgr GLeeEnabled(&_GLEE_EXT_abgr) #define GLEE_EXT_blend_color GLeeEnabled(&_GLEE_EXT_blend_color) #define GLEE_EXT_polygon_offset GLeeEnabled(&_GLEE_EXT_polygon_offset) @@ -845,7 +906,12 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GLEE_ATI_map_object_buffer GLeeEnabled(&_GLEE_ATI_map_object_buffer) #define GLEE_ATI_separate_stencil GLeeEnabled(&_GLEE_ATI_separate_stencil) #define GLEE_ATI_vertex_attrib_array_object GLeeEnabled(&_GLEE_ATI_vertex_attrib_array_object) +#define GLEE_OES_byte_coordinates GLeeEnabled(&_GLEE_OES_byte_coordinates) +#define GLEE_OES_fixed_point GLeeEnabled(&_GLEE_OES_fixed_point) +#define GLEE_OES_single_precision GLeeEnabled(&_GLEE_OES_single_precision) +#define GLEE_OES_compressed_paletted_texture GLeeEnabled(&_GLEE_OES_compressed_paletted_texture) #define GLEE_OES_read_format GLeeEnabled(&_GLEE_OES_read_format) +#define GLEE_OES_query_matrix GLeeEnabled(&_GLEE_OES_query_matrix) #define GLEE_EXT_depth_bounds_test GLeeEnabled(&_GLEE_EXT_depth_bounds_test) #define GLEE_EXT_texture_mirror_clamp GLeeEnabled(&_GLEE_EXT_texture_mirror_clamp) #define GLEE_EXT_blend_equation_separate GLeeEnabled(&_GLEE_EXT_blend_equation_separate) @@ -926,6 +992,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GLEE_NV_vertex_attrib_integer_64bit GLeeEnabled(&_GLEE_NV_vertex_attrib_integer_64bit) #define GLEE_NV_multisample_coverage GLeeEnabled(&_GLEE_NV_multisample_coverage) #define GLEE_AMD_name_gen_delete GLeeEnabled(&_GLEE_AMD_name_gen_delete) +#define GLEE_AMD_debug_output GLeeEnabled(&_GLEE_AMD_debug_output) #define GLEE_AMD_transform_feedback3_lines_triangles GLeeEnabled(&_GLEE_AMD_transform_feedback3_lines_triangles) #define GLEE_AMD_depth_clamp_separate GLeeEnabled(&_GLEE_AMD_depth_clamp_separate) #define GLEE_EXT_texture_sRGB_decode GLeeEnabled(&_GLEE_EXT_texture_sRGB_decode) @@ -935,26 +1002,27 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GLEE_EXT_x11_sync_object GLeeEnabled(&_GLEE_EXT_x11_sync_object) #define GLEE_AMD_multi_draw_indirect GLeeEnabled(&_GLEE_AMD_multi_draw_indirect) #define GLEE_EXT_framebuffer_multisample_blit_scaled GLeeEnabled(&_GLEE_EXT_framebuffer_multisample_blit_scaled) +#define GLEE_NV_path_rendering GLeeEnabled(&_GLEE_NV_path_rendering) +#define GLEE_AMD_pinned_memory GLeeEnabled(&_GLEE_AMD_pinned_memory) +#define GLEE_AMD_stencil_operation_extended GLeeEnabled(&_GLEE_AMD_stencil_operation_extended) +#define GLEE_AMD_vertex_shader_viewport_index GLeeEnabled(&_GLEE_AMD_vertex_shader_viewport_index) +#define GLEE_AMD_vertex_shader_layer GLeeEnabled(&_GLEE_AMD_vertex_shader_layer) +#define GLEE_NV_bindless_texture GLeeEnabled(&_GLEE_NV_bindless_texture) +#define GLEE_NV_shader_atomic_float GLeeEnabled(&_GLEE_NV_shader_atomic_float) +#define GLEE_AMD_query_buffer_object GLeeEnabled(&_GLEE_AMD_query_buffer_object) +#define GLEE_NV_compute_program5 GLeeEnabled(&_GLEE_NV_compute_program5) +#define GLEE_NV_shader_storage_buffer_object GLeeEnabled(&_GLEE_NV_shader_storage_buffer_object) +#define GLEE_NV_shader_atomic_counters GLeeEnabled(&_GLEE_NV_shader_atomic_counters) +#define GLEE_NV_deep_texture3D GLeeEnabled(&_GLEE_NV_deep_texture3D) +#define GLEE_NVX_conditional_render GLeeEnabled(&_GLEE_NVX_conditional_render) +#define GLEE_AMD_sparse_texture GLeeEnabled(&_GLEE_AMD_sparse_texture) +#define GLEE_AMD_shader_trinary_minmax GLeeEnabled(&_GLEE_AMD_shader_trinary_minmax) +#define GLEE_INTEL_map_texture GLeeEnabled(&_GLEE_INTEL_map_texture) +#define GLEE_NV_draw_texture GLeeEnabled(&_GLEE_NV_draw_texture) #define GLEE_SGIX_texture_select GLeeEnabled(&_GLEE_SGIX_texture_select) #define GLEE_INGR_blend_func_separate GLeeEnabled(&_GLEE_INGR_blend_func_separate) #define GLEE_SGIX_depth_pass_instrument GLeeEnabled(&_GLEE_SGIX_depth_pass_instrument) #define GLEE_SGIX_igloo_interface GLeeEnabled(&_GLEE_SGIX_igloo_interface) -#define GLEE_OES_compressed_paletted_texture GLeeEnabled(&_GLEE_OES_compressed_paletted_texture) -#define GLEE_OES_fixed_point GLeeEnabled(&_GLEE_OES_fixed_point) -#define GLEE_OES_single_precision GLeeEnabled(&_GLEE_OES_single_precision) -#define GLEE_OES_query_matrix GLeeEnabled(&_GLEE_OES_query_matrix) -#define GLEE_OES_byte_coordinates GLeeEnabled(&_GLEE_OES_byte_coordinates) -#define GLEE_NV_gpu_program4 GLeeEnabled(&_GLEE_NV_gpu_program4) -#define GLEE_NV_path_rendering GLeeEnabled(&_GLEE_NV_path_rendering) -#define GLEE_AMD_vertex_shader_tessellator GLeeEnabled(&_GLEE_AMD_vertex_shader_tessellator) -#define GLEE_EXT_fragment_lighting GLeeEnabled(&_GLEE_EXT_fragment_lighting) -#define GLEE_EXT_texture_compression_dxt1 GLeeEnabled(&_GLEE_EXT_texture_compression_dxt1) -#define GLEE_EXT_scene_marker GLeeEnabled(&_GLEE_EXT_scene_marker) -#define GLEE_EXT_geometry_shader4 GLeeEnabled(&_GLEE_EXT_geometry_shader4) -#define GLEE_EXT_texture_env GLeeEnabled(&_GLEE_EXT_texture_env) -#define GLEE_SGIX_texture_range GLeeEnabled(&_GLEE_SGIX_texture_range) -#define GLEE_SGIX_pixel_texture_bits GLeeEnabled(&_GLEE_SGIX_pixel_texture_bits) -#define GLEE_IBM_static_data GLeeEnabled(&_GLEE_IBM_static_data) /***************************************************************** @@ -990,12 +1058,22 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GL_ARB_vertex_buffer_object + /* awful hack to work around issue with GLee and Mac OS 10.9's gltypes.h */ +#if defined(__APPLE__) + typedef long GLintptrARB; + typedef long GLsizeiptrARB; +#else typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #endif +#endif #ifndef GL_ARB_shader_objects +#if defined(__APPLE__) + typedef void *GLhandleARB; +#else typedef int GLhandleARB; +#endif typedef char GLcharARB; #endif @@ -1010,6 +1088,33 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; typedef struct __GLsync *GLsync; #endif +#ifndef GL_ARB_cl_event + /* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */ + struct _cl_context; + struct _cl_event; +#endif + +#ifndef GL_ARB_debug_output + typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_AMD_debug_output + typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_KHR_debug + typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_NV_vdpau_interop + typedef GLintptr GLvdpauSurfaceNV; +#endif + +#ifndef GL_OES_fixed_point + /* GLint must be 32 bits, a relatively safe assumption on modern CPUs */ + typedef GLint GLfixed; +#endif + /* Platform-specific */ #ifdef _WIN32 @@ -1044,6 +1149,10 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; RECT rcVirtualScreen; } GPU_DEVICE, *PGPU_DEVICE; #endif + + #ifndef WGL_NV_video_capture + DECLARE_HANDLE(HVIDEOINPUTDEVICENV); + #endif #elif defined(__APPLE__) || defined(__APPLE_CC__) @@ -1184,7 +1293,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #ifndef GLEE_H_DEFINED_glBlendColor #define GLEE_H_DEFINED_glBlendColor - typedef void (APIENTRYP GLEEPFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + typedef void (APIENTRYP GLEEPFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); GLEE_EXTERN GLEEPFNGLBLENDCOLORPROC GLeeFuncPtr_glBlendColor; #define glBlendColor GLeeFuncPtr_glBlendColor #endif @@ -1605,7 +1714,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glSampleCoverage #define GLEE_H_DEFINED_glSampleCoverage - typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); GLEE_EXTERN GLEEPFNGLSAMPLECOVERAGEPROC GLeeFuncPtr_glSampleCoverage; #define glSampleCoverage GLeeFuncPtr_glSampleCoverage #endif @@ -1928,13 +2037,13 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glMultiDrawArrays #define GLEE_H_DEFINED_glMultiDrawArrays - typedef void (APIENTRYP GLEEPFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount); + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount); GLEE_EXTERN GLEEPFNGLMULTIDRAWARRAYSPROC GLeeFuncPtr_glMultiDrawArrays; #define glMultiDrawArrays GLeeFuncPtr_glMultiDrawArrays #endif #ifndef GLEE_H_DEFINED_glMultiDrawElements #define GLEE_H_DEFINED_glMultiDrawElements - typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount); + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei * count, GLenum type, const GLvoid* const * indices, GLsizei drawcount); GLEE_EXTERN GLEEPFNGLMULTIDRAWELEMENTSPROC GLeeFuncPtr_glMultiDrawElements; #define glMultiDrawElements GLeeFuncPtr_glMultiDrawElements #endif @@ -2225,6 +2334,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 @@ -2246,7 +2356,6 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_SRC1_RGB 0x8581 #define GL_SRC2_RGB 0x8582 #define GL_SRC0_ALPHA 0x8588 -#define GL_SRC1_ALPHA 0x8589 #define GL_SRC2_ALPHA 0x858A #ifndef GLEE_H_DEFINED_glGenQueries #define GLEE_H_DEFINED_glGenQueries @@ -2660,7 +2769,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glShaderSource #define GLEE_H_DEFINED_glShaderSource - typedef void (APIENTRYP GLEEPFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* * string, const GLint * length); + typedef void (APIENTRYP GLEEPFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const * string, const GLint * length); GLEE_EXTERN GLEEPFNGLSHADERSOURCEPROC GLeeFuncPtr_glShaderSource; #define glShaderSource GLeeFuncPtr_glShaderSource #endif @@ -3252,7 +3361,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glTransformFeedbackVaryings #define GLEE_H_DEFINED_glTransformFeedbackVaryings - typedef void (APIENTRYP GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* * varyings, GLenum bufferMode); + typedef void (APIENTRYP GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* const * varyings, GLenum bufferMode); GLEE_EXTERN GLEEPFNGLTRANSFORMFEEDBACKVARYINGSPROC GLeeFuncPtr_glTransformFeedbackVaryings; #define glTransformFeedbackVaryings GLeeFuncPtr_glTransformFeedbackVaryings #endif @@ -3557,7 +3666,6 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B #define GL_TEXTURE_BINDING_BUFFER 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E #define GL_TEXTURE_RECTANGLE 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 @@ -3579,13 +3687,13 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E #ifndef GLEE_H_DEFINED_glDrawArraysInstanced #define GLEE_H_DEFINED_glDrawArraysInstanced - typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); + typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); GLEE_EXTERN GLEEPFNGLDRAWARRAYSINSTANCEDPROC GLeeFuncPtr_glDrawArraysInstanced; #define glDrawArraysInstanced GLeeFuncPtr_glDrawArraysInstanced #endif #ifndef GLEE_H_DEFINED_glDrawElementsInstanced #define GLEE_H_DEFINED_glDrawElementsInstanced - typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount); + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei instancecount); GLEE_EXTERN GLEEPFNGLDRAWELEMENTSINSTANCEDPROC GLeeFuncPtr_glDrawElementsInstanced; #define glDrawElementsInstanced GLeeFuncPtr_glDrawElementsInstanced #endif @@ -3685,7 +3793,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F #ifndef GLEE_H_DEFINED_glMinSampleShading #define GLEE_H_DEFINED_glMinSampleShading - typedef void (APIENTRYP GLEEPFNGLMINSAMPLESHADINGPROC) (GLclampf value); + typedef void (APIENTRYP GLEEPFNGLMINSAMPLESHADINGPROC) (GLfloat value); GLEE_EXTERN GLEEPFNGLMINSAMPLESHADINGPROC GLeeFuncPtr_glMinSampleShading; #define glMinSampleShading GLeeFuncPtr_glMinSampleShading #endif @@ -3731,6 +3839,16 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; /* Constants */ #endif +/* GL_VERSION_4_3 */ + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 +#define __GLEE_GL_VERSION_4_3 1 +/* Constants */ +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#endif + /* GL_ARB_multitexture */ #ifndef GL_ARB_multitexture @@ -4031,7 +4149,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_MULTISAMPLE_BIT_ARB 0x20000000 #ifndef GLEE_H_DEFINED_glSampleCoverageARB #define GLEE_H_DEFINED_glSampleCoverageARB - typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); GLEE_EXTERN GLEEPFNGLSAMPLECOVERAGEARBPROC GLeeFuncPtr_glSampleCoverageARB; #define glSampleCoverageARB GLeeFuncPtr_glSampleCoverageARB #endif @@ -6108,7 +6226,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_INVALID_INDEX 0xFFFFFFFFu #ifndef GLEE_H_DEFINED_glGetUniformIndices #define GLEE_H_DEFINED_glGetUniformIndices - typedef void (APIENTRYP GLEEPFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* * uniformNames, GLuint * uniformIndices); + typedef void (APIENTRYP GLEEPFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const * uniformNames, GLuint * uniformIndices); GLEE_EXTERN GLEEPFNGLGETUNIFORMINDICESPROC GLeeFuncPtr_glGetUniformIndices; #define glGetUniformIndices GLeeFuncPtr_glGetUniformIndices #endif @@ -6164,8 +6282,10 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_ARB_copy_buffer 1 #define __GLEE_GL_ARB_copy_buffer 1 /* Constants */ -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER_BINDING +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER_BINDING #ifndef GLEE_H_DEFINED_glCopyBufferSubData #define GLEE_H_DEFINED_glCopyBufferSubData typedef void (APIENTRYP GLEEPFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); @@ -6211,13 +6331,13 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glDrawElementsInstancedBaseVertex #define GLEE_H_DEFINED_glDrawElementsInstancedBaseVertex - typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei primcount, GLint basevertex); + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei instancecount, GLint basevertex); GLEE_EXTERN GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC GLeeFuncPtr_glDrawElementsInstancedBaseVertex; #define glDrawElementsInstancedBaseVertex GLeeFuncPtr_glDrawElementsInstancedBaseVertex #endif #ifndef GLEE_H_DEFINED_glMultiDrawElementsBaseVertex #define GLEE_H_DEFINED_glMultiDrawElementsBaseVertex - typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei * count, GLenum type, const GLvoid* * indices, GLsizei primcount, const GLint * basevertex); + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei * count, GLenum type, const GLvoid* const * indices, GLsizei drawcount, const GLint * basevertex); GLEE_EXTERN GLEEPFNGLMULTIDRAWELEMENTSBASEVERTEXPROC GLeeFuncPtr_glMultiDrawElementsBaseVertex; #define glMultiDrawElementsBaseVertex GLeeFuncPtr_glMultiDrawElementsBaseVertex #endif @@ -6426,7 +6546,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 #ifndef GLEE_H_DEFINED_glMinSampleShadingARB #define GLEE_H_DEFINED_glMinSampleShadingARB - typedef void (APIENTRYP GLEEPFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); + typedef void (APIENTRYP GLEEPFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); GLEE_EXTERN GLEEPFNGLMINSAMPLESHADINGARBPROC GLeeFuncPtr_glMinSampleShadingARB; #define glMinSampleShadingARB GLeeFuncPtr_glMinSampleShadingARB #endif @@ -6455,6 +6575,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; /* Constants */ #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F #endif /* GL_ARB_texture_query_lod */ @@ -7248,8 +7369,10 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define __GLEE_GL_ARB_transform_feedback2 1 /* Constants */ #define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED GL_TRANSFORM_FEEDBACK_PAUSED +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE GL_TRANSFORM_FEEDBACK_ACTIVE #define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 #ifndef GLEE_H_DEFINED_glBindTransformFeedback #define GLEE_H_DEFINED_glBindTransformFeedback @@ -7345,10 +7468,12 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_MEDIUM_INT 0x8DF4 #define GL_HIGH_INT 0x8DF5 #define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB #define GL_MAX_VARYING_VECTORS 0x8DFC #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_RGB565 0x8D62 #ifndef GLEE_H_DEFINED_glReleaseShaderCompiler #define GLEE_H_DEFINED_glReleaseShaderCompiler typedef void (APIENTRYP GLEEPFNGLRELEASESHADERCOMPILERPROC) (); @@ -7369,13 +7494,13 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glDepthRangef #define GLEE_H_DEFINED_glDepthRangef - typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); + typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); GLEE_EXTERN GLEEPFNGLDEPTHRANGEFPROC GLeeFuncPtr_glDepthRangef; #define glDepthRangef GLeeFuncPtr_glDepthRangef #endif #ifndef GLEE_H_DEFINED_glClearDepthf #define GLEE_H_DEFINED_glClearDepthf - typedef void (APIENTRYP GLEEPFNGLCLEARDEPTHFPROC) (GLclampf d); + typedef void (APIENTRYP GLEEPFNGLCLEARDEPTHFPROC) (GLfloat d); GLEE_EXTERN GLEEPFNGLCLEARDEPTHFPROC GLeeFuncPtr_glClearDepthf; #define glClearDepthf GLeeFuncPtr_glClearDepthf #endif @@ -7440,7 +7565,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glCreateShaderProgramv #define GLEE_H_DEFINED_glCreateShaderProgramv - typedef GLuint (APIENTRYP GLEEPFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* * strings); + typedef GLuint (APIENTRYP GLEEPFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* const * strings); GLEE_EXTERN GLEEPFNGLCREATESHADERPROGRAMVPROC GLeeFuncPtr_glCreateShaderProgramv; #define glCreateShaderProgramv GLeeFuncPtr_glCreateShaderProgramv #endif @@ -7914,13 +8039,13 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glDepthRangeArrayv #define GLEE_H_DEFINED_glDepthRangeArrayv - typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v); + typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble * v); GLEE_EXTERN GLEEPFNGLDEPTHRANGEARRAYVPROC GLeeFuncPtr_glDepthRangeArrayv; #define glDepthRangeArrayv GLeeFuncPtr_glDepthRangeArrayv #endif #ifndef GLEE_H_DEFINED_glDepthRangeIndexed #define GLEE_H_DEFINED_glDepthRangeIndexed - typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f); + typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); GLEE_EXTERN GLEEPFNGLDEPTHRANGEINDEXEDPROC GLeeFuncPtr_glDepthRangeIndexed; #define glDepthRangeIndexed GLeeFuncPtr_glDepthRangeIndexed #endif @@ -7954,6 +8079,60 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #endif +/* GL_ARB_debug_output */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 +#define __GLEE_GL_ARB_debug_output 1 +/* Constants */ +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#ifndef GLEE_H_DEFINED_glDebugMessageControlARB +#define GLEE_H_DEFINED_glDebugMessageControlARB + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGECONTROLARBPROC GLeeFuncPtr_glDebugMessageControlARB; + #define glDebugMessageControlARB GLeeFuncPtr_glDebugMessageControlARB +#endif +#ifndef GLEE_H_DEFINED_glDebugMessageInsertARB +#define GLEE_H_DEFINED_glDebugMessageInsertARB + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGEINSERTARBPROC GLeeFuncPtr_glDebugMessageInsertARB; + #define glDebugMessageInsertARB GLeeFuncPtr_glDebugMessageInsertARB +#endif +#ifndef GLEE_H_DEFINED_glDebugMessageCallbackARB +#define GLEE_H_DEFINED_glDebugMessageCallbackARB + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid * userParam); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGECALLBACKARBPROC GLeeFuncPtr_glDebugMessageCallbackARB; + #define glDebugMessageCallbackARB GLeeFuncPtr_glDebugMessageCallbackARB +#endif +#ifndef GLEE_H_DEFINED_glGetDebugMessageLogARB +#define GLEE_H_DEFINED_glGetDebugMessageLogARB + typedef GLuint (APIENTRYP GLEEPFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); + GLEE_EXTERN GLEEPFNGLGETDEBUGMESSAGELOGARBPROC GLeeFuncPtr_glGetDebugMessageLogARB; + #define glGetDebugMessageLogARB GLeeFuncPtr_glGetDebugMessageLogARB +#endif +#endif + /* GL_ARB_robustness */ #ifndef GL_ARB_robustness @@ -8105,19 +8284,19 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; /* Constants */ #ifndef GLEE_H_DEFINED_glDrawArraysInstancedBaseInstance #define GLEE_H_DEFINED_glDrawArraysInstancedBaseInstance - typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance); + typedef void (APIENTRYP GLEEPFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); GLEE_EXTERN GLEEPFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC GLeeFuncPtr_glDrawArraysInstancedBaseInstance; #define glDrawArraysInstancedBaseInstance GLeeFuncPtr_glDrawArraysInstancedBaseInstance #endif #ifndef GLEE_H_DEFINED_glDrawElementsInstancedBaseInstance #define GLEE_H_DEFINED_glDrawElementsInstancedBaseInstance - typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount, GLuint baseinstance); + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); GLEE_EXTERN GLEEPFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC GLeeFuncPtr_glDrawElementsInstancedBaseInstance; #define glDrawElementsInstancedBaseInstance GLeeFuncPtr_glDrawElementsInstancedBaseInstance #endif #ifndef GLEE_H_DEFINED_glDrawElementsInstancedBaseVertexBaseInstance #define GLEE_H_DEFINED_glDrawElementsInstancedBaseVertexBaseInstance - typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount, GLint basevertex, GLuint baseinstance); + typedef void (APIENTRYP GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); GLEE_EXTERN GLEEPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC GLeeFuncPtr_glDrawElementsInstancedBaseVertexBaseInstance; #define glDrawElementsInstancedBaseVertexBaseInstance GLeeFuncPtr_glDrawElementsInstancedBaseVertexBaseInstance #endif @@ -8139,13 +8318,13 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; /* Constants */ #ifndef GLEE_H_DEFINED_glDrawTransformFeedbackInstanced #define GLEE_H_DEFINED_glDrawTransformFeedbackInstanced - typedef void (APIENTRYP GLEEPFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount); + typedef void (APIENTRYP GLEEPFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); GLEE_EXTERN GLEEPFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC GLeeFuncPtr_glDrawTransformFeedbackInstanced; #define glDrawTransformFeedbackInstanced GLeeFuncPtr_glDrawTransformFeedbackInstanced #endif #ifndef GLEE_H_DEFINED_glDrawTransformFeedbackStreamInstanced #define GLEE_H_DEFINED_glDrawTransformFeedbackStreamInstanced - typedef void (APIENTRYP GLEEPFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount); + typedef void (APIENTRYP GLEEPFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); GLEE_EXTERN GLEEPFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC GLeeFuncPtr_glDrawTransformFeedbackStreamInstanced; #define glDrawTransformFeedbackStreamInstanced GLeeFuncPtr_glDrawTransformFeedbackStreamInstanced #endif @@ -8379,6 +8558,819 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #endif +/* GL_KHR_texture_compression_astc_ldr */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#define __GLEE_GL_KHR_texture_compression_astc_ldr 1 +/* Constants */ +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif + +/* GL_KHR_debug */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#define __GLEE_GL_KHR_debug 1 +/* Constants */ +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_DISPLAY_LIST 0x82E7 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#ifndef GLEE_H_DEFINED_glDebugMessageControl +#define GLEE_H_DEFINED_glDebugMessageControl + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGECONTROLPROC GLeeFuncPtr_glDebugMessageControl; + #define glDebugMessageControl GLeeFuncPtr_glDebugMessageControl +#endif +#ifndef GLEE_H_DEFINED_glDebugMessageInsert +#define GLEE_H_DEFINED_glDebugMessageInsert + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGEINSERTPROC GLeeFuncPtr_glDebugMessageInsert; + #define glDebugMessageInsert GLeeFuncPtr_glDebugMessageInsert +#endif +#ifndef GLEE_H_DEFINED_glDebugMessageCallback +#define GLEE_H_DEFINED_glDebugMessageCallback + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void * userParam); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGECALLBACKPROC GLeeFuncPtr_glDebugMessageCallback; + #define glDebugMessageCallback GLeeFuncPtr_glDebugMessageCallback +#endif +#ifndef GLEE_H_DEFINED_glGetDebugMessageLog +#define GLEE_H_DEFINED_glGetDebugMessageLog + typedef GLuint (APIENTRYP GLEEPFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); + GLEE_EXTERN GLEEPFNGLGETDEBUGMESSAGELOGPROC GLeeFuncPtr_glGetDebugMessageLog; + #define glGetDebugMessageLog GLeeFuncPtr_glGetDebugMessageLog +#endif +#ifndef GLEE_H_DEFINED_glPushDebugGroup +#define GLEE_H_DEFINED_glPushDebugGroup + typedef void (APIENTRYP GLEEPFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message); + GLEE_EXTERN GLEEPFNGLPUSHDEBUGGROUPPROC GLeeFuncPtr_glPushDebugGroup; + #define glPushDebugGroup GLeeFuncPtr_glPushDebugGroup +#endif +#ifndef GLEE_H_DEFINED_glPopDebugGroup +#define GLEE_H_DEFINED_glPopDebugGroup + typedef void (APIENTRYP GLEEPFNGLPOPDEBUGGROUPPROC) (); + GLEE_EXTERN GLEEPFNGLPOPDEBUGGROUPPROC GLeeFuncPtr_glPopDebugGroup; + #define glPopDebugGroup GLeeFuncPtr_glPopDebugGroup +#endif +#ifndef GLEE_H_DEFINED_glObjectLabel +#define GLEE_H_DEFINED_glObjectLabel + typedef void (APIENTRYP GLEEPFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar * label); + GLEE_EXTERN GLEEPFNGLOBJECTLABELPROC GLeeFuncPtr_glObjectLabel; + #define glObjectLabel GLeeFuncPtr_glObjectLabel +#endif +#ifndef GLEE_H_DEFINED_glGetObjectLabel +#define GLEE_H_DEFINED_glGetObjectLabel + typedef void (APIENTRYP GLEEPFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); + GLEE_EXTERN GLEEPFNGLGETOBJECTLABELPROC GLeeFuncPtr_glGetObjectLabel; + #define glGetObjectLabel GLeeFuncPtr_glGetObjectLabel +#endif +#ifndef GLEE_H_DEFINED_glObjectPtrLabel +#define GLEE_H_DEFINED_glObjectPtrLabel + typedef void (APIENTRYP GLEEPFNGLOBJECTPTRLABELPROC) (const void * ptr, GLsizei length, const GLchar * label); + GLEE_EXTERN GLEEPFNGLOBJECTPTRLABELPROC GLeeFuncPtr_glObjectPtrLabel; + #define glObjectPtrLabel GLeeFuncPtr_glObjectPtrLabel +#endif +#ifndef GLEE_H_DEFINED_glGetObjectPtrLabel +#define GLEE_H_DEFINED_glGetObjectPtrLabel + typedef void (APIENTRYP GLEEPFNGLGETOBJECTPTRLABELPROC) (const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); + GLEE_EXTERN GLEEPFNGLGETOBJECTPTRLABELPROC GLeeFuncPtr_glGetObjectPtrLabel; + #define glGetObjectPtrLabel GLeeFuncPtr_glGetObjectPtrLabel +#endif +#endif + +/* GL_ARB_arrays_of_arrays */ + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 +#define __GLEE_GL_ARB_arrays_of_arrays 1 +/* Constants */ +#endif + +/* GL_ARB_clear_buffer_object */ + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 +#define __GLEE_GL_ARB_clear_buffer_object 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glClearBufferData +#define GLEE_H_DEFINED_glClearBufferData + typedef void (APIENTRYP GLEEPFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data); + GLEE_EXTERN GLEEPFNGLCLEARBUFFERDATAPROC GLeeFuncPtr_glClearBufferData; + #define glClearBufferData GLeeFuncPtr_glClearBufferData +#endif +#ifndef GLEE_H_DEFINED_glClearBufferSubData +#define GLEE_H_DEFINED_glClearBufferSubData + typedef void (APIENTRYP GLEEPFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); + GLEE_EXTERN GLEEPFNGLCLEARBUFFERSUBDATAPROC GLeeFuncPtr_glClearBufferSubData; + #define glClearBufferSubData GLeeFuncPtr_glClearBufferSubData +#endif +#ifndef GLEE_H_DEFINED_glClearNamedBufferDataEXT +#define GLEE_H_DEFINED_glClearNamedBufferDataEXT + typedef void (APIENTRYP GLEEPFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data); + GLEE_EXTERN GLEEPFNGLCLEARNAMEDBUFFERDATAEXTPROC GLeeFuncPtr_glClearNamedBufferDataEXT; + #define glClearNamedBufferDataEXT GLeeFuncPtr_glClearNamedBufferDataEXT +#endif +#ifndef GLEE_H_DEFINED_glClearNamedBufferSubDataEXT +#define GLEE_H_DEFINED_glClearNamedBufferSubDataEXT + typedef void (APIENTRYP GLEEPFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void * data); + GLEE_EXTERN GLEEPFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC GLeeFuncPtr_glClearNamedBufferSubDataEXT; + #define glClearNamedBufferSubDataEXT GLeeFuncPtr_glClearNamedBufferSubDataEXT +#endif +#endif + +/* GL_ARB_compute_shader */ + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 +#define __GLEE_GL_ARB_compute_shader 1 +/* Constants */ +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#ifndef GLEE_H_DEFINED_glDispatchCompute +#define GLEE_H_DEFINED_glDispatchCompute + typedef void (APIENTRYP GLEEPFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + GLEE_EXTERN GLEEPFNGLDISPATCHCOMPUTEPROC GLeeFuncPtr_glDispatchCompute; + #define glDispatchCompute GLeeFuncPtr_glDispatchCompute +#endif +#ifndef GLEE_H_DEFINED_glDispatchComputeIndirect +#define GLEE_H_DEFINED_glDispatchComputeIndirect + typedef void (APIENTRYP GLEEPFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); + GLEE_EXTERN GLEEPFNGLDISPATCHCOMPUTEINDIRECTPROC GLeeFuncPtr_glDispatchComputeIndirect; + #define glDispatchComputeIndirect GLeeFuncPtr_glDispatchComputeIndirect +#endif +#endif + +/* GL_ARB_copy_image */ + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 +#define __GLEE_GL_ARB_copy_image 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glCopyImageSubData +#define GLEE_H_DEFINED_glCopyImageSubData + typedef void (APIENTRYP GLEEPFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + GLEE_EXTERN GLEEPFNGLCOPYIMAGESUBDATAPROC GLeeFuncPtr_glCopyImageSubData; + #define glCopyImageSubData GLeeFuncPtr_glCopyImageSubData +#endif +#endif + +/* GL_ARB_texture_view */ + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 +#define __GLEE_GL_ARB_texture_view 1 +/* Constants */ +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#ifndef GLEE_H_DEFINED_glTextureView +#define GLEE_H_DEFINED_glTextureView + typedef void (APIENTRYP GLEEPFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); + GLEE_EXTERN GLEEPFNGLTEXTUREVIEWPROC GLeeFuncPtr_glTextureView; + #define glTextureView GLeeFuncPtr_glTextureView +#endif +#endif + +/* GL_ARB_vertex_attrib_binding */ + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 +#define __GLEE_GL_ARB_vertex_attrib_binding 1 +/* Constants */ +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#ifndef GLEE_H_DEFINED_glBindVertexBuffer +#define GLEE_H_DEFINED_glBindVertexBuffer + typedef void (APIENTRYP GLEEPFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + GLEE_EXTERN GLEEPFNGLBINDVERTEXBUFFERPROC GLeeFuncPtr_glBindVertexBuffer; + #define glBindVertexBuffer GLeeFuncPtr_glBindVertexBuffer +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribFormat +#define GLEE_H_DEFINED_glVertexAttribFormat + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBFORMATPROC GLeeFuncPtr_glVertexAttribFormat; + #define glVertexAttribFormat GLeeFuncPtr_glVertexAttribFormat +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribIFormat +#define GLEE_H_DEFINED_glVertexAttribIFormat + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBIFORMATPROC GLeeFuncPtr_glVertexAttribIFormat; + #define glVertexAttribIFormat GLeeFuncPtr_glVertexAttribIFormat +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribLFormat +#define GLEE_H_DEFINED_glVertexAttribLFormat + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBLFORMATPROC GLeeFuncPtr_glVertexAttribLFormat; + #define glVertexAttribLFormat GLeeFuncPtr_glVertexAttribLFormat +#endif +#ifndef GLEE_H_DEFINED_glVertexAttribBinding +#define GLEE_H_DEFINED_glVertexAttribBinding + typedef void (APIENTRYP GLEEPFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); + GLEE_EXTERN GLEEPFNGLVERTEXATTRIBBINDINGPROC GLeeFuncPtr_glVertexAttribBinding; + #define glVertexAttribBinding GLeeFuncPtr_glVertexAttribBinding +#endif +#ifndef GLEE_H_DEFINED_glVertexBindingDivisor +#define GLEE_H_DEFINED_glVertexBindingDivisor + typedef void (APIENTRYP GLEEPFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); + GLEE_EXTERN GLEEPFNGLVERTEXBINDINGDIVISORPROC GLeeFuncPtr_glVertexBindingDivisor; + #define glVertexBindingDivisor GLeeFuncPtr_glVertexBindingDivisor +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayBindVertexBufferEXT +#define GLEE_H_DEFINED_glVertexArrayBindVertexBufferEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC GLeeFuncPtr_glVertexArrayBindVertexBufferEXT; + #define glVertexArrayBindVertexBufferEXT GLeeFuncPtr_glVertexArrayBindVertexBufferEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayVertexAttribFormatEXT +#define GLEE_H_DEFINED_glVertexArrayVertexAttribFormatEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribFormatEXT; + #define glVertexArrayVertexAttribFormatEXT GLeeFuncPtr_glVertexArrayVertexAttribFormatEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayVertexAttribIFormatEXT +#define GLEE_H_DEFINED_glVertexArrayVertexAttribIFormatEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribIFormatEXT; + #define glVertexArrayVertexAttribIFormatEXT GLeeFuncPtr_glVertexArrayVertexAttribIFormatEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayVertexAttribLFormatEXT +#define GLEE_H_DEFINED_glVertexArrayVertexAttribLFormatEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribLFormatEXT; + #define glVertexArrayVertexAttribLFormatEXT GLeeFuncPtr_glVertexArrayVertexAttribLFormatEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayVertexAttribBindingEXT +#define GLEE_H_DEFINED_glVertexArrayVertexAttribBindingEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC GLeeFuncPtr_glVertexArrayVertexAttribBindingEXT; + #define glVertexArrayVertexAttribBindingEXT GLeeFuncPtr_glVertexArrayVertexAttribBindingEXT +#endif +#ifndef GLEE_H_DEFINED_glVertexArrayVertexBindingDivisorEXT +#define GLEE_H_DEFINED_glVertexArrayVertexBindingDivisorEXT + typedef void (APIENTRYP GLEEPFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); + GLEE_EXTERN GLEEPFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC GLeeFuncPtr_glVertexArrayVertexBindingDivisorEXT; + #define glVertexArrayVertexBindingDivisorEXT GLeeFuncPtr_glVertexArrayVertexBindingDivisorEXT +#endif +#endif + +/* GL_ARB_robustness_isolation */ + +#ifndef GL_ARB_robustness_isolation +#define GL_ARB_robustness_isolation 1 +#define __GLEE_GL_ARB_robustness_isolation 1 +/* Constants */ +#endif + +/* GL_ARB_ES3_compatibility */ + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 +#define __GLEE_GL_ARB_ES3_compatibility 1 +/* Constants */ +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#endif + +/* GL_ARB_explicit_uniform_location */ + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 +#define __GLEE_GL_ARB_explicit_uniform_location 1 +/* Constants */ +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#endif + +/* GL_ARB_fragment_layer_viewport */ + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 +#define __GLEE_GL_ARB_fragment_layer_viewport 1 +/* Constants */ +#endif + +/* GL_ARB_framebuffer_no_attachments */ + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 +#define __GLEE_GL_ARB_framebuffer_no_attachments 1 +/* Constants */ +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#ifndef GLEE_H_DEFINED_glFramebufferParameteri +#define GLEE_H_DEFINED_glFramebufferParameteri + typedef void (APIENTRYP GLEEPFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLFRAMEBUFFERPARAMETERIPROC GLeeFuncPtr_glFramebufferParameteri; + #define glFramebufferParameteri GLeeFuncPtr_glFramebufferParameteri +#endif +#ifndef GLEE_H_DEFINED_glGetFramebufferParameteriv +#define GLEE_H_DEFINED_glGetFramebufferParameteriv + typedef void (APIENTRYP GLEEPFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETFRAMEBUFFERPARAMETERIVPROC GLeeFuncPtr_glGetFramebufferParameteriv; + #define glGetFramebufferParameteriv GLeeFuncPtr_glGetFramebufferParameteriv +#endif +#ifndef GLEE_H_DEFINED_glNamedFramebufferParameteriEXT +#define GLEE_H_DEFINED_glNamedFramebufferParameteriEXT + typedef void (APIENTRYP GLEEPFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); + GLEE_EXTERN GLEEPFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC GLeeFuncPtr_glNamedFramebufferParameteriEXT; + #define glNamedFramebufferParameteriEXT GLeeFuncPtr_glNamedFramebufferParameteriEXT +#endif +#ifndef GLEE_H_DEFINED_glGetNamedFramebufferParameterivEXT +#define GLEE_H_DEFINED_glGetNamedFramebufferParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC GLeeFuncPtr_glGetNamedFramebufferParameterivEXT; + #define glGetNamedFramebufferParameterivEXT GLeeFuncPtr_glGetNamedFramebufferParameterivEXT +#endif +#endif + +/* GL_ARB_internalformat_query2 */ + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 +#define __GLEE_GL_ARB_internalformat_query2 1 +/* Constants */ +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_SRGB_DECODE_ARB 0x8299 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#ifndef GLEE_H_DEFINED_glGetInternalformati64v +#define GLEE_H_DEFINED_glGetInternalformati64v + typedef void (APIENTRYP GLEEPFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 * params); + GLEE_EXTERN GLEEPFNGLGETINTERNALFORMATI64VPROC GLeeFuncPtr_glGetInternalformati64v; + #define glGetInternalformati64v GLeeFuncPtr_glGetInternalformati64v +#endif +#endif + +/* GL_ARB_invalidate_subdata */ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 +#define __GLEE_GL_ARB_invalidate_subdata 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glInvalidateTexSubImage +#define GLEE_H_DEFINED_glInvalidateTexSubImage + typedef void (APIENTRYP GLEEPFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + GLEE_EXTERN GLEEPFNGLINVALIDATETEXSUBIMAGEPROC GLeeFuncPtr_glInvalidateTexSubImage; + #define glInvalidateTexSubImage GLeeFuncPtr_glInvalidateTexSubImage +#endif +#ifndef GLEE_H_DEFINED_glInvalidateTexImage +#define GLEE_H_DEFINED_glInvalidateTexImage + typedef void (APIENTRYP GLEEPFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLINVALIDATETEXIMAGEPROC GLeeFuncPtr_glInvalidateTexImage; + #define glInvalidateTexImage GLeeFuncPtr_glInvalidateTexImage +#endif +#ifndef GLEE_H_DEFINED_glInvalidateBufferSubData +#define GLEE_H_DEFINED_glInvalidateBufferSubData + typedef void (APIENTRYP GLEEPFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); + GLEE_EXTERN GLEEPFNGLINVALIDATEBUFFERSUBDATAPROC GLeeFuncPtr_glInvalidateBufferSubData; + #define glInvalidateBufferSubData GLeeFuncPtr_glInvalidateBufferSubData +#endif +#ifndef GLEE_H_DEFINED_glInvalidateBufferData +#define GLEE_H_DEFINED_glInvalidateBufferData + typedef void (APIENTRYP GLEEPFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); + GLEE_EXTERN GLEEPFNGLINVALIDATEBUFFERDATAPROC GLeeFuncPtr_glInvalidateBufferData; + #define glInvalidateBufferData GLeeFuncPtr_glInvalidateBufferData +#endif +#ifndef GLEE_H_DEFINED_glInvalidateFramebuffer +#define GLEE_H_DEFINED_glInvalidateFramebuffer + typedef void (APIENTRYP GLEEPFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum * attachments); + GLEE_EXTERN GLEEPFNGLINVALIDATEFRAMEBUFFERPROC GLeeFuncPtr_glInvalidateFramebuffer; + #define glInvalidateFramebuffer GLeeFuncPtr_glInvalidateFramebuffer +#endif +#ifndef GLEE_H_DEFINED_glInvalidateSubFramebuffer +#define GLEE_H_DEFINED_glInvalidateSubFramebuffer + typedef void (APIENTRYP GLEEPFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); + GLEE_EXTERN GLEEPFNGLINVALIDATESUBFRAMEBUFFERPROC GLeeFuncPtr_glInvalidateSubFramebuffer; + #define glInvalidateSubFramebuffer GLeeFuncPtr_glInvalidateSubFramebuffer +#endif +#endif + +/* GL_ARB_multi_draw_indirect */ + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 +#define __GLEE_GL_ARB_multi_draw_indirect 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glMultiDrawArraysIndirect +#define GLEE_H_DEFINED_glMultiDrawArraysIndirect + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride); + GLEE_EXTERN GLEEPFNGLMULTIDRAWARRAYSINDIRECTPROC GLeeFuncPtr_glMultiDrawArraysIndirect; + #define glMultiDrawArraysIndirect GLeeFuncPtr_glMultiDrawArraysIndirect +#endif +#ifndef GLEE_H_DEFINED_glMultiDrawElementsIndirect +#define GLEE_H_DEFINED_glMultiDrawElementsIndirect + typedef void (APIENTRYP GLEEPFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride); + GLEE_EXTERN GLEEPFNGLMULTIDRAWELEMENTSINDIRECTPROC GLeeFuncPtr_glMultiDrawElementsIndirect; + #define glMultiDrawElementsIndirect GLeeFuncPtr_glMultiDrawElementsIndirect +#endif +#endif + +/* GL_ARB_program_interface_query */ + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 +#define __GLEE_GL_ARB_program_interface_query 1 +/* Constants */ +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_IS_PER_PATCH 0x92E7 +#ifndef GLEE_H_DEFINED_glGetProgramInterfaceiv +#define GLEE_H_DEFINED_glGetProgramInterfaceiv + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMINTERFACEIVPROC GLeeFuncPtr_glGetProgramInterfaceiv; + #define glGetProgramInterfaceiv GLeeFuncPtr_glGetProgramInterfaceiv +#endif +#ifndef GLEE_H_DEFINED_glGetProgramResourceIndex +#define GLEE_H_DEFINED_glGetProgramResourceIndex + typedef GLuint (APIENTRYP GLEEPFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETPROGRAMRESOURCEINDEXPROC GLeeFuncPtr_glGetProgramResourceIndex; + #define glGetProgramResourceIndex GLeeFuncPtr_glGetProgramResourceIndex +#endif +#ifndef GLEE_H_DEFINED_glGetProgramResourceName +#define GLEE_H_DEFINED_glGetProgramResourceName + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); + GLEE_EXTERN GLEEPFNGLGETPROGRAMRESOURCENAMEPROC GLeeFuncPtr_glGetProgramResourceName; + #define glGetProgramResourceName GLeeFuncPtr_glGetProgramResourceName +#endif +#ifndef GLEE_H_DEFINED_glGetProgramResourceiv +#define GLEE_H_DEFINED_glGetProgramResourceiv + typedef void (APIENTRYP GLEEPFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPROGRAMRESOURCEIVPROC GLeeFuncPtr_glGetProgramResourceiv; + #define glGetProgramResourceiv GLeeFuncPtr_glGetProgramResourceiv +#endif +#ifndef GLEE_H_DEFINED_glGetProgramResourceLocation +#define GLEE_H_DEFINED_glGetProgramResourceLocation + typedef GLint (APIENTRYP GLEEPFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETPROGRAMRESOURCELOCATIONPROC GLeeFuncPtr_glGetProgramResourceLocation; + #define glGetProgramResourceLocation GLeeFuncPtr_glGetProgramResourceLocation +#endif +#ifndef GLEE_H_DEFINED_glGetProgramResourceLocationIndex +#define GLEE_H_DEFINED_glGetProgramResourceLocationIndex + typedef GLint (APIENTRYP GLEEPFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar * name); + GLEE_EXTERN GLEEPFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC GLeeFuncPtr_glGetProgramResourceLocationIndex; + #define glGetProgramResourceLocationIndex GLeeFuncPtr_glGetProgramResourceLocationIndex +#endif +#endif + +/* GL_ARB_robust_buffer_access_behavior */ + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 +#define __GLEE_GL_ARB_robust_buffer_access_behavior 1 +/* Constants */ +#endif + +/* GL_ARB_shader_image_size */ + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 +#define __GLEE_GL_ARB_shader_image_size 1 +/* Constants */ +#endif + +/* GL_ARB_shader_storage_buffer_object */ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +#define __GLEE_GL_ARB_shader_storage_buffer_object 1 +/* Constants */ +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS +#ifndef GLEE_H_DEFINED_glShaderStorageBlockBinding +#define GLEE_H_DEFINED_glShaderStorageBlockBinding + typedef void (APIENTRYP GLEEPFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); + GLEE_EXTERN GLEEPFNGLSHADERSTORAGEBLOCKBINDINGPROC GLeeFuncPtr_glShaderStorageBlockBinding; + #define glShaderStorageBlockBinding GLeeFuncPtr_glShaderStorageBlockBinding +#endif +#endif + +/* GL_ARB_stencil_texturing */ + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 +#define __GLEE_GL_ARB_stencil_texturing 1 +/* Constants */ +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#endif + +/* GL_ARB_texture_buffer_range */ + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 +#define __GLEE_GL_ARB_texture_buffer_range 1 +/* Constants */ +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#ifndef GLEE_H_DEFINED_glTexBufferRange +#define GLEE_H_DEFINED_glTexBufferRange + typedef void (APIENTRYP GLEEPFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + GLEE_EXTERN GLEEPFNGLTEXBUFFERRANGEPROC GLeeFuncPtr_glTexBufferRange; + #define glTexBufferRange GLeeFuncPtr_glTexBufferRange +#endif +#ifndef GLEE_H_DEFINED_glTextureBufferRangeEXT +#define GLEE_H_DEFINED_glTextureBufferRangeEXT + typedef void (APIENTRYP GLEEPFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + GLEE_EXTERN GLEEPFNGLTEXTUREBUFFERRANGEEXTPROC GLeeFuncPtr_glTextureBufferRangeEXT; + #define glTextureBufferRangeEXT GLeeFuncPtr_glTextureBufferRangeEXT +#endif +#endif + +/* GL_ARB_texture_query_levels */ + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 +#define __GLEE_GL_ARB_texture_query_levels 1 +/* Constants */ +#endif + +/* GL_ARB_texture_storage_multisample */ + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 +#define __GLEE_GL_ARB_texture_storage_multisample 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glTexStorage2DMultisample +#define GLEE_H_DEFINED_glTexStorage2DMultisample + typedef void (APIENTRYP GLEEPFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + GLEE_EXTERN GLEEPFNGLTEXSTORAGE2DMULTISAMPLEPROC GLeeFuncPtr_glTexStorage2DMultisample; + #define glTexStorage2DMultisample GLeeFuncPtr_glTexStorage2DMultisample +#endif +#ifndef GLEE_H_DEFINED_glTexStorage3DMultisample +#define GLEE_H_DEFINED_glTexStorage3DMultisample + typedef void (APIENTRYP GLEEPFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + GLEE_EXTERN GLEEPFNGLTEXSTORAGE3DMULTISAMPLEPROC GLeeFuncPtr_glTexStorage3DMultisample; + #define glTexStorage3DMultisample GLeeFuncPtr_glTexStorage3DMultisample +#endif +#ifndef GLEE_H_DEFINED_glTextureStorage2DMultisampleEXT +#define GLEE_H_DEFINED_glTextureStorage2DMultisampleEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + GLEE_EXTERN GLEEPFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC GLeeFuncPtr_glTextureStorage2DMultisampleEXT; + #define glTextureStorage2DMultisampleEXT GLeeFuncPtr_glTextureStorage2DMultisampleEXT +#endif +#ifndef GLEE_H_DEFINED_glTextureStorage3DMultisampleEXT +#define GLEE_H_DEFINED_glTextureStorage3DMultisampleEXT + typedef void (APIENTRYP GLEEPFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + GLEE_EXTERN GLEEPFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC GLeeFuncPtr_glTextureStorage3DMultisampleEXT; + #define glTextureStorage3DMultisampleEXT GLeeFuncPtr_glTextureStorage3DMultisampleEXT +#endif +#endif + /* GL_EXT_abgr */ #ifndef GL_EXT_abgr @@ -8401,7 +9393,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_BLEND_COLOR_EXT 0x8005 #ifndef GLEE_H_DEFINED_glBlendColorEXT #define GLEE_H_DEFINED_glBlendColorEXT - typedef void (APIENTRYP GLEEPFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + typedef void (APIENTRYP GLEEPFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); GLEE_EXTERN GLEEPFNGLBLENDCOLOREXTPROC GLeeFuncPtr_glBlendColorEXT; #define glBlendColorEXT GLeeFuncPtr_glBlendColorEXT #endif @@ -10542,6 +11534,18 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; GLEE_EXTERN GLEEPFNGLPIXELTRANSFORMPARAMETERFVEXTPROC GLeeFuncPtr_glPixelTransformParameterfvEXT; #define glPixelTransformParameterfvEXT GLeeFuncPtr_glPixelTransformParameterfvEXT #endif +#ifndef GLEE_H_DEFINED_glGetPixelTransformParameterivEXT +#define GLEE_H_DEFINED_glGetPixelTransformParameterivEXT + typedef void (APIENTRYP GLEEPFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); + GLEE_EXTERN GLEEPFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC GLeeFuncPtr_glGetPixelTransformParameterivEXT; + #define glGetPixelTransformParameterivEXT GLeeFuncPtr_glGetPixelTransformParameterivEXT +#endif +#ifndef GLEE_H_DEFINED_glGetPixelTransformParameterfvEXT +#define GLEE_H_DEFINED_glGetPixelTransformParameterfvEXT + typedef void (APIENTRYP GLEEPFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat * params); + GLEE_EXTERN GLEEPFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC GLeeFuncPtr_glGetPixelTransformParameterfvEXT; + #define glGetPixelTransformParameterfvEXT GLeeFuncPtr_glGetPixelTransformParameterfvEXT +#endif #endif /* GL_EXT_pixel_transform_color_table */ @@ -11547,7 +12551,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #ifndef GLEE_H_DEFINED_glVertexWeightPointerEXT #define GLEE_H_DEFINED_glVertexWeightPointerEXT - typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid * pointer); + typedef void (APIENTRYP GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); GLEE_EXTERN GLEEPFNGLVERTEXWEIGHTPOINTEREXTPROC GLeeFuncPtr_glVertexWeightPointerEXT; #define glVertexWeightPointerEXT GLeeFuncPtr_glVertexWeightPointerEXT #endif @@ -14503,6 +15507,8 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_RGB4_S3TC 0x83A1 #define GL_RGBA_S3TC 0x83A2 #define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 #endif /* GL_ATI_draw_buffers */ @@ -14542,7 +15548,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_ATI_pixel_format_float 1 #define __GLEE_GL_ATI_pixel_format_float 1 /* Constants */ -#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 #define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 #endif @@ -14618,18 +15624,18 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4FNVPROC GLeeFuncPtr_glProgramNamedParameter4fNV; #define glProgramNamedParameter4fNV GLeeFuncPtr_glProgramNamedParameter4fNV #endif -#ifndef GLEE_H_DEFINED_glProgramNamedParameter4dNV -#define GLEE_H_DEFINED_glProgramNamedParameter4dNV - typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC GLeeFuncPtr_glProgramNamedParameter4dNV; - #define glProgramNamedParameter4dNV GLeeFuncPtr_glProgramNamedParameter4dNV -#endif #ifndef GLEE_H_DEFINED_glProgramNamedParameter4fvNV #define GLEE_H_DEFINED_glProgramNamedParameter4fvNV typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4FVNVPROC GLeeFuncPtr_glProgramNamedParameter4fvNV; #define glProgramNamedParameter4fvNV GLeeFuncPtr_glProgramNamedParameter4fvNV #endif +#ifndef GLEE_H_DEFINED_glProgramNamedParameter4dNV +#define GLEE_H_DEFINED_glProgramNamedParameter4dNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLEE_EXTERN GLEEPFNGLPROGRAMNAMEDPARAMETER4DNVPROC GLeeFuncPtr_glProgramNamedParameter4dNV; + #define glProgramNamedParameter4dNV GLeeFuncPtr_glProgramNamedParameter4dNV +#endif #ifndef GLEE_H_DEFINED_glProgramNamedParameter4dvNV #define GLEE_H_DEFINED_glProgramNamedParameter4dvNV typedef void (APIENTRYP GLEEPFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); @@ -14949,7 +15955,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D #ifndef GLEE_H_DEFINED_glPixelDataRangeNV #define GLEE_H_DEFINED_glPixelDataRangeNV - typedef void (APIENTRYP GLEEPFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid * pointer); + typedef void (APIENTRYP GLEEPFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const GLvoid * pointer); GLEE_EXTERN GLEEPFNGLPIXELDATARANGENVPROC GLeeFuncPtr_glPixelDataRangeNV; #define glPixelDataRangeNV GLeeFuncPtr_glPixelDataRangeNV #endif @@ -15070,6 +16076,841 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #endif +/* GL_OES_byte_coordinates */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 +#define __GLEE_GL_OES_byte_coordinates 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glMultiTexCoord1bOES +#define GLEE_H_DEFINED_glMultiTexCoord1bOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1BOESPROC GLeeFuncPtr_glMultiTexCoord1bOES; + #define glMultiTexCoord1bOES GLeeFuncPtr_glMultiTexCoord1bOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1bvOES +#define GLEE_H_DEFINED_glMultiTexCoord1bvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1BVOESPROC GLeeFuncPtr_glMultiTexCoord1bvOES; + #define glMultiTexCoord1bvOES GLeeFuncPtr_glMultiTexCoord1bvOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2bOES +#define GLEE_H_DEFINED_glMultiTexCoord2bOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2BOESPROC GLeeFuncPtr_glMultiTexCoord2bOES; + #define glMultiTexCoord2bOES GLeeFuncPtr_glMultiTexCoord2bOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2bvOES +#define GLEE_H_DEFINED_glMultiTexCoord2bvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2BVOESPROC GLeeFuncPtr_glMultiTexCoord2bvOES; + #define glMultiTexCoord2bvOES GLeeFuncPtr_glMultiTexCoord2bvOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3bOES +#define GLEE_H_DEFINED_glMultiTexCoord3bOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3BOESPROC GLeeFuncPtr_glMultiTexCoord3bOES; + #define glMultiTexCoord3bOES GLeeFuncPtr_glMultiTexCoord3bOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3bvOES +#define GLEE_H_DEFINED_glMultiTexCoord3bvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3BVOESPROC GLeeFuncPtr_glMultiTexCoord3bvOES; + #define glMultiTexCoord3bvOES GLeeFuncPtr_glMultiTexCoord3bvOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4bOES +#define GLEE_H_DEFINED_glMultiTexCoord4bOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4BOESPROC GLeeFuncPtr_glMultiTexCoord4bOES; + #define glMultiTexCoord4bOES GLeeFuncPtr_glMultiTexCoord4bOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4bvOES +#define GLEE_H_DEFINED_glMultiTexCoord4bvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4BVOESPROC GLeeFuncPtr_glMultiTexCoord4bvOES; + #define glMultiTexCoord4bvOES GLeeFuncPtr_glMultiTexCoord4bvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord1bOES +#define GLEE_H_DEFINED_glTexCoord1bOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD1BOESPROC) (GLbyte s); + GLEE_EXTERN GLEEPFNGLTEXCOORD1BOESPROC GLeeFuncPtr_glTexCoord1bOES; + #define glTexCoord1bOES GLeeFuncPtr_glTexCoord1bOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord1bvOES +#define GLEE_H_DEFINED_glTexCoord1bvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD1BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD1BVOESPROC GLeeFuncPtr_glTexCoord1bvOES; + #define glTexCoord1bvOES GLeeFuncPtr_glTexCoord1bvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2bOES +#define GLEE_H_DEFINED_glTexCoord2bOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); + GLEE_EXTERN GLEEPFNGLTEXCOORD2BOESPROC GLeeFuncPtr_glTexCoord2bOES; + #define glTexCoord2bOES GLeeFuncPtr_glTexCoord2bOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2bvOES +#define GLEE_H_DEFINED_glTexCoord2bvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD2BVOESPROC GLeeFuncPtr_glTexCoord2bvOES; + #define glTexCoord2bvOES GLeeFuncPtr_glTexCoord2bvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord3bOES +#define GLEE_H_DEFINED_glTexCoord3bOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); + GLEE_EXTERN GLEEPFNGLTEXCOORD3BOESPROC GLeeFuncPtr_glTexCoord3bOES; + #define glTexCoord3bOES GLeeFuncPtr_glTexCoord3bOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord3bvOES +#define GLEE_H_DEFINED_glTexCoord3bvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD3BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD3BVOESPROC GLeeFuncPtr_glTexCoord3bvOES; + #define glTexCoord3bvOES GLeeFuncPtr_glTexCoord3bvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4bOES +#define GLEE_H_DEFINED_glTexCoord4bOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); + GLEE_EXTERN GLEEPFNGLTEXCOORD4BOESPROC GLeeFuncPtr_glTexCoord4bOES; + #define glTexCoord4bOES GLeeFuncPtr_glTexCoord4bOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4bvOES +#define GLEE_H_DEFINED_glTexCoord4bvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD4BVOESPROC GLeeFuncPtr_glTexCoord4bvOES; + #define glTexCoord4bvOES GLeeFuncPtr_glTexCoord4bvOES +#endif +#ifndef GLEE_H_DEFINED_glVertex2bOES +#define GLEE_H_DEFINED_glVertex2bOES + typedef void (APIENTRYP GLEEPFNGLVERTEX2BOESPROC) (GLbyte x); + GLEE_EXTERN GLEEPFNGLVERTEX2BOESPROC GLeeFuncPtr_glVertex2bOES; + #define glVertex2bOES GLeeFuncPtr_glVertex2bOES +#endif +#ifndef GLEE_H_DEFINED_glVertex2bvOES +#define GLEE_H_DEFINED_glVertex2bvOES + typedef void (APIENTRYP GLEEPFNGLVERTEX2BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLVERTEX2BVOESPROC GLeeFuncPtr_glVertex2bvOES; + #define glVertex2bvOES GLeeFuncPtr_glVertex2bvOES +#endif +#ifndef GLEE_H_DEFINED_glVertex3bOES +#define GLEE_H_DEFINED_glVertex3bOES + typedef void (APIENTRYP GLEEPFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); + GLEE_EXTERN GLEEPFNGLVERTEX3BOESPROC GLeeFuncPtr_glVertex3bOES; + #define glVertex3bOES GLeeFuncPtr_glVertex3bOES +#endif +#ifndef GLEE_H_DEFINED_glVertex3bvOES +#define GLEE_H_DEFINED_glVertex3bvOES + typedef void (APIENTRYP GLEEPFNGLVERTEX3BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLVERTEX3BVOESPROC GLeeFuncPtr_glVertex3bvOES; + #define glVertex3bvOES GLeeFuncPtr_glVertex3bvOES +#endif +#ifndef GLEE_H_DEFINED_glVertex4bOES +#define GLEE_H_DEFINED_glVertex4bOES + typedef void (APIENTRYP GLEEPFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); + GLEE_EXTERN GLEEPFNGLVERTEX4BOESPROC GLeeFuncPtr_glVertex4bOES; + #define glVertex4bOES GLeeFuncPtr_glVertex4bOES +#endif +#ifndef GLEE_H_DEFINED_glVertex4bvOES +#define GLEE_H_DEFINED_glVertex4bvOES + typedef void (APIENTRYP GLEEPFNGLVERTEX4BVOESPROC) (const GLbyte * coords); + GLEE_EXTERN GLEEPFNGLVERTEX4BVOESPROC GLeeFuncPtr_glVertex4bvOES; + #define glVertex4bvOES GLeeFuncPtr_glVertex4bvOES +#endif +#endif + +/* GL_OES_fixed_point */ + +#ifndef GL_OES_fixed_point +#define GL_OES_fixed_point 1 +#define __GLEE_GL_OES_fixed_point 1 +/* Constants */ +#define GL_FIXED_OES 0x140C +#ifndef GLEE_H_DEFINED_glAccumxOES +#define GLEE_H_DEFINED_glAccumxOES + typedef void (APIENTRYP GLEEPFNGLACCUMXOESPROC) (GLenum op, GLfixed value); + GLEE_EXTERN GLEEPFNGLACCUMXOESPROC GLeeFuncPtr_glAccumxOES; + #define glAccumxOES GLeeFuncPtr_glAccumxOES +#endif +#ifndef GLEE_H_DEFINED_glAlphaFuncxOES +#define GLEE_H_DEFINED_glAlphaFuncxOES + typedef void (APIENTRYP GLEEPFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); + GLEE_EXTERN GLEEPFNGLALPHAFUNCXOESPROC GLeeFuncPtr_glAlphaFuncxOES; + #define glAlphaFuncxOES GLeeFuncPtr_glAlphaFuncxOES +#endif +#ifndef GLEE_H_DEFINED_glBitmapxOES +#define GLEE_H_DEFINED_glBitmapxOES + typedef void (APIENTRYP GLEEPFNGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte * bitmap); + GLEE_EXTERN GLEEPFNGLBITMAPXOESPROC GLeeFuncPtr_glBitmapxOES; + #define glBitmapxOES GLeeFuncPtr_glBitmapxOES +#endif +#ifndef GLEE_H_DEFINED_glBlendColorxOES +#define GLEE_H_DEFINED_glBlendColorxOES + typedef void (APIENTRYP GLEEPFNGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); + GLEE_EXTERN GLEEPFNGLBLENDCOLORXOESPROC GLeeFuncPtr_glBlendColorxOES; + #define glBlendColorxOES GLeeFuncPtr_glBlendColorxOES +#endif +#ifndef GLEE_H_DEFINED_glClearAccumxOES +#define GLEE_H_DEFINED_glClearAccumxOES + typedef void (APIENTRYP GLEEPFNGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); + GLEE_EXTERN GLEEPFNGLCLEARACCUMXOESPROC GLeeFuncPtr_glClearAccumxOES; + #define glClearAccumxOES GLeeFuncPtr_glClearAccumxOES +#endif +#ifndef GLEE_H_DEFINED_glClearColorxOES +#define GLEE_H_DEFINED_glClearColorxOES + typedef void (APIENTRYP GLEEPFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); + GLEE_EXTERN GLEEPFNGLCLEARCOLORXOESPROC GLeeFuncPtr_glClearColorxOES; + #define glClearColorxOES GLeeFuncPtr_glClearColorxOES +#endif +#ifndef GLEE_H_DEFINED_glClearDepthxOES +#define GLEE_H_DEFINED_glClearDepthxOES + typedef void (APIENTRYP GLEEPFNGLCLEARDEPTHXOESPROC) (GLfixed depth); + GLEE_EXTERN GLEEPFNGLCLEARDEPTHXOESPROC GLeeFuncPtr_glClearDepthxOES; + #define glClearDepthxOES GLeeFuncPtr_glClearDepthxOES +#endif +#ifndef GLEE_H_DEFINED_glClipPlanexOES +#define GLEE_H_DEFINED_glClipPlanexOES + typedef void (APIENTRYP GLEEPFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed * equation); + GLEE_EXTERN GLEEPFNGLCLIPPLANEXOESPROC GLeeFuncPtr_glClipPlanexOES; + #define glClipPlanexOES GLeeFuncPtr_glClipPlanexOES +#endif +#ifndef GLEE_H_DEFINED_glColor3xOES +#define GLEE_H_DEFINED_glColor3xOES + typedef void (APIENTRYP GLEEPFNGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); + GLEE_EXTERN GLEEPFNGLCOLOR3XOESPROC GLeeFuncPtr_glColor3xOES; + #define glColor3xOES GLeeFuncPtr_glColor3xOES +#endif +#ifndef GLEE_H_DEFINED_glColor4xOES +#define GLEE_H_DEFINED_glColor4xOES + typedef void (APIENTRYP GLEEPFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); + GLEE_EXTERN GLEEPFNGLCOLOR4XOESPROC GLeeFuncPtr_glColor4xOES; + #define glColor4xOES GLeeFuncPtr_glColor4xOES +#endif +#ifndef GLEE_H_DEFINED_glColor3xvOES +#define GLEE_H_DEFINED_glColor3xvOES + typedef void (APIENTRYP GLEEPFNGLCOLOR3XVOESPROC) (const GLfixed * components); + GLEE_EXTERN GLEEPFNGLCOLOR3XVOESPROC GLeeFuncPtr_glColor3xvOES; + #define glColor3xvOES GLeeFuncPtr_glColor3xvOES +#endif +#ifndef GLEE_H_DEFINED_glColor4xvOES +#define GLEE_H_DEFINED_glColor4xvOES + typedef void (APIENTRYP GLEEPFNGLCOLOR4XVOESPROC) (const GLfixed * components); + GLEE_EXTERN GLEEPFNGLCOLOR4XVOESPROC GLeeFuncPtr_glColor4xvOES; + #define glColor4xvOES GLeeFuncPtr_glColor4xvOES +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterxOES +#define GLEE_H_DEFINED_glConvolutionParameterxOES + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERXOESPROC GLeeFuncPtr_glConvolutionParameterxOES; + #define glConvolutionParameterxOES GLeeFuncPtr_glConvolutionParameterxOES +#endif +#ifndef GLEE_H_DEFINED_glConvolutionParameterxvOES +#define GLEE_H_DEFINED_glConvolutionParameterxvOES + typedef void (APIENTRYP GLEEPFNGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed * params); + GLEE_EXTERN GLEEPFNGLCONVOLUTIONPARAMETERXVOESPROC GLeeFuncPtr_glConvolutionParameterxvOES; + #define glConvolutionParameterxvOES GLeeFuncPtr_glConvolutionParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glDepthRangexOES +#define GLEE_H_DEFINED_glDepthRangexOES + typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); + GLEE_EXTERN GLEEPFNGLDEPTHRANGEXOESPROC GLeeFuncPtr_glDepthRangexOES; + #define glDepthRangexOES GLeeFuncPtr_glDepthRangexOES +#endif +#ifndef GLEE_H_DEFINED_glEvalCoord1xOES +#define GLEE_H_DEFINED_glEvalCoord1xOES + typedef void (APIENTRYP GLEEPFNGLEVALCOORD1XOESPROC) (GLfixed u); + GLEE_EXTERN GLEEPFNGLEVALCOORD1XOESPROC GLeeFuncPtr_glEvalCoord1xOES; + #define glEvalCoord1xOES GLeeFuncPtr_glEvalCoord1xOES +#endif +#ifndef GLEE_H_DEFINED_glEvalCoord2xOES +#define GLEE_H_DEFINED_glEvalCoord2xOES + typedef void (APIENTRYP GLEEPFNGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); + GLEE_EXTERN GLEEPFNGLEVALCOORD2XOESPROC GLeeFuncPtr_glEvalCoord2xOES; + #define glEvalCoord2xOES GLeeFuncPtr_glEvalCoord2xOES +#endif +#ifndef GLEE_H_DEFINED_glEvalCoord1xvOES +#define GLEE_H_DEFINED_glEvalCoord1xvOES + typedef void (APIENTRYP GLEEPFNGLEVALCOORD1XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLEVALCOORD1XVOESPROC GLeeFuncPtr_glEvalCoord1xvOES; + #define glEvalCoord1xvOES GLeeFuncPtr_glEvalCoord1xvOES +#endif +#ifndef GLEE_H_DEFINED_glEvalCoord2xvOES +#define GLEE_H_DEFINED_glEvalCoord2xvOES + typedef void (APIENTRYP GLEEPFNGLEVALCOORD2XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLEVALCOORD2XVOESPROC GLeeFuncPtr_glEvalCoord2xvOES; + #define glEvalCoord2xvOES GLeeFuncPtr_glEvalCoord2xvOES +#endif +#ifndef GLEE_H_DEFINED_glFeedbackBufferxOES +#define GLEE_H_DEFINED_glFeedbackBufferxOES + typedef void (APIENTRYP GLEEPFNGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed * buffer); + GLEE_EXTERN GLEEPFNGLFEEDBACKBUFFERXOESPROC GLeeFuncPtr_glFeedbackBufferxOES; + #define glFeedbackBufferxOES GLeeFuncPtr_glFeedbackBufferxOES +#endif +#ifndef GLEE_H_DEFINED_glFogxOES +#define GLEE_H_DEFINED_glFogxOES + typedef void (APIENTRYP GLEEPFNGLFOGXOESPROC) (GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLFOGXOESPROC GLeeFuncPtr_glFogxOES; + #define glFogxOES GLeeFuncPtr_glFogxOES +#endif +#ifndef GLEE_H_DEFINED_glFogxvOES +#define GLEE_H_DEFINED_glFogxvOES + typedef void (APIENTRYP GLEEPFNGLFOGXVOESPROC) (GLenum pname, const GLfixed * param); + GLEE_EXTERN GLEEPFNGLFOGXVOESPROC GLeeFuncPtr_glFogxvOES; + #define glFogxvOES GLeeFuncPtr_glFogxvOES +#endif +#ifndef GLEE_H_DEFINED_glFrustumxOES +#define GLEE_H_DEFINED_glFrustumxOES + typedef void (APIENTRYP GLEEPFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); + GLEE_EXTERN GLEEPFNGLFRUSTUMXOESPROC GLeeFuncPtr_glFrustumxOES; + #define glFrustumxOES GLeeFuncPtr_glFrustumxOES +#endif +#ifndef GLEE_H_DEFINED_glGetClipPlanexOES +#define GLEE_H_DEFINED_glGetClipPlanexOES + typedef void (APIENTRYP GLEEPFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed * equation); + GLEE_EXTERN GLEEPFNGLGETCLIPPLANEXOESPROC GLeeFuncPtr_glGetClipPlanexOES; + #define glGetClipPlanexOES GLeeFuncPtr_glGetClipPlanexOES +#endif +#ifndef GLEE_H_DEFINED_glGetConvolutionParameterxvOES +#define GLEE_H_DEFINED_glGetConvolutionParameterxvOES + typedef void (APIENTRYP GLEEPFNGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETCONVOLUTIONPARAMETERXVOESPROC GLeeFuncPtr_glGetConvolutionParameterxvOES; + #define glGetConvolutionParameterxvOES GLeeFuncPtr_glGetConvolutionParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glGetFixedvOES +#define GLEE_H_DEFINED_glGetFixedvOES + typedef void (APIENTRYP GLEEPFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETFIXEDVOESPROC GLeeFuncPtr_glGetFixedvOES; + #define glGetFixedvOES GLeeFuncPtr_glGetFixedvOES +#endif +#ifndef GLEE_H_DEFINED_glGetHistogramParameterxvOES +#define GLEE_H_DEFINED_glGetHistogramParameterxvOES + typedef void (APIENTRYP GLEEPFNGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETHISTOGRAMPARAMETERXVOESPROC GLeeFuncPtr_glGetHistogramParameterxvOES; + #define glGetHistogramParameterxvOES GLeeFuncPtr_glGetHistogramParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glGetLightxOES +#define GLEE_H_DEFINED_glGetLightxOES + typedef void (APIENTRYP GLEEPFNGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETLIGHTXOESPROC GLeeFuncPtr_glGetLightxOES; + #define glGetLightxOES GLeeFuncPtr_glGetLightxOES +#endif +#ifndef GLEE_H_DEFINED_glGetMapxvOES +#define GLEE_H_DEFINED_glGetMapxvOES + typedef void (APIENTRYP GLEEPFNGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed * v); + GLEE_EXTERN GLEEPFNGLGETMAPXVOESPROC GLeeFuncPtr_glGetMapxvOES; + #define glGetMapxvOES GLeeFuncPtr_glGetMapxvOES +#endif +#ifndef GLEE_H_DEFINED_glGetMaterialxOES +#define GLEE_H_DEFINED_glGetMaterialxOES + typedef void (APIENTRYP GLEEPFNGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLGETMATERIALXOESPROC GLeeFuncPtr_glGetMaterialxOES; + #define glGetMaterialxOES GLeeFuncPtr_glGetMaterialxOES +#endif +#ifndef GLEE_H_DEFINED_glGetPixelMapxv +#define GLEE_H_DEFINED_glGetPixelMapxv + typedef void (APIENTRYP GLEEPFNGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed * values); + GLEE_EXTERN GLEEPFNGLGETPIXELMAPXVPROC GLeeFuncPtr_glGetPixelMapxv; + #define glGetPixelMapxv GLeeFuncPtr_glGetPixelMapxv +#endif +#ifndef GLEE_H_DEFINED_glGetTexEnvxvOES +#define GLEE_H_DEFINED_glGetTexEnvxvOES + typedef void (APIENTRYP GLEEPFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETTEXENVXVOESPROC GLeeFuncPtr_glGetTexEnvxvOES; + #define glGetTexEnvxvOES GLeeFuncPtr_glGetTexEnvxvOES +#endif +#ifndef GLEE_H_DEFINED_glGetTexGenxvOES +#define GLEE_H_DEFINED_glGetTexGenxvOES + typedef void (APIENTRYP GLEEPFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETTEXGENXVOESPROC GLeeFuncPtr_glGetTexGenxvOES; + #define glGetTexGenxvOES GLeeFuncPtr_glGetTexGenxvOES +#endif +#ifndef GLEE_H_DEFINED_glGetTexLevelParameterxvOES +#define GLEE_H_DEFINED_glGetTexLevelParameterxvOES + typedef void (APIENTRYP GLEEPFNGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETTEXLEVELPARAMETERXVOESPROC GLeeFuncPtr_glGetTexLevelParameterxvOES; + #define glGetTexLevelParameterxvOES GLeeFuncPtr_glGetTexLevelParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glGetTexParameterxvOES +#define GLEE_H_DEFINED_glGetTexParameterxvOES + typedef void (APIENTRYP GLEEPFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed * params); + GLEE_EXTERN GLEEPFNGLGETTEXPARAMETERXVOESPROC GLeeFuncPtr_glGetTexParameterxvOES; + #define glGetTexParameterxvOES GLeeFuncPtr_glGetTexParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glIndexxOES +#define GLEE_H_DEFINED_glIndexxOES + typedef void (APIENTRYP GLEEPFNGLINDEXXOESPROC) (GLfixed component); + GLEE_EXTERN GLEEPFNGLINDEXXOESPROC GLeeFuncPtr_glIndexxOES; + #define glIndexxOES GLeeFuncPtr_glIndexxOES +#endif +#ifndef GLEE_H_DEFINED_glIndexxvOES +#define GLEE_H_DEFINED_glIndexxvOES + typedef void (APIENTRYP GLEEPFNGLINDEXXVOESPROC) (const GLfixed * component); + GLEE_EXTERN GLEEPFNGLINDEXXVOESPROC GLeeFuncPtr_glIndexxvOES; + #define glIndexxvOES GLeeFuncPtr_glIndexxvOES +#endif +#ifndef GLEE_H_DEFINED_glLightModelxOES +#define GLEE_H_DEFINED_glLightModelxOES + typedef void (APIENTRYP GLEEPFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLLIGHTMODELXOESPROC GLeeFuncPtr_glLightModelxOES; + #define glLightModelxOES GLeeFuncPtr_glLightModelxOES +#endif +#ifndef GLEE_H_DEFINED_glLightModelxvOES +#define GLEE_H_DEFINED_glLightModelxvOES + typedef void (APIENTRYP GLEEPFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed * param); + GLEE_EXTERN GLEEPFNGLLIGHTMODELXVOESPROC GLeeFuncPtr_glLightModelxvOES; + #define glLightModelxvOES GLeeFuncPtr_glLightModelxvOES +#endif +#ifndef GLEE_H_DEFINED_glLightxOES +#define GLEE_H_DEFINED_glLightxOES + typedef void (APIENTRYP GLEEPFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLLIGHTXOESPROC GLeeFuncPtr_glLightxOES; + #define glLightxOES GLeeFuncPtr_glLightxOES +#endif +#ifndef GLEE_H_DEFINED_glLightxvOES +#define GLEE_H_DEFINED_glLightxvOES + typedef void (APIENTRYP GLEEPFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed * params); + GLEE_EXTERN GLEEPFNGLLIGHTXVOESPROC GLeeFuncPtr_glLightxvOES; + #define glLightxvOES GLeeFuncPtr_glLightxvOES +#endif +#ifndef GLEE_H_DEFINED_glLineWidthxOES +#define GLEE_H_DEFINED_glLineWidthxOES + typedef void (APIENTRYP GLEEPFNGLLINEWIDTHXOESPROC) (GLfixed width); + GLEE_EXTERN GLEEPFNGLLINEWIDTHXOESPROC GLeeFuncPtr_glLineWidthxOES; + #define glLineWidthxOES GLeeFuncPtr_glLineWidthxOES +#endif +#ifndef GLEE_H_DEFINED_glLoadMatrixxOES +#define GLEE_H_DEFINED_glLoadMatrixxOES + typedef void (APIENTRYP GLEEPFNGLLOADMATRIXXOESPROC) (const GLfixed * m); + GLEE_EXTERN GLEEPFNGLLOADMATRIXXOESPROC GLeeFuncPtr_glLoadMatrixxOES; + #define glLoadMatrixxOES GLeeFuncPtr_glLoadMatrixxOES +#endif +#ifndef GLEE_H_DEFINED_glLoadTransposeMatrixxOES +#define GLEE_H_DEFINED_glLoadTransposeMatrixxOES + typedef void (APIENTRYP GLEEPFNGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed * m); + GLEE_EXTERN GLEEPFNGLLOADTRANSPOSEMATRIXXOESPROC GLeeFuncPtr_glLoadTransposeMatrixxOES; + #define glLoadTransposeMatrixxOES GLeeFuncPtr_glLoadTransposeMatrixxOES +#endif +#ifndef GLEE_H_DEFINED_glMap1xOES +#define GLEE_H_DEFINED_glMap1xOES + typedef void (APIENTRYP GLEEPFNGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); + GLEE_EXTERN GLEEPFNGLMAP1XOESPROC GLeeFuncPtr_glMap1xOES; + #define glMap1xOES GLeeFuncPtr_glMap1xOES +#endif +#ifndef GLEE_H_DEFINED_glMap2xOES +#define GLEE_H_DEFINED_glMap2xOES + typedef void (APIENTRYP GLEEPFNGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); + GLEE_EXTERN GLEEPFNGLMAP2XOESPROC GLeeFuncPtr_glMap2xOES; + #define glMap2xOES GLeeFuncPtr_glMap2xOES +#endif +#ifndef GLEE_H_DEFINED_glMapGrid1xOES +#define GLEE_H_DEFINED_glMapGrid1xOES + typedef void (APIENTRYP GLEEPFNGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); + GLEE_EXTERN GLEEPFNGLMAPGRID1XOESPROC GLeeFuncPtr_glMapGrid1xOES; + #define glMapGrid1xOES GLeeFuncPtr_glMapGrid1xOES +#endif +#ifndef GLEE_H_DEFINED_glMapGrid2xOES +#define GLEE_H_DEFINED_glMapGrid2xOES + typedef void (APIENTRYP GLEEPFNGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); + GLEE_EXTERN GLEEPFNGLMAPGRID2XOESPROC GLeeFuncPtr_glMapGrid2xOES; + #define glMapGrid2xOES GLeeFuncPtr_glMapGrid2xOES +#endif +#ifndef GLEE_H_DEFINED_glMaterialxOES +#define GLEE_H_DEFINED_glMaterialxOES + typedef void (APIENTRYP GLEEPFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLMATERIALXOESPROC GLeeFuncPtr_glMaterialxOES; + #define glMaterialxOES GLeeFuncPtr_glMaterialxOES +#endif +#ifndef GLEE_H_DEFINED_glMaterialxvOES +#define GLEE_H_DEFINED_glMaterialxvOES + typedef void (APIENTRYP GLEEPFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed * param); + GLEE_EXTERN GLEEPFNGLMATERIALXVOESPROC GLeeFuncPtr_glMaterialxvOES; + #define glMaterialxvOES GLeeFuncPtr_glMaterialxvOES +#endif +#ifndef GLEE_H_DEFINED_glMultMatrixxOES +#define GLEE_H_DEFINED_glMultMatrixxOES + typedef void (APIENTRYP GLEEPFNGLMULTMATRIXXOESPROC) (const GLfixed * m); + GLEE_EXTERN GLEEPFNGLMULTMATRIXXOESPROC GLeeFuncPtr_glMultMatrixxOES; + #define glMultMatrixxOES GLeeFuncPtr_glMultMatrixxOES +#endif +#ifndef GLEE_H_DEFINED_glMultTransposeMatrixxOES +#define GLEE_H_DEFINED_glMultTransposeMatrixxOES + typedef void (APIENTRYP GLEEPFNGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed * m); + GLEE_EXTERN GLEEPFNGLMULTTRANSPOSEMATRIXXOESPROC GLeeFuncPtr_glMultTransposeMatrixxOES; + #define glMultTransposeMatrixxOES GLeeFuncPtr_glMultTransposeMatrixxOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1xOES +#define GLEE_H_DEFINED_glMultiTexCoord1xOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1XOESPROC GLeeFuncPtr_glMultiTexCoord1xOES; + #define glMultiTexCoord1xOES GLeeFuncPtr_glMultiTexCoord1xOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2xOES +#define GLEE_H_DEFINED_glMultiTexCoord2xOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2XOESPROC GLeeFuncPtr_glMultiTexCoord2xOES; + #define glMultiTexCoord2xOES GLeeFuncPtr_glMultiTexCoord2xOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3xOES +#define GLEE_H_DEFINED_glMultiTexCoord3xOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3XOESPROC GLeeFuncPtr_glMultiTexCoord3xOES; + #define glMultiTexCoord3xOES GLeeFuncPtr_glMultiTexCoord3xOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4xOES +#define GLEE_H_DEFINED_glMultiTexCoord4xOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4XOESPROC GLeeFuncPtr_glMultiTexCoord4xOES; + #define glMultiTexCoord4xOES GLeeFuncPtr_glMultiTexCoord4xOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord1xvOES +#define GLEE_H_DEFINED_glMultiTexCoord1xvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD1XVOESPROC GLeeFuncPtr_glMultiTexCoord1xvOES; + #define glMultiTexCoord1xvOES GLeeFuncPtr_glMultiTexCoord1xvOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord2xvOES +#define GLEE_H_DEFINED_glMultiTexCoord2xvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD2XVOESPROC GLeeFuncPtr_glMultiTexCoord2xvOES; + #define glMultiTexCoord2xvOES GLeeFuncPtr_glMultiTexCoord2xvOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord3xvOES +#define GLEE_H_DEFINED_glMultiTexCoord3xvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD3XVOESPROC GLeeFuncPtr_glMultiTexCoord3xvOES; + #define glMultiTexCoord3xvOES GLeeFuncPtr_glMultiTexCoord3xvOES +#endif +#ifndef GLEE_H_DEFINED_glMultiTexCoord4xvOES +#define GLEE_H_DEFINED_glMultiTexCoord4xvOES + typedef void (APIENTRYP GLEEPFNGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLMULTITEXCOORD4XVOESPROC GLeeFuncPtr_glMultiTexCoord4xvOES; + #define glMultiTexCoord4xvOES GLeeFuncPtr_glMultiTexCoord4xvOES +#endif +#ifndef GLEE_H_DEFINED_glNormal3xOES +#define GLEE_H_DEFINED_glNormal3xOES + typedef void (APIENTRYP GLEEPFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); + GLEE_EXTERN GLEEPFNGLNORMAL3XOESPROC GLeeFuncPtr_glNormal3xOES; + #define glNormal3xOES GLeeFuncPtr_glNormal3xOES +#endif +#ifndef GLEE_H_DEFINED_glNormal3xvOES +#define GLEE_H_DEFINED_glNormal3xvOES + typedef void (APIENTRYP GLEEPFNGLNORMAL3XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLNORMAL3XVOESPROC GLeeFuncPtr_glNormal3xvOES; + #define glNormal3xvOES GLeeFuncPtr_glNormal3xvOES +#endif +#ifndef GLEE_H_DEFINED_glOrthoxOES +#define GLEE_H_DEFINED_glOrthoxOES + typedef void (APIENTRYP GLEEPFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); + GLEE_EXTERN GLEEPFNGLORTHOXOESPROC GLeeFuncPtr_glOrthoxOES; + #define glOrthoxOES GLeeFuncPtr_glOrthoxOES +#endif +#ifndef GLEE_H_DEFINED_glPassThroughxOES +#define GLEE_H_DEFINED_glPassThroughxOES + typedef void (APIENTRYP GLEEPFNGLPASSTHROUGHXOESPROC) (GLfixed token); + GLEE_EXTERN GLEEPFNGLPASSTHROUGHXOESPROC GLeeFuncPtr_glPassThroughxOES; + #define glPassThroughxOES GLeeFuncPtr_glPassThroughxOES +#endif +#ifndef GLEE_H_DEFINED_glPixelMapx +#define GLEE_H_DEFINED_glPixelMapx + typedef void (APIENTRYP GLEEPFNGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed * values); + GLEE_EXTERN GLEEPFNGLPIXELMAPXPROC GLeeFuncPtr_glPixelMapx; + #define glPixelMapx GLeeFuncPtr_glPixelMapx +#endif +#ifndef GLEE_H_DEFINED_glPixelStorex +#define GLEE_H_DEFINED_glPixelStorex + typedef void (APIENTRYP GLEEPFNGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLPIXELSTOREXPROC GLeeFuncPtr_glPixelStorex; + #define glPixelStorex GLeeFuncPtr_glPixelStorex +#endif +#ifndef GLEE_H_DEFINED_glPixelTransferxOES +#define GLEE_H_DEFINED_glPixelTransferxOES + typedef void (APIENTRYP GLEEPFNGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLPIXELTRANSFERXOESPROC GLeeFuncPtr_glPixelTransferxOES; + #define glPixelTransferxOES GLeeFuncPtr_glPixelTransferxOES +#endif +#ifndef GLEE_H_DEFINED_glPixelZoomxOES +#define GLEE_H_DEFINED_glPixelZoomxOES + typedef void (APIENTRYP GLEEPFNGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); + GLEE_EXTERN GLEEPFNGLPIXELZOOMXOESPROC GLeeFuncPtr_glPixelZoomxOES; + #define glPixelZoomxOES GLeeFuncPtr_glPixelZoomxOES +#endif +#ifndef GLEE_H_DEFINED_glPointParameterxvOES +#define GLEE_H_DEFINED_glPointParameterxvOES + typedef void (APIENTRYP GLEEPFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed * params); + GLEE_EXTERN GLEEPFNGLPOINTPARAMETERXVOESPROC GLeeFuncPtr_glPointParameterxvOES; + #define glPointParameterxvOES GLeeFuncPtr_glPointParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glPointSizexOES +#define GLEE_H_DEFINED_glPointSizexOES + typedef void (APIENTRYP GLEEPFNGLPOINTSIZEXOESPROC) (GLfixed size); + GLEE_EXTERN GLEEPFNGLPOINTSIZEXOESPROC GLeeFuncPtr_glPointSizexOES; + #define glPointSizexOES GLeeFuncPtr_glPointSizexOES +#endif +#ifndef GLEE_H_DEFINED_glPolygonOffsetxOES +#define GLEE_H_DEFINED_glPolygonOffsetxOES + typedef void (APIENTRYP GLEEPFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); + GLEE_EXTERN GLEEPFNGLPOLYGONOFFSETXOESPROC GLeeFuncPtr_glPolygonOffsetxOES; + #define glPolygonOffsetxOES GLeeFuncPtr_glPolygonOffsetxOES +#endif +#ifndef GLEE_H_DEFINED_glPrioritizeTexturesxOES +#define GLEE_H_DEFINED_glPrioritizeTexturesxOES + typedef void (APIENTRYP GLEEPFNGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint * textures, const GLfixed * priorities); + GLEE_EXTERN GLEEPFNGLPRIORITIZETEXTURESXOESPROC GLeeFuncPtr_glPrioritizeTexturesxOES; + #define glPrioritizeTexturesxOES GLeeFuncPtr_glPrioritizeTexturesxOES +#endif +#ifndef GLEE_H_DEFINED_glRasterPos2xOES +#define GLEE_H_DEFINED_glRasterPos2xOES + typedef void (APIENTRYP GLEEPFNGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); + GLEE_EXTERN GLEEPFNGLRASTERPOS2XOESPROC GLeeFuncPtr_glRasterPos2xOES; + #define glRasterPos2xOES GLeeFuncPtr_glRasterPos2xOES +#endif +#ifndef GLEE_H_DEFINED_glRasterPos3xOES +#define GLEE_H_DEFINED_glRasterPos3xOES + typedef void (APIENTRYP GLEEPFNGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); + GLEE_EXTERN GLEEPFNGLRASTERPOS3XOESPROC GLeeFuncPtr_glRasterPos3xOES; + #define glRasterPos3xOES GLeeFuncPtr_glRasterPos3xOES +#endif +#ifndef GLEE_H_DEFINED_glRasterPos4xOES +#define GLEE_H_DEFINED_glRasterPos4xOES + typedef void (APIENTRYP GLEEPFNGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); + GLEE_EXTERN GLEEPFNGLRASTERPOS4XOESPROC GLeeFuncPtr_glRasterPos4xOES; + #define glRasterPos4xOES GLeeFuncPtr_glRasterPos4xOES +#endif +#ifndef GLEE_H_DEFINED_glRasterPos2xvOES +#define GLEE_H_DEFINED_glRasterPos2xvOES + typedef void (APIENTRYP GLEEPFNGLRASTERPOS2XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLRASTERPOS2XVOESPROC GLeeFuncPtr_glRasterPos2xvOES; + #define glRasterPos2xvOES GLeeFuncPtr_glRasterPos2xvOES +#endif +#ifndef GLEE_H_DEFINED_glRasterPos3xvOES +#define GLEE_H_DEFINED_glRasterPos3xvOES + typedef void (APIENTRYP GLEEPFNGLRASTERPOS3XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLRASTERPOS3XVOESPROC GLeeFuncPtr_glRasterPos3xvOES; + #define glRasterPos3xvOES GLeeFuncPtr_glRasterPos3xvOES +#endif +#ifndef GLEE_H_DEFINED_glRasterPos4xvOES +#define GLEE_H_DEFINED_glRasterPos4xvOES + typedef void (APIENTRYP GLEEPFNGLRASTERPOS4XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLRASTERPOS4XVOESPROC GLeeFuncPtr_glRasterPos4xvOES; + #define glRasterPos4xvOES GLeeFuncPtr_glRasterPos4xvOES +#endif +#ifndef GLEE_H_DEFINED_glRectxOES +#define GLEE_H_DEFINED_glRectxOES + typedef void (APIENTRYP GLEEPFNGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); + GLEE_EXTERN GLEEPFNGLRECTXOESPROC GLeeFuncPtr_glRectxOES; + #define glRectxOES GLeeFuncPtr_glRectxOES +#endif +#ifndef GLEE_H_DEFINED_glRectxvOES +#define GLEE_H_DEFINED_glRectxvOES + typedef void (APIENTRYP GLEEPFNGLRECTXVOESPROC) (const GLfixed * v1, const GLfixed * v2); + GLEE_EXTERN GLEEPFNGLRECTXVOESPROC GLeeFuncPtr_glRectxvOES; + #define glRectxvOES GLeeFuncPtr_glRectxvOES +#endif +#ifndef GLEE_H_DEFINED_glRotatexOES +#define GLEE_H_DEFINED_glRotatexOES + typedef void (APIENTRYP GLEEPFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); + GLEE_EXTERN GLEEPFNGLROTATEXOESPROC GLeeFuncPtr_glRotatexOES; + #define glRotatexOES GLeeFuncPtr_glRotatexOES +#endif +#ifndef GLEE_H_DEFINED_glSampleCoverageOES +#define GLEE_H_DEFINED_glSampleCoverageOES + typedef void (APIENTRYP GLEEPFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); + GLEE_EXTERN GLEEPFNGLSAMPLECOVERAGEOESPROC GLeeFuncPtr_glSampleCoverageOES; + #define glSampleCoverageOES GLeeFuncPtr_glSampleCoverageOES +#endif +#ifndef GLEE_H_DEFINED_glScalexOES +#define GLEE_H_DEFINED_glScalexOES + typedef void (APIENTRYP GLEEPFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); + GLEE_EXTERN GLEEPFNGLSCALEXOESPROC GLeeFuncPtr_glScalexOES; + #define glScalexOES GLeeFuncPtr_glScalexOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord1xOES +#define GLEE_H_DEFINED_glTexCoord1xOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD1XOESPROC) (GLfixed s); + GLEE_EXTERN GLEEPFNGLTEXCOORD1XOESPROC GLeeFuncPtr_glTexCoord1xOES; + #define glTexCoord1xOES GLeeFuncPtr_glTexCoord1xOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2xOES +#define GLEE_H_DEFINED_glTexCoord2xOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); + GLEE_EXTERN GLEEPFNGLTEXCOORD2XOESPROC GLeeFuncPtr_glTexCoord2xOES; + #define glTexCoord2xOES GLeeFuncPtr_glTexCoord2xOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord3xOES +#define GLEE_H_DEFINED_glTexCoord3xOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); + GLEE_EXTERN GLEEPFNGLTEXCOORD3XOESPROC GLeeFuncPtr_glTexCoord3xOES; + #define glTexCoord3xOES GLeeFuncPtr_glTexCoord3xOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4xOES +#define GLEE_H_DEFINED_glTexCoord4xOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); + GLEE_EXTERN GLEEPFNGLTEXCOORD4XOESPROC GLeeFuncPtr_glTexCoord4xOES; + #define glTexCoord4xOES GLeeFuncPtr_glTexCoord4xOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord1xvOES +#define GLEE_H_DEFINED_glTexCoord1xvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD1XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD1XVOESPROC GLeeFuncPtr_glTexCoord1xvOES; + #define glTexCoord1xvOES GLeeFuncPtr_glTexCoord1xvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord2xvOES +#define GLEE_H_DEFINED_glTexCoord2xvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD2XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD2XVOESPROC GLeeFuncPtr_glTexCoord2xvOES; + #define glTexCoord2xvOES GLeeFuncPtr_glTexCoord2xvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord3xvOES +#define GLEE_H_DEFINED_glTexCoord3xvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD3XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD3XVOESPROC GLeeFuncPtr_glTexCoord3xvOES; + #define glTexCoord3xvOES GLeeFuncPtr_glTexCoord3xvOES +#endif +#ifndef GLEE_H_DEFINED_glTexCoord4xvOES +#define GLEE_H_DEFINED_glTexCoord4xvOES + typedef void (APIENTRYP GLEEPFNGLTEXCOORD4XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLTEXCOORD4XVOESPROC GLeeFuncPtr_glTexCoord4xvOES; + #define glTexCoord4xvOES GLeeFuncPtr_glTexCoord4xvOES +#endif +#ifndef GLEE_H_DEFINED_glTexEnvxOES +#define GLEE_H_DEFINED_glTexEnvxOES + typedef void (APIENTRYP GLEEPFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLTEXENVXOESPROC GLeeFuncPtr_glTexEnvxOES; + #define glTexEnvxOES GLeeFuncPtr_glTexEnvxOES +#endif +#ifndef GLEE_H_DEFINED_glTexEnvxvOES +#define GLEE_H_DEFINED_glTexEnvxvOES + typedef void (APIENTRYP GLEEPFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed * params); + GLEE_EXTERN GLEEPFNGLTEXENVXVOESPROC GLeeFuncPtr_glTexEnvxvOES; + #define glTexEnvxvOES GLeeFuncPtr_glTexEnvxvOES +#endif +#ifndef GLEE_H_DEFINED_glTexGenxOES +#define GLEE_H_DEFINED_glTexGenxOES + typedef void (APIENTRYP GLEEPFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLTEXGENXOESPROC GLeeFuncPtr_glTexGenxOES; + #define glTexGenxOES GLeeFuncPtr_glTexGenxOES +#endif +#ifndef GLEE_H_DEFINED_glTexGenxvOES +#define GLEE_H_DEFINED_glTexGenxvOES + typedef void (APIENTRYP GLEEPFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed * params); + GLEE_EXTERN GLEEPFNGLTEXGENXVOESPROC GLeeFuncPtr_glTexGenxvOES; + #define glTexGenxvOES GLeeFuncPtr_glTexGenxvOES +#endif +#ifndef GLEE_H_DEFINED_glTexParameterxOES +#define GLEE_H_DEFINED_glTexParameterxOES + typedef void (APIENTRYP GLEEPFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); + GLEE_EXTERN GLEEPFNGLTEXPARAMETERXOESPROC GLeeFuncPtr_glTexParameterxOES; + #define glTexParameterxOES GLeeFuncPtr_glTexParameterxOES +#endif +#ifndef GLEE_H_DEFINED_glTexParameterxvOES +#define GLEE_H_DEFINED_glTexParameterxvOES + typedef void (APIENTRYP GLEEPFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed * params); + GLEE_EXTERN GLEEPFNGLTEXPARAMETERXVOESPROC GLeeFuncPtr_glTexParameterxvOES; + #define glTexParameterxvOES GLeeFuncPtr_glTexParameterxvOES +#endif +#ifndef GLEE_H_DEFINED_glTranslatexOES +#define GLEE_H_DEFINED_glTranslatexOES + typedef void (APIENTRYP GLEEPFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); + GLEE_EXTERN GLEEPFNGLTRANSLATEXOESPROC GLeeFuncPtr_glTranslatexOES; + #define glTranslatexOES GLeeFuncPtr_glTranslatexOES +#endif +#ifndef GLEE_H_DEFINED_glVertex2xOES +#define GLEE_H_DEFINED_glVertex2xOES + typedef void (APIENTRYP GLEEPFNGLVERTEX2XOESPROC) (GLfixed x); + GLEE_EXTERN GLEEPFNGLVERTEX2XOESPROC GLeeFuncPtr_glVertex2xOES; + #define glVertex2xOES GLeeFuncPtr_glVertex2xOES +#endif +#ifndef GLEE_H_DEFINED_glVertex3xOES +#define GLEE_H_DEFINED_glVertex3xOES + typedef void (APIENTRYP GLEEPFNGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); + GLEE_EXTERN GLEEPFNGLVERTEX3XOESPROC GLeeFuncPtr_glVertex3xOES; + #define glVertex3xOES GLeeFuncPtr_glVertex3xOES +#endif +#ifndef GLEE_H_DEFINED_glVertex4xOES +#define GLEE_H_DEFINED_glVertex4xOES + typedef void (APIENTRYP GLEEPFNGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); + GLEE_EXTERN GLEEPFNGLVERTEX4XOESPROC GLeeFuncPtr_glVertex4xOES; + #define glVertex4xOES GLeeFuncPtr_glVertex4xOES +#endif +#ifndef GLEE_H_DEFINED_glVertex2xvOES +#define GLEE_H_DEFINED_glVertex2xvOES + typedef void (APIENTRYP GLEEPFNGLVERTEX2XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLVERTEX2XVOESPROC GLeeFuncPtr_glVertex2xvOES; + #define glVertex2xvOES GLeeFuncPtr_glVertex2xvOES +#endif +#ifndef GLEE_H_DEFINED_glVertex3xvOES +#define GLEE_H_DEFINED_glVertex3xvOES + typedef void (APIENTRYP GLEEPFNGLVERTEX3XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLVERTEX3XVOESPROC GLeeFuncPtr_glVertex3xvOES; + #define glVertex3xvOES GLeeFuncPtr_glVertex3xvOES +#endif +#ifndef GLEE_H_DEFINED_glVertex4xvOES +#define GLEE_H_DEFINED_glVertex4xvOES + typedef void (APIENTRYP GLEEPFNGLVERTEX4XVOESPROC) (const GLfixed * coords); + GLEE_EXTERN GLEEPFNGLVERTEX4XVOESPROC GLeeFuncPtr_glVertex4xvOES; + #define glVertex4xvOES GLeeFuncPtr_glVertex4xvOES +#endif +#endif + +/* GL_OES_single_precision */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 +#define __GLEE_GL_OES_single_precision 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glDepthRangefOES +#define GLEE_H_DEFINED_glDepthRangefOES + typedef void (APIENTRYP GLEEPFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); + GLEE_EXTERN GLEEPFNGLDEPTHRANGEFOESPROC GLeeFuncPtr_glDepthRangefOES; + #define glDepthRangefOES GLeeFuncPtr_glDepthRangefOES +#endif +#ifndef GLEE_H_DEFINED_glFrustumfOES +#define GLEE_H_DEFINED_glFrustumfOES + typedef void (APIENTRYP GLEEPFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + GLEE_EXTERN GLEEPFNGLFRUSTUMFOESPROC GLeeFuncPtr_glFrustumfOES; + #define glFrustumfOES GLeeFuncPtr_glFrustumfOES +#endif +#ifndef GLEE_H_DEFINED_glOrthofOES +#define GLEE_H_DEFINED_glOrthofOES + typedef void (APIENTRYP GLEEPFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + GLEE_EXTERN GLEEPFNGLORTHOFOESPROC GLeeFuncPtr_glOrthofOES; + #define glOrthofOES GLeeFuncPtr_glOrthofOES +#endif +#ifndef GLEE_H_DEFINED_glClipPlanefOES +#define GLEE_H_DEFINED_glClipPlanefOES + typedef void (APIENTRYP GLEEPFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat * equation); + GLEE_EXTERN GLEEPFNGLCLIPPLANEFOESPROC GLeeFuncPtr_glClipPlanefOES; + #define glClipPlanefOES GLeeFuncPtr_glClipPlanefOES +#endif +#ifndef GLEE_H_DEFINED_glClearDepthfOES +#define GLEE_H_DEFINED_glClearDepthfOES + typedef void (APIENTRYP GLEEPFNGLCLEARDEPTHFOESPROC) (GLclampd depth); + GLEE_EXTERN GLEEPFNGLCLEARDEPTHFOESPROC GLeeFuncPtr_glClearDepthfOES; + #define glClearDepthfOES GLeeFuncPtr_glClearDepthfOES +#endif +#ifndef GLEE_H_DEFINED_glGetClipPlanefOES +#define GLEE_H_DEFINED_glGetClipPlanefOES + typedef void (APIENTRYP GLEEPFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat * equation); + GLEE_EXTERN GLEEPFNGLGETCLIPPLANEFOESPROC GLeeFuncPtr_glGetClipPlanefOES; + #define glGetClipPlanefOES GLeeFuncPtr_glGetClipPlanefOES +#endif +#endif + +/* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define __GLEE_GL_OES_compressed_paletted_texture 1 +/* Constants */ +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + /* GL_OES_read_format */ #ifndef GL_OES_read_format @@ -15080,6 +16921,20 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B #endif +/* GL_OES_query_matrix */ + +#ifndef GL_OES_query_matrix +#define GL_OES_query_matrix 1 +#define __GLEE_GL_OES_query_matrix 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glQueryMatrixxOES +#define GLEE_H_DEFINED_glQueryMatrixxOES + typedef GLbitfield (APIENTRYP GLEEPFNGLQUERYMATRIXXOESPROC) (const GLfixed * mantissa, const GLint * exponent); + GLEE_EXTERN GLEEPFNGLQUERYMATRIXXOESPROC GLeeFuncPtr_glQueryMatrixxOES; + #define glQueryMatrixxOES GLeeFuncPtr_glQueryMatrixxOES +#endif +#endif + /* GL_EXT_depth_bounds_test */ #ifndef GL_EXT_depth_bounds_test @@ -15810,19 +17665,19 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 #ifndef GLEE_H_DEFINED_glProgramBufferParametersfvNV #define GLEE_H_DEFINED_glProgramBufferParametersfvNV - typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat * params); + typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat * params); GLEE_EXTERN GLEEPFNGLPROGRAMBUFFERPARAMETERSFVNVPROC GLeeFuncPtr_glProgramBufferParametersfvNV; #define glProgramBufferParametersfvNV GLeeFuncPtr_glProgramBufferParametersfvNV #endif #ifndef GLEE_H_DEFINED_glProgramBufferParametersIivNV #define GLEE_H_DEFINED_glProgramBufferParametersIivNV - typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint * params); + typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint * params); GLEE_EXTERN GLEEPFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC GLeeFuncPtr_glProgramBufferParametersIivNV; #define glProgramBufferParametersIivNV GLeeFuncPtr_glProgramBufferParametersIivNV #endif #ifndef GLEE_H_DEFINED_glProgramBufferParametersIuivNV #define GLEE_H_DEFINED_glProgramBufferParametersIuivNV - typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint * params); + typedef void (APIENTRYP GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint * params); GLEE_EXTERN GLEEPFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC GLeeFuncPtr_glProgramBufferParametersIuivNV; #define glProgramBufferParametersIuivNV GLeeFuncPtr_glProgramBufferParametersIuivNV #endif @@ -15897,7 +17752,7 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_PRIMITIVES_GENERATED_NV 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 #define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B #define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C #define GL_SEPARATE_ATTRIBS_NV 0x8C8D @@ -18984,6 +20839,52 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #endif +/* GL_AMD_debug_output */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 +#define __GLEE_GL_AMD_debug_output 1 +/* Constants */ +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 +#ifndef GLEE_H_DEFINED_glDebugMessageEnableAMD +#define GLEE_H_DEFINED_glDebugMessageEnableAMD + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGEENABLEAMDPROC GLeeFuncPtr_glDebugMessageEnableAMD; + #define glDebugMessageEnableAMD GLeeFuncPtr_glDebugMessageEnableAMD +#endif +#ifndef GLEE_H_DEFINED_glDebugMessageInsertAMD +#define GLEE_H_DEFINED_glDebugMessageInsertAMD + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar * buf); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGEINSERTAMDPROC GLeeFuncPtr_glDebugMessageInsertAMD; + #define glDebugMessageInsertAMD GLeeFuncPtr_glDebugMessageInsertAMD +#endif +#ifndef GLEE_H_DEFINED_glDebugMessageCallbackAMD +#define GLEE_H_DEFINED_glDebugMessageCallbackAMD + typedef void (APIENTRYP GLEEPFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid * userParam); + GLEE_EXTERN GLEEPFNGLDEBUGMESSAGECALLBACKAMDPROC GLeeFuncPtr_glDebugMessageCallbackAMD; + #define glDebugMessageCallbackAMD GLeeFuncPtr_glDebugMessageCallbackAMD +#endif +#ifndef GLEE_H_DEFINED_glGetDebugMessageLogAMD +#define GLEE_H_DEFINED_glGetDebugMessageLogAMD + typedef GLuint (APIENTRYP GLEEPFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum * categories, GLuint * severities, GLuint * ids, GLsizei * lengths, GLchar * message); + GLEE_EXTERN GLEEPFNGLGETDEBUGMESSAGELOGAMDPROC GLeeFuncPtr_glGetDebugMessageLogAMD; + #define glGetDebugMessageLogAMD GLeeFuncPtr_glGetDebugMessageLogAMD +#endif +#endif + /* GL_AMD_transform_feedback3_lines_triangles */ #ifndef GL_AMD_transform_feedback3_lines_triangles @@ -19129,6 +21030,720 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB #endif +/* GL_NV_path_rendering */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define __GLEE_GL_NV_path_rendering 1 +/* Constants */ +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#ifndef GLEE_H_DEFINED_glGenPathsNV +#define GLEE_H_DEFINED_glGenPathsNV + typedef GLuint (APIENTRYP GLEEPFNGLGENPATHSNVPROC) (GLsizei range); + GLEE_EXTERN GLEEPFNGLGENPATHSNVPROC GLeeFuncPtr_glGenPathsNV; + #define glGenPathsNV GLeeFuncPtr_glGenPathsNV +#endif +#ifndef GLEE_H_DEFINED_glDeletePathsNV +#define GLEE_H_DEFINED_glDeletePathsNV + typedef void (APIENTRYP GLEEPFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); + GLEE_EXTERN GLEEPFNGLDELETEPATHSNVPROC GLeeFuncPtr_glDeletePathsNV; + #define glDeletePathsNV GLeeFuncPtr_glDeletePathsNV +#endif +#ifndef GLEE_H_DEFINED_glIsPathNV +#define GLEE_H_DEFINED_glIsPathNV + typedef GLboolean (APIENTRYP GLEEPFNGLISPATHNVPROC) (GLuint path); + GLEE_EXTERN GLEEPFNGLISPATHNVPROC GLeeFuncPtr_glIsPathNV; + #define glIsPathNV GLeeFuncPtr_glIsPathNV +#endif +#ifndef GLEE_H_DEFINED_glPathCommandsNV +#define GLEE_H_DEFINED_glPathCommandsNV + typedef void (APIENTRYP GLEEPFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte * commands, GLsizei numCoords, GLenum coordType, const GLvoid * coords); + GLEE_EXTERN GLEEPFNGLPATHCOMMANDSNVPROC GLeeFuncPtr_glPathCommandsNV; + #define glPathCommandsNV GLeeFuncPtr_glPathCommandsNV +#endif +#ifndef GLEE_H_DEFINED_glPathCoordsNV +#define GLEE_H_DEFINED_glPathCoordsNV + typedef void (APIENTRYP GLEEPFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const GLvoid * coords); + GLEE_EXTERN GLEEPFNGLPATHCOORDSNVPROC GLeeFuncPtr_glPathCoordsNV; + #define glPathCoordsNV GLeeFuncPtr_glPathCoordsNV +#endif +#ifndef GLEE_H_DEFINED_glPathSubCommandsNV +#define GLEE_H_DEFINED_glPathSubCommandsNV + typedef void (APIENTRYP GLEEPFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte * commands, GLsizei numCoords, GLenum coordType, const GLvoid * coords); + GLEE_EXTERN GLEEPFNGLPATHSUBCOMMANDSNVPROC GLeeFuncPtr_glPathSubCommandsNV; + #define glPathSubCommandsNV GLeeFuncPtr_glPathSubCommandsNV +#endif +#ifndef GLEE_H_DEFINED_glPathSubCoordsNV +#define GLEE_H_DEFINED_glPathSubCoordsNV + typedef void (APIENTRYP GLEEPFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const GLvoid * coords); + GLEE_EXTERN GLEEPFNGLPATHSUBCOORDSNVPROC GLeeFuncPtr_glPathSubCoordsNV; + #define glPathSubCoordsNV GLeeFuncPtr_glPathSubCoordsNV +#endif +#ifndef GLEE_H_DEFINED_glPathStringNV +#define GLEE_H_DEFINED_glPathStringNV + typedef void (APIENTRYP GLEEPFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const GLvoid * pathString); + GLEE_EXTERN GLEEPFNGLPATHSTRINGNVPROC GLeeFuncPtr_glPathStringNV; + #define glPathStringNV GLeeFuncPtr_glPathStringNV +#endif +#ifndef GLEE_H_DEFINED_glPathGlyphsNV +#define GLEE_H_DEFINED_glPathGlyphsNV + typedef void (APIENTRYP GLEEPFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const GLvoid * fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const GLvoid * charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); + GLEE_EXTERN GLEEPFNGLPATHGLYPHSNVPROC GLeeFuncPtr_glPathGlyphsNV; + #define glPathGlyphsNV GLeeFuncPtr_glPathGlyphsNV +#endif +#ifndef GLEE_H_DEFINED_glPathGlyphRangeNV +#define GLEE_H_DEFINED_glPathGlyphRangeNV + typedef void (APIENTRYP GLEEPFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const GLvoid * fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); + GLEE_EXTERN GLEEPFNGLPATHGLYPHRANGENVPROC GLeeFuncPtr_glPathGlyphRangeNV; + #define glPathGlyphRangeNV GLeeFuncPtr_glPathGlyphRangeNV +#endif +#ifndef GLEE_H_DEFINED_glWeightPathsNV +#define GLEE_H_DEFINED_glWeightPathsNV + typedef void (APIENTRYP GLEEPFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint * paths, const GLfloat * weights); + GLEE_EXTERN GLEEPFNGLWEIGHTPATHSNVPROC GLeeFuncPtr_glWeightPathsNV; + #define glWeightPathsNV GLeeFuncPtr_glWeightPathsNV +#endif +#ifndef GLEE_H_DEFINED_glCopyPathNV +#define GLEE_H_DEFINED_glCopyPathNV + typedef void (APIENTRYP GLEEPFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); + GLEE_EXTERN GLEEPFNGLCOPYPATHNVPROC GLeeFuncPtr_glCopyPathNV; + #define glCopyPathNV GLeeFuncPtr_glCopyPathNV +#endif +#ifndef GLEE_H_DEFINED_glInterpolatePathsNV +#define GLEE_H_DEFINED_glInterpolatePathsNV + typedef void (APIENTRYP GLEEPFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); + GLEE_EXTERN GLEEPFNGLINTERPOLATEPATHSNVPROC GLeeFuncPtr_glInterpolatePathsNV; + #define glInterpolatePathsNV GLeeFuncPtr_glInterpolatePathsNV +#endif +#ifndef GLEE_H_DEFINED_glTransformPathNV +#define GLEE_H_DEFINED_glTransformPathNV + typedef void (APIENTRYP GLEEPFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat * transformValues); + GLEE_EXTERN GLEEPFNGLTRANSFORMPATHNVPROC GLeeFuncPtr_glTransformPathNV; + #define glTransformPathNV GLeeFuncPtr_glTransformPathNV +#endif +#ifndef GLEE_H_DEFINED_glPathParameterivNV +#define GLEE_H_DEFINED_glPathParameterivNV + typedef void (APIENTRYP GLEEPFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint * value); + GLEE_EXTERN GLEEPFNGLPATHPARAMETERIVNVPROC GLeeFuncPtr_glPathParameterivNV; + #define glPathParameterivNV GLeeFuncPtr_glPathParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glPathParameteriNV +#define GLEE_H_DEFINED_glPathParameteriNV + typedef void (APIENTRYP GLEEPFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); + GLEE_EXTERN GLEEPFNGLPATHPARAMETERINVPROC GLeeFuncPtr_glPathParameteriNV; + #define glPathParameteriNV GLeeFuncPtr_glPathParameteriNV +#endif +#ifndef GLEE_H_DEFINED_glPathParameterfvNV +#define GLEE_H_DEFINED_glPathParameterfvNV + typedef void (APIENTRYP GLEEPFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat * value); + GLEE_EXTERN GLEEPFNGLPATHPARAMETERFVNVPROC GLeeFuncPtr_glPathParameterfvNV; + #define glPathParameterfvNV GLeeFuncPtr_glPathParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glPathParameterfNV +#define GLEE_H_DEFINED_glPathParameterfNV + typedef void (APIENTRYP GLEEPFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); + GLEE_EXTERN GLEEPFNGLPATHPARAMETERFNVPROC GLeeFuncPtr_glPathParameterfNV; + #define glPathParameterfNV GLeeFuncPtr_glPathParameterfNV +#endif +#ifndef GLEE_H_DEFINED_glPathDashArrayNV +#define GLEE_H_DEFINED_glPathDashArrayNV + typedef void (APIENTRYP GLEEPFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat * dashArray); + GLEE_EXTERN GLEEPFNGLPATHDASHARRAYNVPROC GLeeFuncPtr_glPathDashArrayNV; + #define glPathDashArrayNV GLeeFuncPtr_glPathDashArrayNV +#endif +#ifndef GLEE_H_DEFINED_glPathStencilFuncNV +#define GLEE_H_DEFINED_glPathStencilFuncNV + typedef void (APIENTRYP GLEEPFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); + GLEE_EXTERN GLEEPFNGLPATHSTENCILFUNCNVPROC GLeeFuncPtr_glPathStencilFuncNV; + #define glPathStencilFuncNV GLeeFuncPtr_glPathStencilFuncNV +#endif +#ifndef GLEE_H_DEFINED_glPathStencilDepthOffsetNV +#define GLEE_H_DEFINED_glPathStencilDepthOffsetNV + typedef void (APIENTRYP GLEEPFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); + GLEE_EXTERN GLEEPFNGLPATHSTENCILDEPTHOFFSETNVPROC GLeeFuncPtr_glPathStencilDepthOffsetNV; + #define glPathStencilDepthOffsetNV GLeeFuncPtr_glPathStencilDepthOffsetNV +#endif +#ifndef GLEE_H_DEFINED_glStencilFillPathNV +#define GLEE_H_DEFINED_glStencilFillPathNV + typedef void (APIENTRYP GLEEPFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); + GLEE_EXTERN GLEEPFNGLSTENCILFILLPATHNVPROC GLeeFuncPtr_glStencilFillPathNV; + #define glStencilFillPathNV GLeeFuncPtr_glStencilFillPathNV +#endif +#ifndef GLEE_H_DEFINED_glStencilStrokePathNV +#define GLEE_H_DEFINED_glStencilStrokePathNV + typedef void (APIENTRYP GLEEPFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); + GLEE_EXTERN GLEEPFNGLSTENCILSTROKEPATHNVPROC GLeeFuncPtr_glStencilStrokePathNV; + #define glStencilStrokePathNV GLeeFuncPtr_glStencilStrokePathNV +#endif +#ifndef GLEE_H_DEFINED_glStencilFillPathInstancedNV +#define GLEE_H_DEFINED_glStencilFillPathInstancedNV + typedef void (APIENTRYP GLEEPFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat * transformValues); + GLEE_EXTERN GLEEPFNGLSTENCILFILLPATHINSTANCEDNVPROC GLeeFuncPtr_glStencilFillPathInstancedNV; + #define glStencilFillPathInstancedNV GLeeFuncPtr_glStencilFillPathInstancedNV +#endif +#ifndef GLEE_H_DEFINED_glStencilStrokePathInstancedNV +#define GLEE_H_DEFINED_glStencilStrokePathInstancedNV + typedef void (APIENTRYP GLEEPFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat * transformValues); + GLEE_EXTERN GLEEPFNGLSTENCILSTROKEPATHINSTANCEDNVPROC GLeeFuncPtr_glStencilStrokePathInstancedNV; + #define glStencilStrokePathInstancedNV GLeeFuncPtr_glStencilStrokePathInstancedNV +#endif +#ifndef GLEE_H_DEFINED_glPathCoverDepthFuncNV +#define GLEE_H_DEFINED_glPathCoverDepthFuncNV + typedef void (APIENTRYP GLEEPFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); + GLEE_EXTERN GLEEPFNGLPATHCOVERDEPTHFUNCNVPROC GLeeFuncPtr_glPathCoverDepthFuncNV; + #define glPathCoverDepthFuncNV GLeeFuncPtr_glPathCoverDepthFuncNV +#endif +#ifndef GLEE_H_DEFINED_glPathColorGenNV +#define GLEE_H_DEFINED_glPathColorGenNV + typedef void (APIENTRYP GLEEPFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat * coeffs); + GLEE_EXTERN GLEEPFNGLPATHCOLORGENNVPROC GLeeFuncPtr_glPathColorGenNV; + #define glPathColorGenNV GLeeFuncPtr_glPathColorGenNV +#endif +#ifndef GLEE_H_DEFINED_glPathTexGenNV +#define GLEE_H_DEFINED_glPathTexGenNV + typedef void (APIENTRYP GLEEPFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat * coeffs); + GLEE_EXTERN GLEEPFNGLPATHTEXGENNVPROC GLeeFuncPtr_glPathTexGenNV; + #define glPathTexGenNV GLeeFuncPtr_glPathTexGenNV +#endif +#ifndef GLEE_H_DEFINED_glPathFogGenNV +#define GLEE_H_DEFINED_glPathFogGenNV + typedef void (APIENTRYP GLEEPFNGLPATHFOGGENNVPROC) (GLenum genMode); + GLEE_EXTERN GLEEPFNGLPATHFOGGENNVPROC GLeeFuncPtr_glPathFogGenNV; + #define glPathFogGenNV GLeeFuncPtr_glPathFogGenNV +#endif +#ifndef GLEE_H_DEFINED_glCoverFillPathNV +#define GLEE_H_DEFINED_glCoverFillPathNV + typedef void (APIENTRYP GLEEPFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); + GLEE_EXTERN GLEEPFNGLCOVERFILLPATHNVPROC GLeeFuncPtr_glCoverFillPathNV; + #define glCoverFillPathNV GLeeFuncPtr_glCoverFillPathNV +#endif +#ifndef GLEE_H_DEFINED_glCoverStrokePathNV +#define GLEE_H_DEFINED_glCoverStrokePathNV + typedef void (APIENTRYP GLEEPFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); + GLEE_EXTERN GLEEPFNGLCOVERSTROKEPATHNVPROC GLeeFuncPtr_glCoverStrokePathNV; + #define glCoverStrokePathNV GLeeFuncPtr_glCoverStrokePathNV +#endif +#ifndef GLEE_H_DEFINED_glCoverFillPathInstancedNV +#define GLEE_H_DEFINED_glCoverFillPathInstancedNV + typedef void (APIENTRYP GLEEPFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat * transformValues); + GLEE_EXTERN GLEEPFNGLCOVERFILLPATHINSTANCEDNVPROC GLeeFuncPtr_glCoverFillPathInstancedNV; + #define glCoverFillPathInstancedNV GLeeFuncPtr_glCoverFillPathInstancedNV +#endif +#ifndef GLEE_H_DEFINED_glCoverStrokePathInstancedNV +#define GLEE_H_DEFINED_glCoverStrokePathInstancedNV + typedef void (APIENTRYP GLEEPFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat * transformValues); + GLEE_EXTERN GLEEPFNGLCOVERSTROKEPATHINSTANCEDNVPROC GLeeFuncPtr_glCoverStrokePathInstancedNV; + #define glCoverStrokePathInstancedNV GLeeFuncPtr_glCoverStrokePathInstancedNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathParameterivNV +#define GLEE_H_DEFINED_glGetPathParameterivNV + typedef void (APIENTRYP GLEEPFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint * value); + GLEE_EXTERN GLEEPFNGLGETPATHPARAMETERIVNVPROC GLeeFuncPtr_glGetPathParameterivNV; + #define glGetPathParameterivNV GLeeFuncPtr_glGetPathParameterivNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathParameterfvNV +#define GLEE_H_DEFINED_glGetPathParameterfvNV + typedef void (APIENTRYP GLEEPFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat * value); + GLEE_EXTERN GLEEPFNGLGETPATHPARAMETERFVNVPROC GLeeFuncPtr_glGetPathParameterfvNV; + #define glGetPathParameterfvNV GLeeFuncPtr_glGetPathParameterfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathCommandsNV +#define GLEE_H_DEFINED_glGetPathCommandsNV + typedef void (APIENTRYP GLEEPFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte * commands); + GLEE_EXTERN GLEEPFNGLGETPATHCOMMANDSNVPROC GLeeFuncPtr_glGetPathCommandsNV; + #define glGetPathCommandsNV GLeeFuncPtr_glGetPathCommandsNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathCoordsNV +#define GLEE_H_DEFINED_glGetPathCoordsNV + typedef void (APIENTRYP GLEEPFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat * coords); + GLEE_EXTERN GLEEPFNGLGETPATHCOORDSNVPROC GLeeFuncPtr_glGetPathCoordsNV; + #define glGetPathCoordsNV GLeeFuncPtr_glGetPathCoordsNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathDashArrayNV +#define GLEE_H_DEFINED_glGetPathDashArrayNV + typedef void (APIENTRYP GLEEPFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat * dashArray); + GLEE_EXTERN GLEEPFNGLGETPATHDASHARRAYNVPROC GLeeFuncPtr_glGetPathDashArrayNV; + #define glGetPathDashArrayNV GLeeFuncPtr_glGetPathDashArrayNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathMetricsNV +#define GLEE_H_DEFINED_glGetPathMetricsNV + typedef void (APIENTRYP GLEEPFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLsizei stride, GLfloat * metrics); + GLEE_EXTERN GLEEPFNGLGETPATHMETRICSNVPROC GLeeFuncPtr_glGetPathMetricsNV; + #define glGetPathMetricsNV GLeeFuncPtr_glGetPathMetricsNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathMetricRangeNV +#define GLEE_H_DEFINED_glGetPathMetricRangeNV + typedef void (APIENTRYP GLEEPFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat * metrics); + GLEE_EXTERN GLEEPFNGLGETPATHMETRICRANGENVPROC GLeeFuncPtr_glGetPathMetricRangeNV; + #define glGetPathMetricRangeNV GLeeFuncPtr_glGetPathMetricRangeNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathSpacingNV +#define GLEE_H_DEFINED_glGetPathSpacingNV + typedef void (APIENTRYP GLEEPFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const GLvoid * paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat * returnedSpacing); + GLEE_EXTERN GLEEPFNGLGETPATHSPACINGNVPROC GLeeFuncPtr_glGetPathSpacingNV; + #define glGetPathSpacingNV GLeeFuncPtr_glGetPathSpacingNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathColorGenivNV +#define GLEE_H_DEFINED_glGetPathColorGenivNV + typedef void (APIENTRYP GLEEPFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint * value); + GLEE_EXTERN GLEEPFNGLGETPATHCOLORGENIVNVPROC GLeeFuncPtr_glGetPathColorGenivNV; + #define glGetPathColorGenivNV GLeeFuncPtr_glGetPathColorGenivNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathColorGenfvNV +#define GLEE_H_DEFINED_glGetPathColorGenfvNV + typedef void (APIENTRYP GLEEPFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat * value); + GLEE_EXTERN GLEEPFNGLGETPATHCOLORGENFVNVPROC GLeeFuncPtr_glGetPathColorGenfvNV; + #define glGetPathColorGenfvNV GLeeFuncPtr_glGetPathColorGenfvNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathTexGenivNV +#define GLEE_H_DEFINED_glGetPathTexGenivNV + typedef void (APIENTRYP GLEEPFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint * value); + GLEE_EXTERN GLEEPFNGLGETPATHTEXGENIVNVPROC GLeeFuncPtr_glGetPathTexGenivNV; + #define glGetPathTexGenivNV GLeeFuncPtr_glGetPathTexGenivNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathTexGenfvNV +#define GLEE_H_DEFINED_glGetPathTexGenfvNV + typedef void (APIENTRYP GLEEPFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat * value); + GLEE_EXTERN GLEEPFNGLGETPATHTEXGENFVNVPROC GLeeFuncPtr_glGetPathTexGenfvNV; + #define glGetPathTexGenfvNV GLeeFuncPtr_glGetPathTexGenfvNV +#endif +#ifndef GLEE_H_DEFINED_glIsPointInFillPathNV +#define GLEE_H_DEFINED_glIsPointInFillPathNV + typedef GLboolean (APIENTRYP GLEEPFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLISPOINTINFILLPATHNVPROC GLeeFuncPtr_glIsPointInFillPathNV; + #define glIsPointInFillPathNV GLeeFuncPtr_glIsPointInFillPathNV +#endif +#ifndef GLEE_H_DEFINED_glIsPointInStrokePathNV +#define GLEE_H_DEFINED_glIsPointInStrokePathNV + typedef GLboolean (APIENTRYP GLEEPFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); + GLEE_EXTERN GLEEPFNGLISPOINTINSTROKEPATHNVPROC GLeeFuncPtr_glIsPointInStrokePathNV; + #define glIsPointInStrokePathNV GLeeFuncPtr_glIsPointInStrokePathNV +#endif +#ifndef GLEE_H_DEFINED_glGetPathLengthNV +#define GLEE_H_DEFINED_glGetPathLengthNV + typedef GLfloat (APIENTRYP GLEEPFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); + GLEE_EXTERN GLEEPFNGLGETPATHLENGTHNVPROC GLeeFuncPtr_glGetPathLengthNV; + #define glGetPathLengthNV GLeeFuncPtr_glGetPathLengthNV +#endif +#ifndef GLEE_H_DEFINED_glPointAlongPathNV +#define GLEE_H_DEFINED_glPointAlongPathNV + typedef GLboolean (APIENTRYP GLEEPFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat * x, GLfloat * y, GLfloat * tangentX, GLfloat * tangentY); + GLEE_EXTERN GLEEPFNGLPOINTALONGPATHNVPROC GLeeFuncPtr_glPointAlongPathNV; + #define glPointAlongPathNV GLeeFuncPtr_glPointAlongPathNV +#endif +#endif + +/* GL_AMD_pinned_memory */ + +#ifndef GL_AMD_pinned_memory +#define GL_AMD_pinned_memory 1 +#define __GLEE_GL_AMD_pinned_memory 1 +/* Constants */ +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 +#endif + +/* GL_AMD_stencil_operation_extended */ + +#ifndef GL_AMD_stencil_operation_extended +#define GL_AMD_stencil_operation_extended 1 +#define __GLEE_GL_AMD_stencil_operation_extended 1 +/* Constants */ +#define GL_SET_AMD 0x874A +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D +#ifndef GLEE_H_DEFINED_glStencilOpValueAMD +#define GLEE_H_DEFINED_glStencilOpValueAMD + typedef void (APIENTRYP GLEEPFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); + GLEE_EXTERN GLEEPFNGLSTENCILOPVALUEAMDPROC GLeeFuncPtr_glStencilOpValueAMD; + #define glStencilOpValueAMD GLeeFuncPtr_glStencilOpValueAMD +#endif +#endif + +/* GL_AMD_vertex_shader_viewport_index */ + +#ifndef GL_AMD_vertex_shader_viewport_index +#define GL_AMD_vertex_shader_viewport_index 1 +#define __GLEE_GL_AMD_vertex_shader_viewport_index 1 +/* Constants */ +#endif + +/* GL_AMD_vertex_shader_layer */ + +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 +#define __GLEE_GL_AMD_vertex_shader_layer 1 +/* Constants */ +#endif + +/* GL_NV_bindless_texture */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 +#define __GLEE_GL_NV_bindless_texture 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glGetTextureHandleNV +#define GLEE_H_DEFINED_glGetTextureHandleNV + typedef GLuint64 (APIENTRYP GLEEPFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); + GLEE_EXTERN GLEEPFNGLGETTEXTUREHANDLENVPROC GLeeFuncPtr_glGetTextureHandleNV; + #define glGetTextureHandleNV GLeeFuncPtr_glGetTextureHandleNV +#endif +#ifndef GLEE_H_DEFINED_glGetTextureSamplerHandleNV +#define GLEE_H_DEFINED_glGetTextureSamplerHandleNV + typedef GLuint64 (APIENTRYP GLEEPFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); + GLEE_EXTERN GLEEPFNGLGETTEXTURESAMPLERHANDLENVPROC GLeeFuncPtr_glGetTextureSamplerHandleNV; + #define glGetTextureSamplerHandleNV GLeeFuncPtr_glGetTextureSamplerHandleNV +#endif +#ifndef GLEE_H_DEFINED_glMakeTextureHandleResidentNV +#define GLEE_H_DEFINED_glMakeTextureHandleResidentNV + typedef void (APIENTRYP GLEEPFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); + GLEE_EXTERN GLEEPFNGLMAKETEXTUREHANDLERESIDENTNVPROC GLeeFuncPtr_glMakeTextureHandleResidentNV; + #define glMakeTextureHandleResidentNV GLeeFuncPtr_glMakeTextureHandleResidentNV +#endif +#ifndef GLEE_H_DEFINED_glMakeTextureHandleNonResidentNV +#define GLEE_H_DEFINED_glMakeTextureHandleNonResidentNV + typedef void (APIENTRYP GLEEPFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); + GLEE_EXTERN GLEEPFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC GLeeFuncPtr_glMakeTextureHandleNonResidentNV; + #define glMakeTextureHandleNonResidentNV GLeeFuncPtr_glMakeTextureHandleNonResidentNV +#endif +#ifndef GLEE_H_DEFINED_glGetImageHandleNV +#define GLEE_H_DEFINED_glGetImageHandleNV + typedef GLuint64 (APIENTRYP GLEEPFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); + GLEE_EXTERN GLEEPFNGLGETIMAGEHANDLENVPROC GLeeFuncPtr_glGetImageHandleNV; + #define glGetImageHandleNV GLeeFuncPtr_glGetImageHandleNV +#endif +#ifndef GLEE_H_DEFINED_glMakeImageHandleResidentNV +#define GLEE_H_DEFINED_glMakeImageHandleResidentNV + typedef void (APIENTRYP GLEEPFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); + GLEE_EXTERN GLEEPFNGLMAKEIMAGEHANDLERESIDENTNVPROC GLeeFuncPtr_glMakeImageHandleResidentNV; + #define glMakeImageHandleResidentNV GLeeFuncPtr_glMakeImageHandleResidentNV +#endif +#ifndef GLEE_H_DEFINED_glMakeImageHandleNonResidentNV +#define GLEE_H_DEFINED_glMakeImageHandleNonResidentNV + typedef void (APIENTRYP GLEEPFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); + GLEE_EXTERN GLEEPFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC GLeeFuncPtr_glMakeImageHandleNonResidentNV; + #define glMakeImageHandleNonResidentNV GLeeFuncPtr_glMakeImageHandleNonResidentNV +#endif +#ifndef GLEE_H_DEFINED_glUniformHandleui64NV +#define GLEE_H_DEFINED_glUniformHandleui64NV + typedef void (APIENTRYP GLEEPFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); + GLEE_EXTERN GLEEPFNGLUNIFORMHANDLEUI64NVPROC GLeeFuncPtr_glUniformHandleui64NV; + #define glUniformHandleui64NV GLeeFuncPtr_glUniformHandleui64NV +#endif +#ifndef GLEE_H_DEFINED_glUniformHandleui64vNV +#define GLEE_H_DEFINED_glUniformHandleui64vNV + typedef void (APIENTRYP GLEEPFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 * value); + GLEE_EXTERN GLEEPFNGLUNIFORMHANDLEUI64VNVPROC GLeeFuncPtr_glUniformHandleui64vNV; + #define glUniformHandleui64vNV GLeeFuncPtr_glUniformHandleui64vNV +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformHandleui64NV +#define GLEE_H_DEFINED_glProgramUniformHandleui64NV + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMHANDLEUI64NVPROC GLeeFuncPtr_glProgramUniformHandleui64NV; + #define glProgramUniformHandleui64NV GLeeFuncPtr_glProgramUniformHandleui64NV +#endif +#ifndef GLEE_H_DEFINED_glProgramUniformHandleui64vNV +#define GLEE_H_DEFINED_glProgramUniformHandleui64vNV + typedef void (APIENTRYP GLEEPFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 * values); + GLEE_EXTERN GLEEPFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC GLeeFuncPtr_glProgramUniformHandleui64vNV; + #define glProgramUniformHandleui64vNV GLeeFuncPtr_glProgramUniformHandleui64vNV +#endif +#ifndef GLEE_H_DEFINED_glIsTextureHandleResidentNV +#define GLEE_H_DEFINED_glIsTextureHandleResidentNV + typedef GLboolean (APIENTRYP GLEEPFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); + GLEE_EXTERN GLEEPFNGLISTEXTUREHANDLERESIDENTNVPROC GLeeFuncPtr_glIsTextureHandleResidentNV; + #define glIsTextureHandleResidentNV GLeeFuncPtr_glIsTextureHandleResidentNV +#endif +#ifndef GLEE_H_DEFINED_glIsImageHandleResidentNV +#define GLEE_H_DEFINED_glIsImageHandleResidentNV + typedef GLboolean (APIENTRYP GLEEPFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); + GLEE_EXTERN GLEEPFNGLISIMAGEHANDLERESIDENTNVPROC GLeeFuncPtr_glIsImageHandleResidentNV; + #define glIsImageHandleResidentNV GLeeFuncPtr_glIsImageHandleResidentNV +#endif +#endif + +/* GL_NV_shader_atomic_float */ + +#ifndef GL_NV_shader_atomic_float +#define GL_NV_shader_atomic_float 1 +#define __GLEE_GL_NV_shader_atomic_float 1 +/* Constants */ +#endif + +/* GL_AMD_query_buffer_object */ + +#ifndef GL_AMD_query_buffer_object +#define GL_AMD_query_buffer_object 1 +#define __GLEE_GL_AMD_query_buffer_object 1 +/* Constants */ +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 +#endif + +/* GL_NV_compute_program5 */ + +#ifndef GL_NV_compute_program5 +#define GL_NV_compute_program5 1 +#define __GLEE_GL_NV_compute_program5 1 +/* Constants */ +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC +#endif + +/* GL_NV_shader_storage_buffer_object */ + +#ifndef GL_NV_shader_storage_buffer_object +#define GL_NV_shader_storage_buffer_object 1 +#define __GLEE_GL_NV_shader_storage_buffer_object 1 +/* Constants */ +#endif + +/* GL_NV_shader_atomic_counters */ + +#ifndef GL_NV_shader_atomic_counters +#define GL_NV_shader_atomic_counters 1 +#define __GLEE_GL_NV_shader_atomic_counters 1 +/* Constants */ +#endif + +/* GL_NV_deep_texture3D */ + +#ifndef GL_NV_deep_texture3D +#define GL_NV_deep_texture3D 1 +#define __GLEE_GL_NV_deep_texture3D 1 +/* Constants */ +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#endif + +/* GL_NVX_conditional_render */ + +#ifndef GL_NVX_conditional_render +#define GL_NVX_conditional_render 1 +#define __GLEE_GL_NVX_conditional_render 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glBeginConditionalRenderNVX +#define GLEE_H_DEFINED_glBeginConditionalRenderNVX + typedef void (APIENTRYP GLEEPFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); + GLEE_EXTERN GLEEPFNGLBEGINCONDITIONALRENDERNVXPROC GLeeFuncPtr_glBeginConditionalRenderNVX; + #define glBeginConditionalRenderNVX GLeeFuncPtr_glBeginConditionalRenderNVX +#endif +#ifndef GLEE_H_DEFINED_glEndConditionalRenderNVX +#define GLEE_H_DEFINED_glEndConditionalRenderNVX + typedef void (APIENTRYP GLEEPFNGLENDCONDITIONALRENDERNVXPROC) (); + GLEE_EXTERN GLEEPFNGLENDCONDITIONALRENDERNVXPROC GLeeFuncPtr_glEndConditionalRenderNVX; + #define glEndConditionalRenderNVX GLeeFuncPtr_glEndConditionalRenderNVX +#endif +#endif + +/* GL_AMD_sparse_texture */ + +#ifndef GL_AMD_sparse_texture +#define GL_AMD_sparse_texture 1 +#define __GLEE_GL_AMD_sparse_texture 1 +/* Constants */ +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIN_LOD_WARNING_AMD 0x919C +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +#ifndef GLEE_H_DEFINED_glTexStorageSparseAMD +#define GLEE_H_DEFINED_glTexStorageSparseAMD + typedef void (APIENTRYP GLEEPFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); + GLEE_EXTERN GLEEPFNGLTEXSTORAGESPARSEAMDPROC GLeeFuncPtr_glTexStorageSparseAMD; + #define glTexStorageSparseAMD GLeeFuncPtr_glTexStorageSparseAMD +#endif +#ifndef GLEE_H_DEFINED_glTextureStorageSparseAMD +#define GLEE_H_DEFINED_glTextureStorageSparseAMD + typedef void (APIENTRYP GLEEPFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); + GLEE_EXTERN GLEEPFNGLTEXTURESTORAGESPARSEAMDPROC GLeeFuncPtr_glTextureStorageSparseAMD; + #define glTextureStorageSparseAMD GLeeFuncPtr_glTextureStorageSparseAMD +#endif +#endif + +/* GL_AMD_shader_trinary_minmax */ + +#ifndef GL_AMD_shader_trinary_minmax +#define GL_AMD_shader_trinary_minmax 1 +#define __GLEE_GL_AMD_shader_trinary_minmax 1 +/* Constants */ +#endif + +/* GL_INTEL_map_texture */ + +#ifndef GL_INTEL_map_texture +#define GL_INTEL_map_texture 1 +#define __GLEE_GL_INTEL_map_texture 1 +/* Constants */ +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF +#define GL_LAYOUT_DEFAULT_INTEL +#define GL_LAYOUT_LINEAR_INTEL +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL +#ifndef GLEE_H_DEFINED_glSyncTextureINTEL +#define GLEE_H_DEFINED_glSyncTextureINTEL + typedef void (APIENTRYP GLEEPFNGLSYNCTEXTUREINTELPROC) (GLuint texture); + GLEE_EXTERN GLEEPFNGLSYNCTEXTUREINTELPROC GLeeFuncPtr_glSyncTextureINTEL; + #define glSyncTextureINTEL GLeeFuncPtr_glSyncTextureINTEL +#endif +#ifndef GLEE_H_DEFINED_glUnmapTexture2DINTEL +#define GLEE_H_DEFINED_glUnmapTexture2DINTEL + typedef void (APIENTRYP GLEEPFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); + GLEE_EXTERN GLEEPFNGLUNMAPTEXTURE2DINTELPROC GLeeFuncPtr_glUnmapTexture2DINTEL; + #define glUnmapTexture2DINTEL GLeeFuncPtr_glUnmapTexture2DINTEL +#endif +#ifndef GLEE_H_DEFINED_glMapTexture2DINTEL +#define GLEE_H_DEFINED_glMapTexture2DINTEL + typedef GLvoid* (APIENTRYP GLEEPFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, const GLint * stride, const GLenum * layout); + GLEE_EXTERN GLEEPFNGLMAPTEXTURE2DINTELPROC GLeeFuncPtr_glMapTexture2DINTEL; + #define glMapTexture2DINTEL GLeeFuncPtr_glMapTexture2DINTEL +#endif +#endif + +/* GL_NV_draw_texture */ + +#ifndef GL_NV_draw_texture +#define GL_NV_draw_texture 1 +#define __GLEE_GL_NV_draw_texture 1 +/* Constants */ +#ifndef GLEE_H_DEFINED_glDrawTextureNV +#define GLEE_H_DEFINED_glDrawTextureNV + typedef void (APIENTRYP GLEEPFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); + GLEE_EXTERN GLEEPFNGLDRAWTEXTURENVPROC GLeeFuncPtr_glDrawTextureNV; + #define glDrawTextureNV GLeeFuncPtr_glDrawTextureNV +#endif +#endif + /* GL_SGIX_texture_select */ #ifndef GL_SGIX_texture_select @@ -19173,403 +21788,6 @@ GLEE_EXTERN GLboolean _GLEE_IBM_static_data; #endif #endif -/* GL_OES_compressed_paletted_texture */ - -#ifndef GL_OES_compressed_paletted_texture -#define GL_OES_compressed_paletted_texture 1 -#define __GLEE_GL_OES_compressed_paletted_texture 1 -/* Constants */ -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 -#endif - -/* GL_OES_fixed_point */ - -#ifndef GL_OES_fixed_point -#define GL_OES_fixed_point 1 -#define __GLEE_GL_OES_fixed_point 1 -/* Constants */ -#define GL_FIXED_OES 0x140C -#endif - -/* GL_OES_single_precision */ - -#ifndef GL_OES_single_precision -#define GL_OES_single_precision 1 -#define __GLEE_GL_OES_single_precision 1 -/* Constants */ -#ifndef GLEE_H_DEFINED_glClearDepthfOES -#define GLEE_H_DEFINED_glClearDepthfOES - typedef GLvoid (APIENTRYP GLEEPFNGLCLEARDEPTHFOESPROC) (GLclampd depth); - GLEE_EXTERN GLEEPFNGLCLEARDEPTHFOESPROC GLeeFuncPtr_glClearDepthfOES; - #define glClearDepthfOES GLeeFuncPtr_glClearDepthfOES -#endif -#endif - -/* GL_OES_query_matrix */ - -#ifndef GL_OES_query_matrix -#define GL_OES_query_matrix 1 -#define __GLEE_GL_OES_query_matrix 1 -/* Constants */ -#endif - -/* GL_OES_byte_coordinates */ - -#ifndef GL_OES_byte_coordinates -#define GL_OES_byte_coordinates 1 -#define __GLEE_GL_OES_byte_coordinates 1 -/* Constants */ -#define GL_BYTE 0x1400 -#endif - -/* GL_NV_gpu_program4 */ - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 -#define __GLEE_GL_NV_gpu_program4 1 -/* Constants */ -#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_LINES_ADJACENCY_EXT 0xA -#define GL_LINE_STRIP_ADJACENCY_EXT 0xB -#define GL_TRIANGLES_ADJACENCY_EXT 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD -#endif - -/* GL_NV_path_rendering */ - -#ifndef GL_NV_path_rendering -#define GL_NV_path_rendering 1 -#define __GLEE_GL_NV_path_rendering 1 -/* Constants */ -#define GL_CLOSE_PATH_NV 0x00 -#define GL_MOVE_TO_NV 0x02 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_LINE_TO_NV 0x04 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_RESTART_PATH_NV 0xF0 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_RECT_NV 0xF6 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_ARC_TO_NV 0xFE -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_FILE_NAME_NV 0x9074 -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_COUNT_UP_NV 0x9088 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_CONVEX_HULL_NV 0x908B -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_UTF8_NV 0x909A -#define GL_UTF16_NV 0x909B -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_SQUARE_NV 0x90A3 -#define GL_ROUND_NV 0x90A4 -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_BEVEL_NV 0x90A6 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_BOLD_BIT_NV 0x01 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_GLYPH_HAS_KERNING_NV 0x100 -#define GL_FONT_X_MIN_BOUNDS_NV 0x00010000 -#define GL_FONT_Y_MIN_BOUNDS_NV 0x00020000 -#define GL_FONT_X_MAX_BOUNDS_NV 0x00040000 -#define GL_FONT_Y_MAX_BOUNDS_NV 0x00080000 -#define GL_FONT_UNITS_PER_EM_NV 0x00100000 -#define GL_FONT_ASCENDER_NV 0x00200000 -#define GL_FONT_DESCENDER_NV 0x00400000 -#define GL_FONT_HEIGHT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_WIDTH_NV 0x01000000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_NV 0x02000000 -#define GL_FONT_UNDERLINE_POSITION_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_NV 0x08000000 -#define GL_FONT_HAS_KERNING_NV 0x10000000 -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#endif - -/* GL_AMD_vertex_shader_tessellator */ - -#ifndef GL_AMD_vertex_shader_tessellator -#define GL_AMD_vertex_shader_tessellator 1 -#define __GLEE_GL_AMD_vertex_shader_tessellator 1 -/* Constants */ -#define GL_SAMPLER_BUFFER_AMD 0x9001 -#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 -#define GL_DISCRETE_AMD 0x9006 -#define GL_CONTINUOUS_AMD 0x9007 -#define GL_TESSELLATION_MODE_AMD 0x9004 -#define GL_TESSELLATION_FACTOR_AMD 0x9005 -#ifndef GLEE_H_DEFINED_glTessellationModeAMD -#define GLEE_H_DEFINED_glTessellationModeAMD - typedef GLvoid (APIENTRYP GLEEPFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); - GLEE_EXTERN GLEEPFNGLTESSELLATIONMODEAMDPROC GLeeFuncPtr_glTessellationModeAMD; - #define glTessellationModeAMD GLeeFuncPtr_glTessellationModeAMD -#endif -#endif - -/* GL_EXT_fragment_lighting */ - -#ifndef GL_EXT_fragment_lighting -#define GL_EXT_fragment_lighting 1 -#define __GLEE_GL_EXT_fragment_lighting 1 -/* Constants */ -#define GL_FRAGMENT_LIGHTING_EXT 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 -#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 -#define GL_LIGHT_ENV_MODE_EXT 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B -#define GL_FRAGMENT_LIGHT0_EXT 0x840C -#define GL_FRAGMENT_LIGHT7_EXT 0x8413 -#endif - -/* GL_EXT_texture_compression_dxt1 */ - -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_EXT_texture_compression_dxt1 1 -#define __GLEE_GL_EXT_texture_compression_dxt1 1 -/* Constants */ -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#endif - -/* GL_EXT_scene_marker */ - -#ifndef GL_EXT_scene_marker -#define GL_EXT_scene_marker 1 -#define __GLEE_GL_EXT_scene_marker 1 -/* Constants */ -#ifndef GLEE_H_DEFINED_glEndSceneEXT -#define GLEE_H_DEFINED_glEndSceneEXT - typedef GLvoid (APIENTRYP GLEEPFNGLENDSCENEEXTPROC) (); - GLEE_EXTERN GLEEPFNGLENDSCENEEXTPROC GLeeFuncPtr_glEndSceneEXT; - #define glEndSceneEXT GLeeFuncPtr_glEndSceneEXT -#endif -#endif - -/* GL_EXT_geometry_shader4 */ - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 -#define __GLEE_GL_EXT_geometry_shader4 1 -/* Constants */ -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -#define GL_LINES_ADJACENCY_EXT 0xA -#define GL_LINE_STRIP_ADJACENCY_EXT 0xB -#define GL_TRIANGLES_ADJACENCY_EXT 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#endif - -/* GL_EXT_texture_env */ - -#ifndef GL_EXT_texture_env -#define GL_EXT_texture_env 1 -#define __GLEE_GL_EXT_texture_env 1 -/* Constants */ -#define GL_TEXTURE_ENV0_EXT 0x0 -#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0x0 -#define GL_ENV_COPY_EXT 0x0 -#define GL_ENV_REPLACE_EXT 0x0 -#define GL_ENV_MODULATE_EXT 0x0 -#define GL_ENV_ADD_EXT 0x0 -#define GL_ENV_SUBTRACT_EXT 0x0 -#define GL_ENV_REVERSE_SUBTRACT_EXT 0x0 -#define GL_ENV_BLEND_EXT 0x0 -#define GL_ENV_REVERSE_BLEND_EXT 0x0 -#define GL_TEXTURE_ENV_SHIFT_EXT 0x0 -#endif - -/* GL_SGIX_texture_range */ - -#ifndef GL_SGIX_texture_range -#define GL_SGIX_texture_range 1 -#define __GLEE_GL_SGIX_texture_range 1 -/* Constants */ -#define GL_RGB_SIGNED_SGIX 0x85E0 -#define GL_RGBA_SIGNED_SGIX 0x85E1 -#define GL_ALPHA_SIGNED_SGIX 0x85E2 -#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 -#define GL_INTENSITY_SIGNED_SGIX 0x85E4 -#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 -#define GL_RGB16_SIGNED_SGIX 0x85E6 -#define GL_RGBA16_SIGNED_SGIX 0x85E7 -#define GL_ALPHA16_SIGNED_SGIX 0x85E8 -#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 -#define GL_INTENSITY16_SIGNED_SGIX 0x85EA -#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB -#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC -#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED -#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE -#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF -#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 -#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 -#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 -#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 -#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 -#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 -#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 -#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 -#define GL_MIN_LUMINANCE_SGIS 0x85F8 -#define GL_MAX_LUMINANCE_SGIS 0x85F9 -#define GL_MIN_INTENSITY_SGIS 0x85FA -#define GL_MAX_INTENSITY_SGIS 0x85FB -#endif - -/* GL_SGIX_pixel_texture_bits */ - -#ifndef GL_SGIX_pixel_texture_bits -#define GL_SGIX_pixel_texture_bits 1 -#define __GLEE_GL_SGIX_pixel_texture_bits 1 -/* Constants */ -#endif - -/* GL_IBM_static_data */ - -#ifndef GL_IBM_static_data -#define GL_IBM_static_data 1 -#define __GLEE_GL_IBM_static_data 1 -/* Constants */ -#define GL_ALL_STATIC_DATA_IBM 103060 -#define GL_STATIC_VERTEX_ARRAY_IBM 103061 -#endif - /* WGL */ #ifdef _WIN32 @@ -19614,6 +21832,8 @@ GLEE_EXTERN GLboolean _GLEE_WGL_NV_copy_image; GLEE_EXTERN GLboolean _GLEE_WGL_NV_multisample_coverage; GLEE_EXTERN GLboolean _GLEE_WGL_EXT_create_context_es2_profile; GLEE_EXTERN GLboolean _GLEE_WGL_NV_DX_interop; +GLEE_EXTERN GLboolean _GLEE_WGL_NV_DX_interop2; +GLEE_EXTERN GLboolean _GLEE_WGL_EXT_swap_control_tear; GLEE_EXTERN GLboolean _GLEE_WGL_EXT_display_color_table; GLEE_EXTERN GLboolean _GLEE_WGL_EXT_extensions_string; GLEE_EXTERN GLboolean _GLEE_WGL_EXT_swap_control; @@ -19662,6 +21882,8 @@ GLEE_EXTERN GLboolean _GLEE_WGL_NV_video_output; #define GLEE_WGL_NV_multisample_coverage GLeeEnabled(&_GLEE_WGL_NV_multisample_coverage) #define GLEE_WGL_EXT_create_context_es2_profile GLeeEnabled(&_GLEE_WGL_EXT_create_context_es2_profile) #define GLEE_WGL_NV_DX_interop GLeeEnabled(&_GLEE_WGL_NV_DX_interop) +#define GLEE_WGL_NV_DX_interop2 GLeeEnabled(&_GLEE_WGL_NV_DX_interop2) +#define GLEE_WGL_EXT_swap_control_tear GLeeEnabled(&_GLEE_WGL_EXT_swap_control_tear) #define GLEE_WGL_EXT_display_color_table GLeeEnabled(&_GLEE_WGL_EXT_display_color_table) #define GLEE_WGL_EXT_extensions_string GLeeEnabled(&_GLEE_WGL_EXT_extensions_string) #define GLEE_WGL_EXT_swap_control GLeeEnabled(&_GLEE_WGL_EXT_swap_control) @@ -20737,6 +22959,22 @@ GLEE_EXTERN GLboolean _GLEE_WGL_NV_video_output; #endif #endif +/* WGL_NV_DX_interop2 */ + +#ifndef WGL_NV_DX_interop2 +#define WGL_NV_DX_interop2 1 +#define __GLEE_WGL_NV_DX_interop2 1 +/* Constants */ +#endif + +/* WGL_EXT_swap_control_tear */ + +#ifndef WGL_EXT_swap_control_tear +#define WGL_EXT_swap_control_tear 1 +#define __GLEE_WGL_EXT_swap_control_tear 1 +/* Constants */ +#endif + /* WGL_EXT_display_color_table */ #ifndef WGL_EXT_display_color_table @@ -20996,8 +23234,10 @@ GLEE_EXTERN GLboolean _GLEE_GLX_INTEL_swap_event; GLEE_EXTERN GLboolean _GLEE_GLX_NV_multisample_coverage; GLEE_EXTERN GLboolean _GLEE_GLX_AMD_gpu_association; GLEE_EXTERN GLboolean _GLEE_GLX_EXT_create_context_es2_profile; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_create_context_es_profile; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_swap_control_tear; +GLEE_EXTERN GLboolean _GLEE_GLX_EXT_buffer_age; GLEE_EXTERN GLboolean _GLEE_GLX_NV_video_output; -GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; /* Aliases for extension querying variables */ @@ -21050,8 +23290,10 @@ GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; #define GLEE_GLX_NV_multisample_coverage GLeeEnabled(&_GLEE_GLX_NV_multisample_coverage) #define GLEE_GLX_AMD_gpu_association GLeeEnabled(&_GLEE_GLX_AMD_gpu_association) #define GLEE_GLX_EXT_create_context_es2_profile GLeeEnabled(&_GLEE_GLX_EXT_create_context_es2_profile) +#define GLEE_GLX_EXT_create_context_es_profile GLeeEnabled(&_GLEE_GLX_EXT_create_context_es_profile) +#define GLEE_GLX_EXT_swap_control_tear GLeeEnabled(&_GLEE_GLX_EXT_swap_control_tear) +#define GLEE_GLX_EXT_buffer_age GLeeEnabled(&_GLEE_GLX_EXT_buffer_age) #define GLEE_GLX_NV_video_output GLeeEnabled(&_GLEE_GLX_NV_video_output) -#define GLEE_GLX_EXT_scene_marker GLeeEnabled(&_GLEE_GLX_EXT_scene_marker) /* GLX_VERSION_1_3 */ @@ -21443,13 +23685,13 @@ GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; #endif #ifndef GLEE_H_DEFINED_glXGetContextIDEXT #define GLEE_H_DEFINED_glXGetContextIDEXT - typedef GLXContextID (APIENTRYP GLEEPFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); + typedef GLEE_GLXContextID (APIENTRYP GLEEPFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); GLEE_EXTERN GLEEPFNGLXGETCONTEXTIDEXTPROC GLeeFuncPtr_glXGetContextIDEXT; #define glXGetContextIDEXT GLeeFuncPtr_glXGetContextIDEXT #endif #ifndef GLEE_H_DEFINED_glXImportContextEXT #define GLEE_H_DEFINED_glXImportContextEXT - typedef GLXContext (APIENTRYP GLEEPFNGLXIMPORTCONTEXTEXTPROC) (Display * dpy, GLXContextID contextID); + typedef GLXContext (APIENTRYP GLEEPFNGLXIMPORTCONTEXTEXTPROC) (Display * dpy, GLEE_GLXContextID contextID); GLEE_EXTERN GLEEPFNGLXIMPORTCONTEXTEXTPROC GLeeFuncPtr_glXImportContextEXT; #define glXImportContextEXT GLeeFuncPtr_glXImportContextEXT #endif @@ -22121,7 +24363,7 @@ GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 #ifndef GLEE_H_DEFINED_glXSwapIntervalEXT #define GLEE_H_DEFINED_glXSwapIntervalEXT - typedef int (APIENTRYP GLEEPFNGLXSWAPINTERVALEXTPROC) (Display * dpy, GLXDrawable drawable, int interval); + typedef void (APIENTRYP GLEEPFNGLXSWAPINTERVALEXTPROC) (Display * dpy, GLXDrawable drawable, int interval); GLEE_EXTERN GLEEPFNGLXSWAPINTERVALEXTPROC GLeeFuncPtr_glXSwapIntervalEXT; #define glXSwapIntervalEXT GLeeFuncPtr_glXSwapIntervalEXT #endif @@ -22190,6 +24432,33 @@ GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #endif +/* GLX_EXT_create_context_es_profile */ + +#ifndef GLX_EXT_create_context_es_profile +#define GLX_EXT_create_context_es_profile 1 +#define __GLEE_GLX_EXT_create_context_es_profile 1 +/* Constants */ +#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#endif + +/* GLX_EXT_swap_control_tear */ + +#ifndef GLX_EXT_swap_control_tear +#define GLX_EXT_swap_control_tear 1 +#define __GLEE_GLX_EXT_swap_control_tear 1 +/* Constants */ +#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 +#endif + +/* GLX_EXT_buffer_age */ + +#ifndef GLX_EXT_buffer_age +#define GLX_EXT_buffer_age 1 +#define __GLEE_GLX_EXT_buffer_age 1 +/* Constants */ +#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 +#endif + /* GLX_NV_video_output */ #ifndef GLX_NV_video_output @@ -22233,14 +24502,6 @@ GLEE_EXTERN GLboolean _GLEE_GLX_EXT_scene_marker; #define glXGetVideoInfoNV GLeeFuncPtr_glXGetVideoInfoNV #endif #endif - -/* GLX_EXT_scene_marker */ - -#ifndef GLX_EXT_scene_marker -#define GLX_EXT_scene_marker 1 -#define __GLEE_GLX_EXT_scene_marker 1 -/* Constants */ -#endif #endif /*end GLX */ /***************************************************************** diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index cf365c633..075887c4a 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,19 +18,23 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "common/config.h" #include "common/math.h" #include "common/Vector.h" #include "Graphics.h" #include "window/sdl/Window.h" +#include "Polyline.h" +// C++ #include #include #include #include -using love::window::WindowFlags; +// C +#include namespace love { @@ -45,8 +49,16 @@ Graphics::Graphics() , lineWidth(1) , matrixLimit(0) , userMatrices(0) + , colorMask() + , width(0) + , height(0) + , created(false) + , savedState() { - currentWindow = love::window::sdl::Window::getSingleton(); + currentWindow = love::window::sdl::Window::createSingleton(); + + if (currentWindow->isCreated()) + setMode(currentWindow->getWidth(), currentWindow->getHeight()); } Graphics::~Graphics() @@ -62,11 +74,6 @@ const char *Graphics::getName() const return "love.graphics.opengl"; } -bool Graphics::checkMode(int width, int height, bool fullscreen) const -{ - return currentWindow->checkWindowSize(width, height, fullscreen); -} - DisplayState Graphics::saveState() { DisplayState s; @@ -75,7 +82,6 @@ DisplayState Graphics::saveState() s.backgroundColor = getBackgroundColor(); s.blendMode = getBlendMode(); - s.colorMode = getColorMode(); //get line style s.lineStyle = lineStyle; //get the point size @@ -86,7 +92,10 @@ DisplayState Graphics::saveState() s.scissor = (glIsEnabled(GL_SCISSOR_TEST) == GL_TRUE); //do we have scissor, if so, store the box if (s.scissor) - glGetIntegerv(GL_SCISSOR_BOX, s.scissorBox); + s.scissorBox = gl.getScissor(); + + for (int i = 0; i < 4; i++) + s.colorMask[i] = colorMask[i]; return s; } @@ -96,40 +105,66 @@ void Graphics::restoreState(const DisplayState &s) setColor(s.color); setBackgroundColor(s.backgroundColor); setBlendMode(s.blendMode); - setColorMode(s.colorMode); - setLine(lineWidth, s.lineStyle); - setPoint(s.pointSize, s.pointStyle); + setLineWidth(lineWidth); + setLineStyle(s.lineStyle); + setPointSize(s.pointSize); + setPointStyle(s.pointStyle); if (s.scissor) - setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]); + setScissor(s.scissorBox.x, s.scissorBox.y, s.scissorBox.w, s.scissorBox.h); else setScissor(); + setColorMask(s.colorMask[0], s.colorMask[1], s.colorMask[2], s.colorMask[3]); } -bool Graphics::setMode(int width, int height, WindowFlags *flags) +void Graphics::setViewportSize(int width, int height) { - // This operation destroys the OpenGL context, so - // we must save the state. - DisplayState tempState; - if (isCreated()) - tempState = saveState(); + this->width = width; + this->height = height; - // Unload all volatile objects. These must be reloaded after - // the display mode change. - Volatile::unloadAll(); + if (!isCreated()) + return; - uninitializeContext(); + // We want to affect the main screen, not any Canvas that's currently active + // (not that any *should* be active when this is called.) + Canvas *c = Canvas::current; + Canvas::bindDefaultCanvas(); - bool success = currentWindow->setWindow(width, height, flags); + // Set the viewport to top-left corner. + gl.setViewport(OpenGL::Viewport(0, 0, width, height)); - // Regardless of failure, we'll have to set up OpenGL once again. - width = currentWindow->getWidth(); - height = currentWindow->getHeight(); + // If a canvas was bound before this function was called, it needs to be + // made aware of the new system viewport size. + Canvas::systemViewport = gl.getViewport(); + + // Reset the projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Set up orthographic view (no depth) + glOrtho(0.0, width, height, 0.0, -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + + // Restore the previously active Canvas. + if (c != nullptr) + c->startGrab(c->getAttachedCanvases()); +} + +bool Graphics::setMode(int width, int height) +{ + this->width = width; + this->height = height; // Okay, setup OpenGL. - initializeContext(); + gl.initContext(); + + created = true; + + setViewportSize(width, height); // Make sure antialiasing works when set elsewhere - glEnable(GL_MULTISAMPLE); + if (GLEE_VERSION_1_3 || GLEE_ARB_multisample) + glEnable(GL_MULTISAMPLE); // Enable blending glEnable(GL_BLEND); @@ -137,6 +172,9 @@ bool Graphics::setMode(int width, int height, WindowFlags *flags) // "Normal" blending glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // Enable all color component writes. + setColorMask(true, true, true, true); + // Enable line/point smoothing. setLineStyle(LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); @@ -148,54 +186,45 @@ bool Graphics::setMode(int width, int height, WindowFlags *flags) // Enable textures glEnable(GL_TEXTURE_2D); - setActiveTextureUnit(0); - - // Set the viewport to top-left corner - glViewport(0, 0, width, height); - - // Reset the projection matrix - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // Set up orthographic view (no depth) - glOrtho(0.0, width, height, 0.0, -1.0, 1.0); + gl.setTextureUnit(0); // Reset modelview matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Set pixel row alignment - glPixelStorei(GL_UNPACK_ALIGNMENT, 2); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Reload all volatile objects. if (!Volatile::loadAll()) std::cerr << "Could not reload all volatile objects." << std::endl; // Restore the display state. - restoreState(tempState); + restoreState(savedState); + pixel_size_stack.clear(); + pixel_size_stack.reserve(5); + pixel_size_stack.push_back(1); // Get the maximum number of matrices // subtract a few to give the engine some room. glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &matrixLimit); matrixLimit -= 5; - return success; + return true; } -void Graphics::getMode(int &width, int &height, WindowFlags &flags) const +void Graphics::unSetMode() { - currentWindow->getWindow(width, height, flags); -} + // Window re-creation may destroy the GL context, so we must save the state. + if (isCreated()) + savedState = saveState(); -bool Graphics::toggleFullscreen() -{ - int width, height; - WindowFlags flags; - currentWindow->getWindow(width, height, flags); - flags.fullscreen = !flags.fullscreen; - return setMode(width, height, &flags); -} + // Unload all volatile objects. These must be reloaded after the display + // mode change. + Volatile::unloadAll(); + gl.deInitContext(); +} void Graphics::reset() { @@ -203,13 +232,13 @@ void Graphics::reset() discardStencil(); Canvas::bindDefaultCanvas(); Shader::detach(); + origin(); restoreState(s); } void Graphics::clear() { glClear(GL_COLOR_BUFFER_BIT); - glLoadIdentity(); } void Graphics::present() @@ -217,86 +246,26 @@ void Graphics::present() currentWindow->swapBuffers(); } -void Graphics::setIcon(Image *image) -{ - currentWindow->setIcon(image->getData()); -} - -void Graphics::setCaption(const char *caption) -{ - std::string title(caption); - currentWindow->setWindowTitle(title); -} - -int Graphics::getCaption(lua_State *L) const -{ - std::string title = currentWindow->getWindowTitle(); - lua_pushstring(L, title.c_str()); - return 1; -} - int Graphics::getWidth() const { - return currentWindow->getWidth(); + return width; } int Graphics::getHeight() const { - return currentWindow->getHeight(); -} - -int Graphics::getRenderHeight() const -{ - if (Canvas::current) - return Canvas::current->getHeight(); - return getHeight(); + return height; } bool Graphics::isCreated() const { - return currentWindow->isCreated(); -} - -int Graphics::getModes(lua_State *L) const -{ - int n; - love::window::Window::WindowSize **modes = currentWindow->getFullscreenSizes(n); - - if (modes == 0) - return 0; - - lua_newtable(L); - - for (int i = 0; i < n ; i++) - { - lua_pushinteger(L, i+1); - lua_newtable(L); - - // Inner table attribs. - - lua_pushstring(L, "width"); - lua_pushinteger(L, modes[i]->width); - lua_settable(L, -3); - - lua_pushstring(L, "height"); - lua_pushinteger(L, modes[i]->height); - lua_settable(L, -3); - - // Inner table attribs end. - - lua_settable(L, -3); - - delete modes[i]; - } - - delete[] modes; - return 1; + return created; } void Graphics::setScissor(int x, int y, int width, int height) { glEnable(GL_SCISSOR_TEST); - glScissor(x, getRenderHeight() - (y + height), width, height); // Compensates for the fact that our y-coordinate is reverse of OpenGLs. + // OpenGL's reversed y-coordinate is compensated for in OpenGL::setScissor. + gl.setScissor(OpenGL::Viewport(x, y, width, height)); } void Graphics::setScissor() @@ -304,49 +273,60 @@ void Graphics::setScissor() glDisable(GL_SCISSOR_TEST); } -int Graphics::getScissor(lua_State *L) const +bool Graphics::getScissor(int &x, int &y, int &width, int &height) const { - if (glIsEnabled(GL_SCISSOR_TEST) == GL_FALSE) - return 0; + OpenGL::Viewport scissor = gl.getScissor(); - GLint scissor[4]; - glGetIntegerv(GL_SCISSOR_BOX, scissor); + x = scissor.x; + y = scissor.y; + width = scissor.w; + height = scissor.h; - lua_pushnumber(L, scissor[0]); - lua_pushnumber(L, getRenderHeight() - (scissor[1] + scissor[3])); // Compensates for the fact that our y-coordinate is reverse of OpenGLs. - lua_pushnumber(L, scissor[2]); - lua_pushnumber(L, scissor[3]); - - return 4; + return glIsEnabled(GL_SCISSOR_TEST) == GL_TRUE; } void Graphics::defineStencil() { + // Make sure the active canvas has a stencil buffer. + if (Canvas::current) + Canvas::current->checkCreateStencil(); + + // Disable color writes but don't save the mask values. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glEnable(GL_STENCIL_TEST); + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); } void Graphics::useStencil(bool invert) { - glStencilFunc(GL_EQUAL, (int)(!invert), 1); // invert ? 0 : 1 + glStencilFunc(GL_EQUAL, (GLint)(!invert), 1); // invert ? 0 : 1 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + setColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); } void Graphics::discardStencil() { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + setColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); glDisable(GL_STENCIL_TEST); } +int Graphics::getMaxTextureSize() const +{ + return gl.getMaxTextureSize(); +} + Image *Graphics::newImage(love::image::ImageData *data) { // Create the image. Image *image = new Image(data); - bool success; + + if (!isCreated()) + return image; + + bool success = false; try { success = image->load(); @@ -365,36 +345,63 @@ Image *Graphics::newImage(love::image::ImageData *data) return image; } -Quad *Graphics::newQuad(float x, float y, float w, float h, float sw, float sh) +Image *Graphics::newImage(love::image::CompressedData *cdata) +{ + // Create the image. + Image *image = new Image(cdata); + + if (!isCreated()) + return image; + + bool success = false; + try + { + success = image->load(); + } + catch(love::Exception &) + { + image->release(); + throw; + } + if (!success) + { + image->release(); + return 0; + } + + return image; +} + +Quad *Graphics::newQuad(Quad::Viewport v, float sw, float sh) { - Quad::Viewport v; - v.x = x; - v.y = y; - v.w = w; - v.h = h; return new Quad(v, sw, sh); } -Font *Graphics::newFont(love::font::Rasterizer *r, const Image::Filter &filter) +Font *Graphics::newFont(love::font::Rasterizer *r, const Texture::Filter &filter) { return new Font(r, filter); } -SpriteBatch *Graphics::newSpriteBatch(Image *image, int size, int usage) +SpriteBatch *Graphics::newSpriteBatch(Texture *texture, int size, int usage) { - return new SpriteBatch(image, size, usage); + return new SpriteBatch(texture, size, usage); } -ParticleSystem *Graphics::newParticleSystem(Image *image, int size) +ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size) { - return new ParticleSystem(image, size); + return new ParticleSystem(texture, size); } Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_type) { - if (texture_type == Canvas::TYPE_HDR && !Canvas::isHdrSupported()) + if (texture_type == Canvas::TYPE_HDR && !Canvas::isHDRSupported()) throw Exception("HDR Canvases are not supported by your OpenGL implementation"); + if (width > gl.getMaxTextureSize()) + throw Exception("Cannot create canvas: width of %d pixels is too large for this system.", width); + else if (height > gl.getMaxTextureSize()) + throw Exception("Cannot create canvas: height of %d pixels is too large for this system.", height); + while (GL_NO_ERROR != glGetError()) /* clear opengl error flag */; @@ -448,48 +455,34 @@ Shader *Graphics::newShader(const Shader::ShaderSources &sources) return new Shader(sources); } +Mesh *Graphics::newMesh(const std::vector &vertices, Mesh::DrawMode mode) +{ + return new Mesh(vertices, mode); +} + void Graphics::setColor(const Color &c) { - glColor4ubv(&c.r); + gl.setColor(c); } Color Graphics::getColor() const { - float c[4]; - glGetFloatv(GL_CURRENT_COLOR, c); - - Color t; - t.r = (unsigned char)(255.0f*c[0]); - t.g = (unsigned char)(255.0f*c[1]); - t.b = (unsigned char)(255.0f*c[2]); - t.a = (unsigned char)(255.0f*c[3]); - - return t; + return gl.getColor(); } void Graphics::setBackgroundColor(const Color &c) { - glClearColor((float)c.r/255.0f, (float)c.g/255.0f, (float)c.b/255.0f, (float)c.a/255.0f); + gl.setClearColor(c); } Color Graphics::getBackgroundColor() const { - float c[4]; - glGetFloatv(GL_COLOR_CLEAR_VALUE, c); - - Color t; - t.r = (unsigned char)(255.0f*c[0]); - t.g = (unsigned char)(255.0f*c[1]); - t.b = (unsigned char)(255.0f*c[2]); - t.a = (unsigned char)(255.0f*c[3]); - - return t; + return gl.getClearColor(); } void Graphics::setFont(Font *font) { - if (currentFont != 0) - currentFont->release(); + Object::AutoRelease fontrelease(currentFont); currentFont = font; @@ -502,6 +495,21 @@ Font *Graphics::getFont() const return currentFont; } +void Graphics::setColorMask(bool r, bool g, bool b, bool a) +{ + colorMask[0] = r; + colorMask[1] = g; + colorMask[2] = b; + colorMask[3] = a; + + glColorMask((GLboolean) r, (GLboolean) g, (GLboolean) b, (GLboolean) a); +} + +const bool *Graphics::getColorMask() const +{ + return colorMask; +} + void Graphics::setBlendMode(Graphics::BlendMode mode) { const int gl_1_4 = GLEE_VERSION_1_4; @@ -545,7 +553,7 @@ void Graphics::setBlendMode(Graphics::BlendMode mode) src_rgb = src_a = GL_SRC_ALPHA; dst_rgb = dst_a = GL_ONE; break; - case BLEND_NONE: + case BLEND_REPLACE: default: src_rgb = src_a = GL_ONE; dst_rgb = dst_a = GL_ZERO; @@ -576,20 +584,6 @@ void Graphics::setBlendMode(Graphics::BlendMode mode) } } -void Graphics::setColorMode(Graphics::ColorMode mode) -{ - if (mode == COLOR_MODULATE) - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - else if (mode == COLOR_COMBINE) - { - glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED); - glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - } - else // mode = COLOR_REPLACE - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -} - Graphics::BlendMode Graphics::getBlendMode() const { const int gl_1_4 = GLEE_VERSION_1_4; @@ -629,7 +623,7 @@ Graphics::BlendMode Graphics::getBlendMode() const else if (src_rgb == GL_ONE && dst_rgb == GL_ONE_MINUS_SRC_ALPHA) return BLEND_PREMULTIPLIED; else if (src_rgb == GL_ONE && dst_rgb == GL_ZERO) - return BLEND_NONE; + return BLEND_REPLACE; } else if (src_rgb == GL_SRC_ALPHA && src_a == GL_ONE && dst_rgb == GL_ONE_MINUS_SRC_ALPHA && dst_a == GL_ONE_MINUS_SRC_ALPHA) @@ -638,27 +632,26 @@ Graphics::BlendMode Graphics::getBlendMode() const throw Exception("Unknown blend mode"); } -Graphics::ColorMode Graphics::getColorMode() const +void Graphics::setDefaultFilter(const Texture::Filter &f) { - GLint mode; - glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &mode); - - if (mode == GL_MODULATE) - return COLOR_MODULATE; - else if (mode == GL_COMBINE) - return COLOR_COMBINE; - else // mode == GL_REPLACE - return COLOR_REPLACE; + Texture::setDefaultFilter(f); } -void Graphics::setDefaultImageFilter(const Image::Filter &f) +const Texture::Filter &Graphics::getDefaultFilter() const { - Image::setDefaultFilter(f); + return Texture::getDefaultFilter(); } -const Image::Filter &Graphics::getDefaultImageFilter() const +void Graphics::setDefaultMipmapFilter(Texture::FilterMode filter, float sharpness) { - return Image::getDefaultFilter(); + Image::setDefaultMipmapFilter(filter); + Image::setDefaultMipmapSharpness(sharpness); +} + +void Graphics::getDefaultMipmapFilter(Texture::FilterMode *filter, float *sharpness) const +{ + *filter = Image::getDefaultMipmapFilter(); + *sharpness = Image::getDefaultMipmapSharpness(); } void Graphics::setLineWidth(float width) @@ -671,13 +664,9 @@ void Graphics::setLineStyle(Graphics::LineStyle style) lineStyle = style; } -void Graphics::setLine(float width, Graphics::LineStyle style) +void Graphics::setLineJoin(Graphics::LineJoin join) { - setLineWidth(width); - - if (style == 0) - return; - setLineStyle(style); + lineJoin = join; } float Graphics::getLineWidth() const @@ -690,6 +679,11 @@ Graphics::LineStyle Graphics::getLineStyle() const return lineStyle; } +Graphics::LineJoin Graphics::getLineJoin() const +{ + return lineJoin; +} + void Graphics::setPointSize(float size) { glPointSize((GLfloat)size); @@ -703,16 +697,6 @@ void Graphics::setPointStyle(Graphics::PointStyle style) glDisable(GL_POINT_SMOOTH); } -void Graphics::setPoint(float size, Graphics::PointStyle style) -{ - if (style == POINT_SMOOTH) - glEnable(GL_POINT_SMOOTH); - else // POINT_ROUGH - glDisable(GL_POINT_SMOOTH); - - glPointSize((GLfloat)size); -} - float Graphics::getPointSize() const { GLfloat size; @@ -735,52 +719,79 @@ int Graphics::getMaxPointSize() const return (int)max; } -void Graphics::print(const char *str, float x, float y , float angle, float sx, float sy, float ox, float oy, float kx, float ky) +void Graphics::print(const std::string &str, float x, float y , float angle, float sx, float sy, float ox, float oy, float kx, float ky) { - if (currentFont != 0) - { - std::string text(str); - currentFont->print(text, x, y, 0.0, angle, sx, sy, ox, oy, kx, ky); - } + if (currentFont != nullptr) + currentFont->print(str, x, y, 0.0, angle, sx, sy, ox, oy, kx, ky); } -void Graphics::printf(const char *str, float x, float y, float wrap, AlignMode align) +void Graphics::printf(const std::string &str, float x, float y, float wrap, AlignMode align, float angle, float sx, float sy, float ox, float oy, float kx, float ky) { - if (currentFont == 0) + if (currentFont == nullptr) return; - using namespace std; - string text(str); - vector lines_to_draw = currentFont->getWrap(text, wrap); + if (wrap < 0.0f) + throw love::Exception("Horizontal wrap limit cannot be negative."); - // now for the actual printing - vector::const_iterator line_iter, line_end = lines_to_draw.end(); - float letter_spacing = 0.0f; - for (line_iter = lines_to_draw.begin(); line_iter != line_end; ++line_iter) + using std::string; + using std::vector; + + // wrappedlines indicates which lines were automatically wrapped. It's + // guaranteed to have the same number of elements as lines_to_draw. + vector wrappedlines; + vector lines_to_draw = currentFont->getWrap(str, wrap, 0, &wrappedlines); + + glPushMatrix(); + + static Matrix t; + t.setTransformation(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky); + glMultMatrixf((const GLfloat *)t.getElements()); + + x = y = 0.0f; + + try { - float width = static_cast(currentFont->getWidth(*line_iter)); - switch (align) + // now for the actual printing + vector::const_iterator line_iter, line_end = lines_to_draw.end(); + float extra_spacing = 0.0f; + int num_spaces = 0; + int i = 0; + + for (line_iter = lines_to_draw.begin(); line_iter != line_end; ++line_iter) { - case ALIGN_RIGHT: - currentFont->print(*line_iter, ceil(x + wrap - width), ceil(y)); - break; - case ALIGN_CENTER: - currentFont->print(*line_iter, ceil(x + (wrap - width) / 2), ceil(y)); - break; - case ALIGN_JUSTIFY: - if (line_iter->length() > 1 && (line_iter+1) != line_end) - letter_spacing = (wrap - width) / float(line_iter->length() - 1); - else - letter_spacing = 0.0f; - currentFont->print(*line_iter, ceil(x), ceil(y), letter_spacing); - break; - case ALIGN_LEFT: - default: - currentFont->print(*line_iter, ceil(x), ceil(y)); - break; + float width = static_cast(currentFont->getWidth(*line_iter)); + switch (align) + { + case ALIGN_RIGHT: + currentFont->print(*line_iter, ceilf(x + (wrap - width)), ceilf(y), 0.0f); + break; + case ALIGN_CENTER: + currentFont->print(*line_iter, ceilf(x + (wrap - width) / 2), ceilf(y), 0.0f); + break; + case ALIGN_JUSTIFY: + num_spaces = std::count(line_iter->begin(), line_iter->end(), ' '); + if (wrappedlines[i] && num_spaces >= 1) + extra_spacing = (wrap - width) / float(num_spaces); + else + extra_spacing = 0.0f; + currentFont->print(*line_iter, ceilf(x), ceilf(y), extra_spacing); + break; + case ALIGN_LEFT: + default: + currentFont->print(*line_iter, ceilf(x), ceilf(y), 0.0f); + break; + } + y += currentFont->getHeight() * currentFont->getLineHeight(); + i++; } - y += currentFont->getHeight() * currentFont->getLineHeight(); } + catch (love::Exception &) + { + glPopMatrix(); + throw; + } + + glPopMatrix(); } /** @@ -789,234 +800,38 @@ void Graphics::printf(const char *str, float x, float y, float wrap, AlignMode a void Graphics::point(float x, float y) { - bindTexture(0); + gl.prepareDraw(); + gl.bindTexture(0); glBegin(GL_POINTS); glVertex2f(x, y); glEnd(); } -// Calculate line boundary points u1 and u2. Sketch: -// u1 -// -------------+---...___ -// | ```'''-- --- -// p- - - - - - q- - . _ _ | w/2 -// | ` ' ' r + -// -------------+---...___ | w/2 -// u2 ```'''-- --- -// -// u1 and u2 depend on four things: -// - the half line width w/2 -// - the previous line vertex p -// - the current line vertex q -// - the next line vertex r -// -// u1/u2 are the intersection points of the parallel lines to p-q and q-r, -// i.e. the point where -// -// (p + w/2 * n1) + mu * (q - p) = (q + w/2 * n2) + lambda * (r - q) (u1) -// (p - w/2 * n1) + mu * (q - p) = (q - w/2 * n2) + lambda * (r - q) (u2) -// -// with n1,n2 being the normals on the segments p-q and q-r: -// -// n1 = perp(q - p) / |q - p| -// n2 = perp(r - q) / |r - q| -// -// The intersection points can be calculated using cramers rule. -static void pushIntersectionPoints(Vector *vertices, Vector *overdraw, - int pos, int count, float hw, float overdraw_factor, - const Vector &p, const Vector &q, const Vector &r) -{ - // calculate line directions - Vector s = (q - p); - Vector t = (r - q); - - // calculate vertex displacement vectors - Vector n1 = s.getNormal(); - Vector n2 = t.getNormal(); - n1.normalize(); - n2.normalize(); - float det_norm = n1 ^ n2; // will be close to zero if the angle between the normals is sharp - n1 *= hw; - n2 *= hw; - - // lines parallel -> assume intersection at displacement points - if (fabs(det_norm) <= .03) - { - vertices[pos] = q - n2; - vertices[pos+1] = q + n2; - } - // real intersection -> calculate boundary intersection points with cramers rule - else - { - float det = s ^ t; - Vector d = n1 - n2; - Vector b = s - d; // s = q - p - Vector c = s + d; - float lambda = (b ^ t) / det; - float mu = (c ^ t) / det; - - // ordering for GL_TRIANGLE_STRIP - vertices[pos] = p + s*mu - n1; // u1 - vertices[pos+1] = p + s*lambda + n1; // u2 - } - - if (overdraw) - { - // displacement of the overdraw vertices - Vector x = (vertices[pos] - q) * overdraw_factor; - - overdraw[pos] = vertices[pos]; - overdraw[pos+1] = vertices[pos] + x; - - overdraw[2*count-pos-2] = vertices[pos+1]; - overdraw[2*count-pos-1] = vertices[pos+1] - x; - } -} - -// precondition: -// glEnableClientState(GL_VERTEX_ARRAY); -static void draw_overdraw(Vector *overdraw, size_t count, float pixel_size, bool looping) -{ - // if not looping, the outer overdraw vertices need to be displaced - // to cover the line endings, i.e.: - // +- - - - //- - + +- - - - - //- - - + - // +-------//-----+ : +-------//-----+ : - // | core // line | --> : | core // line | : - // +-----//-------+ : +-----//-------+ : - // +- - //- - - - + +- - - //- - - - - + - if (!looping) - { - Vector s = overdraw[1] - overdraw[3]; - s.normalize(); - s *= pixel_size; - overdraw[1] += s; - overdraw[2*count-1] += s; - - Vector t = overdraw[count-1] - overdraw[count-3]; - t.normalize(); - t *= pixel_size; - overdraw[count-1] += t; - overdraw[count+1] += t; - - // we need to draw two more triangles to close the - // overdraw at the line start. - overdraw[2*count] = overdraw[0]; - overdraw[2*count+1] = overdraw[1]; - } - - // prepare colors: - // even indices in overdraw* point to inner vertices => alpha = current-alpha, - // odd indices point to outer vertices => alpha = 0. - GLfloat c[4]; - glGetFloatv(GL_CURRENT_COLOR, c); - - Color *colors = new Color[2*count+2]; - for (size_t i = 0; i < 2*count+2; ++i) - { - colors[i] = Color(GLubyte(c[0] * 255.f), - GLubyte(c[1] * 255.f), - GLubyte(c[2] * 255.f), - // avoids branching. equiv to if (i%2 == 1) colors[i].a = 0; - GLubyte(c[3] * 255.f) * GLubyte(i%2 == 0)); - } - - // draw faded out line halos - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); - glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *)overdraw); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*count + 2 * int(!looping)); - glDisableClientState(GL_COLOR_ARRAY); - // "if GL_COLOR_ARRAY is enabled, the value of the current color is - // undefined after glDrawArrays executes" - glColor4fv(c); - - delete[] colors; -} - void Graphics::polyline(const float *coords, size_t count) { - Vector *vertices = new Vector[count]; // two vertices for every line end-point - Vector *overdraw = NULL; - - Vector p,q,r; - bool looping = (coords[0] == coords[count-2]) && (coords[1] == coords[count-1]); - - float halfwidth = lineWidth/2.f; - float pixel_size = 1.f; - float overdraw_factor = .0f; - - if (lineStyle == LINE_SMOOTH) + if (lineJoin == LINE_JOIN_NONE) { - overdraw = new Vector[2*count+2]; - // TODO: is there a better way to get the pixel size at the current scale? - GLfloat m[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, m); - float det = m[0]*m[5]*m[10] + m[4]*m[9]*m[2] + m[8]*m[1]*m[6]; - det -= m[2]*m[5]*m[8] + m[6]*m[9]*m[0] + m[10]*m[1]*m[4]; - pixel_size = 1.f / sqrt(det); - - overdraw_factor = pixel_size / halfwidth; - halfwidth = std::max(.0f, halfwidth - .25f*pixel_size); + NoneJoinPolyline line; + line.render(coords, count, lineWidth * .5f, float(pixel_size_stack.back()), lineStyle == LINE_SMOOTH); + line.draw(); } - - // get line vertex boundaries - // if not looping, extend the line at the beginning, else use last point as `p' - r = Vector(coords[0], coords[1]); - if (!looping) - q = r * 2 - Vector(coords[2], coords[3]); - else - q = Vector(coords[count-4], coords[count-3]); - - for (size_t i = 0; i+3 < count; i += 2) + else if (lineJoin == LINE_JOIN_BEVEL) { - p = q; - q = r; - r = Vector(coords[i+2], coords[i+3]); - pushIntersectionPoints(vertices, overdraw, i, count, halfwidth, overdraw_factor, p,q,r); + BevelJoinPolyline line; + line.render(coords, count, lineWidth * .5f, float(pixel_size_stack.back()), lineStyle == LINE_SMOOTH); + line.draw(); + } + else // LINE_JOIN_MITER + { + MiterJoinPolyline line; + line.render(coords, count, lineWidth * .5f, float(pixel_size_stack.back()), lineStyle == LINE_SMOOTH); + line.draw(); } - - // if not looping, extend the line at the end, else use first point as `r' - p = q; - q = r; - if (!looping) - r += q - p; - else - r = Vector(coords[2], coords[3]); - pushIntersectionPoints(vertices, overdraw, count-2, count, halfwidth, overdraw_factor, p,q,r); - // end get line vertex boundaries - - // draw the core line - bindTexture(0); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *)vertices); - glDrawArrays(GL_TRIANGLE_STRIP, 0, count); - - // draw the line halo (antialiasing) - if (lineStyle == LINE_SMOOTH) - draw_overdraw(overdraw, count, pixel_size, looping); - - glDisableClientState(GL_VERTEX_ARRAY); - - // cleanup - delete[] vertices; - if (lineStyle == LINE_SMOOTH) - delete[] overdraw; -} - -void Graphics::triangle(DrawMode mode, float x1, float y1, float x2, float y2, float x3, float y3) -{ - float coords[] = { x1,y1, x2,y2, x3,y3, x1,y1 }; - polygon(mode, coords, 4 * 2); } void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h) { - quad(mode, x,y, x,y+h, x+w,y+h, x+w,y); -} - -void Graphics::quad(DrawMode mode, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) -{ - float coords[] = { x1,y1, x2,y2, x3,y3, x4,y4, x1,y1 }; + float coords[] = {x,y, x,y+h, x+w,y+h, x+w,y, x,y}; polygon(mode, coords, 5 * 2); } @@ -1030,8 +845,8 @@ void Graphics::circle(DrawMode mode, float x, float y, float radius, int points) float *coords = new float[2 * (points + 1)]; for (int i = 0; i < points; ++i, phi += angle_shift) { - coords[2*i] = x + radius * cos(phi); - coords[2*i+1] = y + radius * sin(phi); + coords[2*i] = x + radius * cosf(phi); + coords[2*i+1] = y + radius * sinf(phi); } coords[2*points] = coords[0]; @@ -1068,8 +883,8 @@ void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, for (int i = 0; i <= points; ++i, phi += angle_shift) { - coords[2 * (i+1)] = x + radius * cos(phi); - coords[2 * (i+1) + 1] = y + radius * sin(phi); + coords[2 * (i+1)] = x + radius * cosf(phi); + coords[2 * (i+1) + 1] = y + radius * sinf(phi); } // GL_POLYGON can only fill-draw convex polygons, so we need to do stuff manually here @@ -1079,7 +894,8 @@ void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, } else { - bindTexture(0); + gl.prepareDraw(); + gl.bindTexture(0); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *) coords); glDrawArrays(GL_TRIANGLE_FAN, 0, points + 2); @@ -1102,7 +918,8 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count) } else { - bindTexture(0); + gl.prepareDraw(); + gl.bindTexture(0); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *)coords); glDrawArrays(GL_POLYGON, 0, count/2-1); // opengl will close the polygon for us @@ -1110,8 +927,14 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count) } } -love::image::ImageData *Graphics::newScreenshot(love::image::Image *image) +love::image::ImageData *Graphics::newScreenshot(love::image::Image *image, bool copyAlpha) { + // Temporarily unbind the currently active canvas (glReadPixels reads the + // active framebuffer, not the main one.) + Canvas *curcanvas = Canvas::current; + if (curcanvas) + Canvas::bindDefaultCanvas(); + int w = getWidth(); int h = getHeight(); @@ -1119,34 +942,97 @@ love::image::ImageData *Graphics::newScreenshot(love::image::Image *image) int size = row*h; - GLubyte *pixels = new GLubyte[size]; - GLubyte *screenshot = new GLubyte[size]; + GLubyte *pixels = 0; + GLubyte *screenshot = 0; + + try + { + pixels = new GLubyte[size]; + screenshot = new GLubyte[size]; + } + catch (std::exception &) + { + delete[] pixels; + delete[] screenshot; + if (curcanvas) + curcanvas->startGrab(curcanvas->getAttachedCanvases()); + throw love::Exception("Out of memory."); + } glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + if (!copyAlpha) + { + // Replace alpha values with full opacity. + for (int i = 3; i < size; i += 4) + pixels[i] = 255; + } + // OpenGL sucks and reads pixels from the lower-left. Let's fix that. GLubyte *src = pixels - row, *dst = screenshot + size; for (int i = 0; i < h; ++i) - { memcpy(dst-=row, src+=row, row); + + delete[] pixels; + + love::image::ImageData *img = 0; + try + { + // Tell the new ImageData that it owns the screenshot data, so we don't + // need to delete it here. + img = image->newImageData(w, h, (void *) screenshot, true); + } + catch (love::Exception &) + { + delete[] screenshot; + if (curcanvas) + curcanvas->startGrab(curcanvas->getAttachedCanvases()); + throw; } - love::image::ImageData *img = image->newImageData(w, h, (void *)screenshot); - - delete [] pixels; - delete [] screenshot; + // Re-bind the active canvas, if necessary. + if (curcanvas) + curcanvas->startGrab(curcanvas->getAttachedCanvases()); return img; } +std::string Graphics::getRendererInfo(Graphics::RendererInfo infotype) const +{ + const char *infostr = 0; + + switch (infotype) + { + case Graphics::RENDERER_INFO_NAME: + default: + infostr = "OpenGL"; + break; + case Graphics::RENDERER_INFO_VERSION: + infostr = (const char *) glGetString(GL_VERSION); + break; + case Graphics::RENDERER_INFO_VENDOR: + infostr = (const char *) glGetString(GL_VENDOR); + break; + case Graphics::RENDERER_INFO_DEVICE: + infostr = (const char *) glGetString(GL_RENDERER); + break; + } + + if (!infostr) + throw love::Exception("Cannot retrieve renderer information."); + + return std::string(infostr); +} + void Graphics::push() { if (userMatrices == matrixLimit) throw Exception("Maximum stack depth reached. (More pushes than pops?)"); glPushMatrix(); ++userMatrices; + pixel_size_stack.push_back(pixel_size_stack.back()); } void Graphics::pop() @@ -1155,6 +1041,7 @@ void Graphics::pop() throw Exception("Minimum stack depth reached. (More pops than pushes?)"); glPopMatrix(); --userMatrices; + pixel_size_stack.pop_back(); } void Graphics::rotate(float r) @@ -1165,6 +1052,7 @@ void Graphics::rotate(float r) void Graphics::scale(float x, float y) { glScalef(x, y, 1); + pixel_size_stack.back() *= 2. / (fabs(x) + fabs(y)); } void Graphics::translate(float x, float y) @@ -1179,9 +1067,10 @@ void Graphics::shear(float kx, float ky) glMultMatrixf((const GLfloat *)t.getElements()); } -bool Graphics::hasFocus() const +void Graphics::origin() { - return currentWindow->hasFocus(); + glLoadIdentity(); + pixel_size_stack.back() = 1; } } // opengl diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 6264853cb..1dc2c5c82 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,7 +23,8 @@ // STD #include -#include +#include +#include // OpenGL #include "OpenGL.h" @@ -39,13 +40,12 @@ #include "Font.h" #include "Image.h" -#include "Quad.h" +#include "graphics/Quad.h" #include "SpriteBatch.h" #include "ParticleSystem.h" #include "Canvas.h" #include "Shader.h" - -using love::window::WindowFlags; +#include "Mesh.h" namespace love { @@ -63,12 +63,12 @@ struct DisplayState Color color; Color backgroundColor; - // Blend and color modes. + // Blend mode. Graphics::BlendMode blendMode; - Graphics::ColorMode colorMode; // Line. Graphics::LineStyle lineStyle; + Graphics::LineJoin lineJoin; // Point. float pointSize; @@ -76,28 +76,23 @@ struct DisplayState // Scissor. bool scissor; - GLint scissorBox[4]; + OpenGL::Viewport scissorBox; - // Window info. - std::string caption; - bool mouseVisible; + // Color mask. + bool colorMask[4]; // Default values. DisplayState() { color.set(255,255,255,255); - backgroundColor.r = 0; - backgroundColor.g = 0; - backgroundColor.b = 0; - backgroundColor.a = 255; + backgroundColor.set(0, 0, 0, 255); blendMode = Graphics::BLEND_ALPHA; - colorMode = Graphics::COLOR_MODULATE; lineStyle = Graphics::LINE_SMOOTH; + lineJoin = Graphics::LINE_JOIN_MITER; pointSize = 1.0f; pointStyle = Graphics::POINT_SMOOTH; scissor = false; - caption = ""; - mouseVisible = true; + colorMask[0] = colorMask[1] = colorMask[2] = colorMask[3] = true; } }; @@ -112,40 +107,13 @@ public: // Implements Module. const char *getName() const; - /** - * Checks whether a display mode is supported or not. Note - * that fullscreen is assumed, because windowed modes are - * generally supported regardless of size. - * @param width The window width. - * @param height The window height. - **/ - bool checkMode(int width, int height, bool fullscreen) const; - DisplayState saveState(); void restoreState(const DisplayState &s); - /** - * Sets the current display mode. - * @param width The window width. - * @param height The window height. - * @param flags An optional WindowFlags structure. - **/ - bool setMode(int width, int height, WindowFlags *flags); - - /** - * Gets the current display mode. - * @param width Pointer to an integer for the window width. - * @param height Pointer to an integer for the window height. - * @param flags A WindowFlags structure. - **/ - void getMode(int &width, int &height, WindowFlags &flags) const; - - /** - * Toggles fullscreen. Note that this also needs to reload the - * entire OpenGL context. - **/ - bool toggleFullscreen(); + virtual void setViewportSize(int width, int height); + virtual bool setMode(int width, int height); + virtual void unSetMode(); /** * Resets the current color, background color, @@ -160,53 +128,25 @@ public: void clear(); /** - * Flips buffers. (Rendered geometry is - * presented on screen). + * Flips buffers. (Rendered geometry is presented on screen). **/ void present(); /** - * Sets the window's icon. - **/ - void setIcon(Image *image); - - /** - * Sets the window's caption. - **/ - void setCaption(const char *caption); - - int getCaption(lua_State *L) const; - - /** - * Gets the width of the current display mode. + * Gets the width of the current graphics viewport. **/ int getWidth() const; /** - * Gets the height of the current display mode. + * Gets the height of the current graphics viewport. **/ int getHeight() const; /** - * True if some display mode is set. + * True if a graphics viewport is set. **/ bool isCreated() const; - /** - * This native Lua function gets available modes - * from SDL and returns them as a table on the following format: - * - * { - * { width = 800, height = 600 }, - * { width = 1024, height = 768 }, - * ... - * } - * - * Only fullscreen modes are returned here, as all - * window sizes are supported (normally). - **/ - int getModes(lua_State *L) const; - /** * Scissor defines a box such that everything outside that box is discarded and not drawn. * Scissoring is automatically enabled. @@ -223,10 +163,10 @@ public: void setScissor(); /** - * This native Lua function gets the current scissor box in the order of: - * x, y, width, height - **/ - int getScissor(lua_State *L) const; + * Gets the current scissor box. + * @return Whether the scissor is enabled. + */ + bool getScissor(int &x, int &y, int &width, int &height) const; /** * Enables the stencil buffer and set stencil function to fill it @@ -247,29 +187,33 @@ public: void discardStencil(); /** - * Creates an Image object with padding and/or optimization. + * Gets the maximum supported width or height of Textures on this system. **/ - Image *newImage(love::filesystem::File *file); - Image *newImage(love::image::ImageData *data); + int getMaxTextureSize() const; /** - * Creates a Quad object. + * Creates an Image object with padding and/or optimization. **/ - Quad *newQuad(float x, float y, float w, float h, float sw, float sh); + Image *newImage(love::image::ImageData *data); + Image *newImage(love::image::CompressedData *cdata); + + Quad *newQuad(Quad::Viewport v, float sw, float sh); /** * Creates a Font object. **/ - Font *newFont(love::font::Rasterizer *data, const Image::Filter &filter = Image::Filter()); + Font *newFont(love::font::Rasterizer *data, const Texture::Filter &filter = Texture::getDefaultFilter()); - SpriteBatch *newSpriteBatch(Image *image, int size, int usage); + SpriteBatch *newSpriteBatch(Texture *texture, int size, int usage); - ParticleSystem *newParticleSystem(Image *image, int size); + ParticleSystem *newParticleSystem(Texture *texture, int size); Canvas *newCanvas(int width, int height, Canvas::TextureType texture_type = Canvas::TYPE_NORMAL); Shader *newShader(const Shader::ShaderSources &sources); + Mesh *newMesh(const std::vector &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN); + /** * Sets the foreground color. * @param c The new foreground color. @@ -301,35 +245,42 @@ public: **/ Font *getFont() const; + /** + * Sets the enabled color components when rendering. + **/ + void setColorMask(bool r, bool g, bool b, bool a); + + /** + * Gets the current color mask. + * Returns an array of 4 booleans representing the mask. + **/ + const bool *getColorMask() const; + /** * Sets the current blend mode. **/ void setBlendMode(BlendMode mode); - /** - * Sets the current color mode. - **/ - void setColorMode(ColorMode mode); - - /** - * Sets the current image filter. - **/ - void setDefaultImageFilter(const Image::Filter &f); - /** * Gets the current blend mode. **/ BlendMode getBlendMode() const; /** - * Gets the current color mode. + * Sets the default filter for images, canvases, and fonts. **/ - ColorMode getColorMode() const; + void setDefaultFilter(const Texture::Filter &f); /** - * Gets the current image filter. + * Gets the default filter for images, canvases, and fonts. **/ - const Image::Filter &getDefaultImageFilter() const; + const Texture::Filter &getDefaultFilter() const; + + /** + * Default Image mipmap filter mode and sharpness values. + **/ + void setDefaultMipmapFilter(Texture::FilterMode filter, float sharpness); + void getDefaultMipmapFilter(Texture::FilterMode *filter, float *sharpness) const; /** * Sets the line width. @@ -344,10 +295,10 @@ public: void setLineStyle(LineStyle style); /** - * Sets the type of line used to draw primitives. - * A shorthand for setLineWidth and setLineStyle. + * Sets the line style. + * @param style LINE_ROUGH or LINE_SMOOTH. **/ - void setLine(float width, LineStyle style); + void setLineJoin(LineJoin style); /** * Gets the line width. @@ -359,6 +310,11 @@ public: **/ LineStyle getLineStyle() const; + /** + * Gets the line style. + **/ + LineJoin getLineJoin() const; + /** * Sets the size of points. **/ @@ -370,11 +326,6 @@ public: **/ void setPointStyle(PointStyle style); - /** - * Shorthand for setPointSize and setPointStyle. - **/ - void setPoint(float size, PointStyle style); - /** * Gets the point size. **/ @@ -404,7 +355,7 @@ public: * @param kx Shear along the x-axis. * @param ky Shear along the y-axis. **/ - void print(const char *str, float x, float y , float angle, float sx, float sy, float ox, float oy, float kx, float ky); + void print(const std::string &str, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky); /** * Draw formatted text on screen at the specified coordinates. @@ -414,8 +365,15 @@ public: * @param y The y-coordinate. * @param wrap The maximum width of the text area. * @param align Where to align the text. + * @param angle The amount of rotation. + * @param sx The scale factor along the x-axis. (1 = normal). + * @param sy The scale factor along the y-axis. (1 = normal). + * @param ox The origin offset along the x-axis. + * @param oy The origin offset along the y-axis. + * @param kx Shear along the x-axis. + * @param ky Shear along the y-axis. **/ - void printf(const char *str, float x, float y, float wrap, AlignMode align); + void printf(const std::string &str, float x, float y, float wrap, AlignMode align, float angle, float sx, float sy, float ox, float oy, float kx, float ky); /** * Draws a point at (x,y). @@ -431,18 +389,6 @@ public: **/ void polyline(const float *coords, size_t count); - /** - * Draws a triangle using the three coordinates passed. - * @param mode The mode of drawing (line/filled). - * @param x1 First x-coordinate. - * @param y1 First y-coordinate. - * @param x2 Second x-coordinate. - * @param y2 Second y-coordinate. - * @param x3 Third x-coordinate. - * @param y3 Third y-coordinate. - **/ - void triangle(DrawMode mode, float x1, float y1, float x2, float y2, float x3, float y3); - /** * Draws a rectangle. * @param x Position along x-axis for top-left corner. @@ -452,20 +398,6 @@ public: **/ void rectangle(DrawMode mode, float x, float y, float w, float h); - /** - * Draws a quadrilateral using the four coordinates passed. - * @param mode The mode of drawing (line/filled). - * @param x1 First x-coordinate. - * @param y1 First y-coordinate. - * @param x2 Second x-coordinate. - * @param y2 Second y-coordinate. - * @param x3 Third x-coordinate. - * @param y3 Third y-coordinate. - * @param x4 Fourth x-coordinate. - * @param y4 Fourth y-coordinate. - **/ - void quad(DrawMode mode, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); - /** * Draws a circle using the specified arguments. * @param mode The mode of drawing (line/filled). @@ -490,7 +422,7 @@ public: /** * Draws a polygon with an arbitrary number of vertices. - * @param type The type of drawing (line/filled). + * @param mode The type of drawing (line/filled). * @param coords Vertex components (x1, y1, x2, y2, etc.) * @param count Coord array size **/ @@ -499,8 +431,17 @@ public: /** * Creates a screenshot of the view and saves it to the default folder. * @param image The love.image module. + * @param copyAlpha If the alpha channel should be copied or set to full opacity (255). **/ - love::image::ImageData *newScreenshot(love::image::Image *image); + love::image::ImageData *newScreenshot(love::image::Image *image, bool copyAlpha = true); + + /** + * Returns a string containing system-dependent renderer information. + * Returned string can vary greatly between systems! Do not rely on it for + * anything! + * @param infotype The type of information to return. + **/ + std::string getRendererInfo(Graphics::RendererInfo infotype) const; void push(); void pop(); @@ -508,19 +449,27 @@ public: void scale(float x, float y = 1.0f); void translate(float x, float y); void shear(float kx, float ky); + void origin(); - bool hasFocus() const; private: Font *currentFont; love::window::Window *currentWindow; + std::vector pixel_size_stack; // stores current size of a pixel (needed for line drawing) LineStyle lineStyle; + LineJoin lineJoin; float lineWidth; GLint matrixLimit; GLint userMatrices; + bool colorMask[4]; + + int width; + int height; + bool created; + + DisplayState savedState; - int getRenderHeight() const; }; // Graphics } // opengl diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 29c4deaf3..2d7719656 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,8 +24,6 @@ #include // For memcpy #include // for min/max -#include - namespace love { namespace graphics @@ -33,149 +31,181 @@ namespace graphics namespace opengl { +float Image::maxMipmapSharpness = 0.0f; + +Texture::FilterMode Image::defaultMipmapFilter = Texture::FILTER_NONE; +float Image::defaultMipmapSharpness = 0.0f; + Image::Image(love::image::ImageData *data) - : width((float)(data->getWidth())) - , height((float)(data->getHeight())) + : data(data) + , cdata(nullptr) + , paddedWidth(width) + , paddedHeight(height) , texture(0) - , mipmapSharpness(0.0f) + , mipmapSharpness(defaultMipmapSharpness) , mipmapsCreated(false) + , compressed(false) + , usingDefaultTexture(false) { + width = data->getWidth(); + height = data->getHeight(); + data->retain(); - this->data = data; + preload(); +} - memset(vertices, 255, sizeof(vertex)*4); +Image::Image(love::image::CompressedData *cdata) + : data(nullptr) + , cdata(cdata) + , paddedWidth(width) + , paddedHeight(height) + , texture(0) + , mipmapSharpness(defaultMipmapSharpness) + , mipmapsCreated(false) + , compressed(true) + , usingDefaultTexture(false) +{ + width = cdata->getWidth(0); + height = cdata->getHeight(0); - vertices[0].x = 0; - vertices[0].y = 0; - vertices[1].x = 0; - vertices[1].y = height; - vertices[2].x = width; - vertices[2].y = height; - vertices[3].x = width; - vertices[3].y = 0; - - vertices[0].s = 0; - vertices[0].t = 0; - vertices[1].s = 0; - vertices[1].t = 1; - vertices[2].s = 1; - vertices[2].t = 1; - vertices[3].s = 1; - vertices[3].t = 0; - - filter = getDefaultFilter(); + cdata->retain(); + preload(); } Image::~Image() { - if (data != 0) + if (data != nullptr) data->release(); + if (cdata != nullptr) + cdata->release(); unload(); } -float Image::getWidth() const -{ - return width; -} - -float Image::getHeight() const -{ - return height; -} - -const vertex *Image::getVertices() const -{ - return vertices; -} - -love::image::ImageData *Image::getData() const +love::image::ImageData *Image::getImageData() const { return data; } -void Image::getRectangleVertices(int x, int y, int w, int h, vertex *vertices) const +love::image::CompressedData *Image::getCompressedData() const { - // Check upper. - x = (x+w > (int)width) ? (int)width-w : x; - y = (y+h > (int)height) ? (int)height-h : y; - - // Check lower. - x = (x < 0) ? 0 : x; - y = (y < 0) ? 0 : y; - - vertices[0].x = 0; - vertices[0].y = 0; - vertices[1].x = 0; - vertices[1].y = (float)h; - vertices[2].x = (float)w; - vertices[2].y = (float)h; - vertices[3].x = (float)w; - vertices[3].y = 0; - - float tx = (float)x/width; - float ty = (float)y/height; - float tw = (float)w/width; - float th = (float)h/height; - - vertices[0].s = tx; - vertices[0].t = ty; - vertices[1].s = tx; - vertices[1].t = ty+th; - vertices[2].s = tx+tw; - vertices[2].t = ty+th; - vertices[3].s = tx+tw; - vertices[3].t = ty; + return cdata; } void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { - static Matrix t; - + Matrix t; t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + drawv(t, vertices); } -void Image::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 Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { - static Matrix t; - const vertex *v = quad->getVertices(); - + Matrix t; t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); - drawv(t, v); + + drawv(t, quad->getVertices()); } -void Image::checkMipmapsCreated() +void Image::predraw() const { - if (mipmapsCreated || (filter.mipmap != FILTER_NEAREST && filter.mipmap != FILTER_LINEAR)) + bind(); + + if (width != paddedWidth || height != paddedHeight) + { + // NPOT image padded to POT size, so the texcoords should be scaled. + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glScalef(float(width) / float(paddedWidth), float(height) / float(paddedHeight), 0.0f); + glMatrixMode(GL_MODELVIEW); + } +} + +void Image::postdraw() const +{ + if (width != paddedWidth || height != paddedHeight) + { + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + } +} + +GLuint Image::getGLTexture() const +{ + return texture; +} + +void Image::uploadCompressedMipmaps() +{ + if (!isCompressed() || !cdata || !hasCompressedTextureSupport(cdata->getFormat())) + return; + + bind(); + + int count = cdata->getMipmapCount(); + + // We have to inform OpenGL if the image doesn't have all mipmap levels. + if (GLEE_VERSION_1_2 || GLEE_SGIS_texture_lod) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1); + } + else if (cdata->getWidth(count-1) > 1 || cdata->getHeight(count-1) > 1) + { + // Telling OpenGL to ignore certain levels isn't always supported. + throw love::Exception("Cannot load mipmaps: " + "compressed image does not have all required levels."); + } + + for (int i = 1; i < count; i++) + { + glCompressedTexImage2DARB(GL_TEXTURE_2D, + i, + getCompressedFormat(cdata->getFormat()), + cdata->getWidth(i), + cdata->getHeight(i), + 0, + GLsizei(cdata->getSize(i)), + cdata->getData(i)); + } +} + +void Image::createMipmaps() +{ + // Only valid for Images created with ImageData. + if (!data || isCompressed()) return; if (!hasMipmapSupport()) throw love::Exception("Mipmap filtering is not supported on this system."); - // Some old drivers claim support for NPOT textures, but fail when creating mipmaps. - // we can't detect which systems will do this, so we fail gracefully for all NPOT images. + // Some old drivers claim support for NPOT textures, but fail when creating + // mipmaps. We can't detect which systems will do this, so we fail gracefully + // for all NPOT images. int w = int(width), h = int(height); if (w != next_p2(w) || h != next_p2(h)) - throw love::Exception("Cannot create mipmaps: image does not have power of two dimensions."); + { + throw love::Exception("Cannot create mipmaps: " + "image does not have power of two dimensions."); + } bind(); + // Prevent other threads from changing the ImageData while we upload it. + love::thread::Lock lock(data->getMutex()); + if (hasNpot() && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object)) { - // AMD/ATI drivers have several bugs when generating mipmaps, - // re-uploading the entire base image seems to be required. - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA8, - (GLsizei)width, - (GLsizei)height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - data->getData()); + if (gl.getVendor() == OpenGL::VENDOR_ATI_AMD) + { + // AMD/ATI drivers have several bugs when generating mipmaps, + // re-uploading the entire base image seems to be required. + uploadTexture(); + + // More bugs: http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation + glEnable(GL_TEXTURE_2D); + } - // More bugs: http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation - glEnable(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D); } else @@ -191,47 +221,61 @@ void Image::checkMipmapsCreated() GL_UNSIGNED_BYTE, data->getData()); } +} + +void Image::checkMipmapsCreated() +{ + if (mipmapsCreated || filter.mipmap == FILTER_NONE || usingDefaultTexture) + return; + + if (isCompressed() && cdata && hasCompressedTextureSupport(cdata->getFormat())) + uploadCompressedMipmaps(); + else if (data) + createMipmaps(); + else + return; mipmapsCreated = true; } -void Image::setFilter(const Image::Filter &f) +void Image::setFilter(const Texture::Filter &f) { filter = f; + // We don't want filtering or (attempted) mipmaps on the default texture. + if (usingDefaultTexture) + { + filter.mipmap = FILTER_NONE; + filter.min = filter.mag = FILTER_NEAREST; + } + bind(); - setTextureFilter(f); + gl.setTextureFilter(filter); checkMipmapsCreated(); } -const Image::Filter &Image::getFilter() const -{ - return filter; -} - -void Image::setWrap(const Image::Wrap &w) +void Image::setWrap(const Texture::Wrap &w) { wrap = w; bind(); - setTextureWrap(w); -} - -const Image::Wrap &Image::getWrap() const -{ - return wrap; + gl.setTextureWrap(w); } void Image::setMipmapSharpness(float sharpness) { - if (!hasMipmapSharpnessSupport()) - return; + if (hasMipmapSharpnessSupport()) + { + // LOD bias has the range (-maxbias, maxbias) + mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f); - // LOD bias has the range (-maxbias, maxbias) - mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f); + bind(); - bind(); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness); // negative bias is sharper + // negative bias is sharper + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness); + } + else + mipmapSharpness = 0.0f; } float Image::getMipmapSharpness() const @@ -244,7 +288,32 @@ void Image::bind() const if (texture == 0) return; - bindTexture(texture); + gl.bindTexture(texture); +} + +void Image::preload() +{ + memset(vertices, 255, sizeof(Vertex)*4); + + vertices[0].x = 0; + vertices[0].y = 0; + vertices[1].x = 0; + vertices[1].y = (float) height; + vertices[2].x = (float) width; + vertices[2].y = (float) height; + vertices[3].x = (float) width; + vertices[3].y = 0; + + vertices[0].s = 0; + vertices[0].t = 0; + vertices[1].s = 0; + vertices[1].t = 1; + vertices[2].s = 1; + vertices[2].t = 1; + vertices[3].s = 1; + vertices[3].t = 0; + + filter.mipmap = defaultMipmapFilter; } bool Image::load() @@ -259,93 +328,125 @@ void Image::unload() bool Image::loadVolatile() { - if (hasMipmapSharpnessSupport()) + if (isCompressed() && cdata && !hasCompressedTextureSupport(cdata->getFormat())) + { + const char *str; + if (image::CompressedData::getConstant(cdata->getFormat(), str)) + { + throw love::Exception("Cannot create image: " + "%s compressed images are not supported on this system.", str); + } + else + throw love::Exception("cannot create image: format is not supported on this system."); + } + + if (hasMipmapSharpnessSupport() && maxMipmapSharpness == 0.0f) glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &maxMipmapSharpness); - if (hasNpot()) - return loadVolatileNPOT(); + glGenTextures(1, &texture); + gl.bindTexture(texture); + + filter.anisotropy = gl.setTextureFilter(filter); + gl.setTextureWrap(wrap); + setMipmapSharpness(mipmapSharpness); + + paddedWidth = width; + paddedHeight = height; + + if (!hasNpot()) + { + // NPOT textures will be padded to POT dimensions if necessary. + paddedWidth = next_p2(width); + paddedHeight = next_p2(height); + } + + // Use a default texture if the size is too big for the system. + if (paddedWidth > gl.getMaxTextureSize() || paddedHeight > gl.getMaxTextureSize()) + { + uploadDefaultTexture(); + return true; + } + + // Mutex lock will potentially cover texture loading and mipmap creation. + love::thread::EmptyLock lock; + if (data) + lock.setLock(data->getMutex()); + + while (glGetError() != GL_NO_ERROR); // Clear errors. + + if (hasNpot() || (width == paddedWidth && height == paddedHeight)) + uploadTexture(); else - return loadVolatilePOT(); -} + uploadTexturePadded(); -bool Image::loadVolatilePOT() -{ - glGenTextures(1,(GLuint *)&texture); - bindTexture(texture); - - setTextureFilter(filter); - setTextureWrap(wrap); - - float p2width = next_p2(width); - float p2height = next_p2(height); - float s = width/p2width; - float t = height/p2height; - - vertices[1].t = t; - vertices[2].t = t; - vertices[2].s = s; - vertices[3].s = s; - - while (glGetError() != GL_NO_ERROR); // clear errors - - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA8, - (GLsizei)p2width, - (GLsizei)p2height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - 0); - - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - (GLsizei)width, - (GLsizei)height, - GL_RGBA, - GL_UNSIGNED_BYTE, - data->getData()); - - if (glGetError() != GL_NO_ERROR) - throw love::Exception("Cannot create image: size may be too large for this system."); + GLenum glerr = glGetError(); + if (glerr != GL_NO_ERROR) + throw love::Exception("Cannot create image (error code 0x%x)", glerr); + usingDefaultTexture = false; mipmapsCreated = false; checkMipmapsCreated(); - setMipmapSharpness(mipmapSharpness); return true; } -bool Image::loadVolatileNPOT() +void Image::uploadTexturePadded() { - glGenTextures(1,(GLuint *)&texture); - bindTexture(texture); + if (isCompressed() && cdata) + { + // Padded textures don't really work if they're compressed... + throw love::Exception("Cannot create image: " + "compressed NPOT images are not supported on this system."); + } + else if (data) + { + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA8, + (GLsizei)paddedWidth, + (GLsizei)paddedHeight, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + 0); - setTextureFilter(filter); - setTextureWrap(wrap); + glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, 0, + (GLsizei)width, + (GLsizei)height, + GL_RGBA, + GL_UNSIGNED_BYTE, + data->getData()); + } +} - while (glGetError() != GL_NO_ERROR); // clear errors - - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA8, - (GLsizei)width, - (GLsizei)height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - data->getData()); - - if (glGetError() != GL_NO_ERROR) - throw love::Exception("Cannot create image: size may be too large for this system."); - - mipmapsCreated = false; - checkMipmapsCreated(); - setMipmapSharpness(mipmapSharpness); - - return true; +void Image::uploadTexture() +{ + if (isCompressed() && cdata) + { + GLenum format = getCompressedFormat(cdata->getFormat()); + glCompressedTexImage2DARB(GL_TEXTURE_2D, + 0, + format, + cdata->getWidth(0), + cdata->getHeight(0), + 0, + GLsizei(cdata->getSize(0)), + cdata->getData(0)); + } + else if (data) + { + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA8, + (GLsizei)width, + (GLsizei)height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + data->getData()); + } } void Image::unloadVolatile() @@ -353,28 +454,134 @@ void Image::unloadVolatile() // Delete the hardware texture. if (texture != 0) { - deleteTexture(texture); + gl.deleteTexture(texture); texture = 0; } } -void Image::drawv(const Matrix &t, const vertex *v) const +bool Image::refresh() { + // No effect if the texture hasn't been created yet. + if (texture == 0) + return false; + + if (usingDefaultTexture) + { + uploadDefaultTexture(); + return true; + } + + // We want this lock to potentially cover mipmap creation as well. + love::thread::EmptyLock lock; + bind(); + if (data && !isCompressed()) + lock.setLock(data->getMutex()); + + while (glGetError() != GL_NO_ERROR); // Clear errors. + + if (hasNpot() || (width == paddedWidth && height == paddedHeight)) + uploadTexture(); + else + uploadTexturePadded(); + + if (glGetError() != GL_NO_ERROR) + uploadDefaultTexture(); + else + usingDefaultTexture = false; + + mipmapsCreated = false; + checkMipmapsCreated(); + + return true; +} + +void Image::uploadDefaultTexture() +{ + usingDefaultTexture = true; + + bind(); + setFilter(filter); + + // A nice friendly checkerboard to signify invalid textures... + GLubyte px[] = {0xFF,0xFF,0xFF,0xFF, 0xC0,0xC0,0xC0,0xFF, + 0xC0,0xC0,0xC0,0xFF, 0xFF,0xFF,0xFF,0xFF}; + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px); +} + +void Image::drawv(const Matrix &t, const Vertex *v) const +{ + predraw(); + glPushMatrix(); glMultMatrixf((const GLfloat *)t.getElements()); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].x); - glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&v[0].s); + + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s); + + gl.prepareDraw(); glDrawArrays(GL_QUADS, 0, 4); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); + + postdraw(); +} + +void Image::setDefaultMipmapSharpness(float sharpness) +{ + defaultMipmapSharpness = sharpness; +} + +float Image::getDefaultMipmapSharpness() +{ + return defaultMipmapSharpness; +} + +void Image::setDefaultMipmapFilter(Texture::FilterMode f) +{ + defaultMipmapFilter = f; +} + +Texture::FilterMode Image::getDefaultMipmapFilter() +{ + return defaultMipmapFilter; +} + +bool Image::isCompressed() const +{ + return compressed; +} + +GLenum Image::getCompressedFormat(image::CompressedData::Format format) const +{ + switch (format) + { + case image::CompressedData::FORMAT_DXT1: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case image::CompressedData::FORMAT_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case image::CompressedData::FORMAT_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case image::CompressedData::FORMAT_BC4: + return GL_COMPRESSED_RED_RGTC1; + case image::CompressedData::FORMAT_BC4s: + return GL_COMPRESSED_SIGNED_RED_RGTC1; + case image::CompressedData::FORMAT_BC5: + return GL_COMPRESSED_RG_RGTC2; + case image::CompressedData::FORMAT_BC5s: + return GL_COMPRESSED_SIGNED_RG_RGTC2; + default: + return GL_RGBA8; + } } bool Image::hasNpot() @@ -382,6 +589,11 @@ bool Image::hasNpot() return GLEE_VERSION_2_0 || GLEE_ARB_texture_non_power_of_two; } +bool Image::hasAnisotropicFilteringSupport() +{ + return GLEE_EXT_texture_filter_anisotropic; +} + bool Image::hasMipmapSupport() { return GLEE_VERSION_1_4 || GLEE_SGIS_generate_mipmap; @@ -389,7 +601,35 @@ bool Image::hasMipmapSupport() bool Image::hasMipmapSharpnessSupport() { - return GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias; + return GLEE_VERSION_1_4; +} + +bool Image::hasCompressedTextureSupport() +{ + return GLEE_VERSION_1_3 || GLEE_ARB_texture_compression; +} + +bool Image::hasCompressedTextureSupport(image::CompressedData::Format format) +{ + if (!hasCompressedTextureSupport()) + return false; + + switch (format) + { + case image::CompressedData::FORMAT_DXT1: + case image::CompressedData::FORMAT_DXT3: + case image::CompressedData::FORMAT_DXT5: + return GLEE_EXT_texture_compression_s3tc; + case image::CompressedData::FORMAT_BC4: + case image::CompressedData::FORMAT_BC4s: + case image::CompressedData::FORMAT_BC5: + case image::CompressedData::FORMAT_BC5s: + return (GLEE_VERSION_3_0 || GLEE_ARB_texture_compression_rgtc || GLEE_EXT_texture_compression_rgtc); + default: + break; + } + + return false; } } // opengl diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index ea4f05bfb..0622fb8dc 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,11 +22,13 @@ #define LOVE_GRAPHICS_OPENGL_IMAGE_H // LOVE -#include "common/Matrix.h" -#include "common/math.h" #include "common/config.h" +#include "common/Matrix.h" +#include "common/Vector.h" +#include "common/math.h" #include "image/ImageData.h" -#include "graphics/Image.h" +#include "image/CompressedData.h" +#include "Texture.h" // OpenGL #include "OpenGL.h" @@ -44,7 +46,7 @@ namespace opengl * * @author Anders Ruud **/ -class Image : public love::graphics::Image +class Image : public Texture { public: @@ -52,35 +54,24 @@ public: * Creates a new Image. Not that anything is ready to use * before load is called. * - * @param file The file from which to load the image. + * @param data The data from which to load the image. **/ Image(love::image::ImageData *data); + /** + * Creates a new Image with compressed image data. + * + * @param cdata The compressed data from which to load the image. + **/ + Image(love::image::CompressedData *cdata); + /** * Destructor. Deletes the hardware texture and other resources. **/ virtual ~Image(); - float getWidth() const; - float getHeight() const; - - const vertex *getVertices() const; - - love::image::ImageData *getData() const; - - /** - * Generate vertices according to a subimage. - * - * Note: out-of-range values will be clamped. - * Note: the vertex colors will not be changed. - * - * @param x The top-left corner of the subimage along the x-axis. - * @param y The top-left corner of the subimage along the y-axis. - * @param w The width of the subimage. - * @param h The height of the subimage. - * @param vertices A vertex array of size four. - **/ - void getRectangleVertices(int x, int y, int w, int h, vertex *vertices) const; + love::image::ImageData *getImageData() const; + love::image::CompressedData *getCompressedData() const; /** * @copydoc Drawable::draw() @@ -88,26 +79,31 @@ public: void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; /** - * @copydoc DrawQable::drawq() + * @copydoc Texture::drawq() **/ - void 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 drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; /** - * Sets the filter mode. - * @param f The filter mode. + * Call before using this Image's texture to draw. Binds the texture, + * globally scales texture coordinates if the Image has NPOT dimensions and + * NPOT isn't supported, etc. **/ - void setFilter(const Image::Filter &f); + virtual void predraw() const; + virtual void postdraw() const; - const Image::Filter &getFilter() const; + virtual GLuint getGLTexture() const; - void setWrap(const Image::Wrap &w); - - const Image::Wrap &getWrap() const; + virtual void setFilter(const Texture::Filter &f); + virtual void setWrap(const Texture::Wrap &w); void setMipmapSharpness(float sharpness); - float getMipmapSharpness() const; + /** + * Whether this Image is using a compressed texture (via CompressedData). + **/ + bool isCompressed() const; + void bind() const; bool load(); @@ -117,51 +113,75 @@ public: bool loadVolatile(); void unloadVolatile(); + /** + * Re-uploads the ImageData or CompressedData associated with this Image to + * the GPU, allowing situations where lovers modify an ImageData after image + * creation from the ImageData, and apply the changes with Image:refresh(). + **/ + bool refresh(); + + static void setDefaultMipmapSharpness(float sharpness); + static float getDefaultMipmapSharpness(); + static void setDefaultMipmapFilter(FilterMode f); + static FilterMode getDefaultMipmapFilter(); + static bool hasNpot(); + static bool hasAnisotropicFilteringSupport(); static bool hasMipmapSupport(); static bool hasMipmapSharpnessSupport(); + static bool hasCompressedTextureSupport(); + static bool hasCompressedTextureSupport(image::CompressedData::Format format); + private: - void drawv(const Matrix &t, const vertex *v) const; + void uploadDefaultTexture(); - friend class Shader; - GLuint getTextureName() const - { - return texture; - } - // The ImageData from which the texture is created. + void drawv(const Matrix &t, const Vertex *v) const; + + // The ImageData from which the texture is created. May be null if + // Compressed image data was used to create the texture. love::image::ImageData *data; - // Width and height of the hardware texture. - float width, height; + // Or the Compressed Image Data from which the texture is created. May be + // null if raw ImageData was used to create the texture. + love::image::CompressedData *cdata; + + // Real dimensions of the texture, if it was auto-padded to POT size. + int paddedWidth, paddedHeight; // OpenGL texture identifier. GLuint texture; - // The source vertices of the image. - vertex vertices[4]; - // Mipmap texture LOD bias (sharpness) value. float mipmapSharpness; - // Implementation-dependent min/max mipmap sharpness values. - float maxMipmapSharpness; - // True if mipmaps have been created for this Image. bool mipmapsCreated; - // The image's filter mode - Image::Filter filter; + // Whether this Image is using a compressed texture. + bool compressed; - // The image's wrap mode - Image::Wrap wrap; + // True if the image wasn't able to be properly created and it had to fall + // back to a default texture. + bool usingDefaultTexture; - bool loadVolatilePOT(); - bool loadVolatileNPOT(); + void preload(); + void uploadTexturePadded(); + void uploadTexture(); + + void uploadCompressedMipmaps(); + void createMipmaps(); void checkMipmapsCreated(); + static float maxMipmapSharpness; + + static FilterMode defaultMipmapFilter; + static float defaultMipmapSharpness; + + GLenum getCompressedFormat(image::CompressedData::Format format) const; + }; // Image } // opengl diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp new file mode 100644 index 000000000..f73ff7dca --- /dev/null +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -0,0 +1,347 @@ +/** + * Copyright (c) 2006-2014 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 "Mesh.h" +#include "common/Matrix.h" +#include "common/Exception.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Mesh::Mesh(const std::vector &verts, Mesh::DrawMode mode) + : vbo(nullptr) + , vertex_count(0) + , ibo(nullptr) + , element_count(0) + , draw_mode(mode) + , texture(nullptr) + , colors_enabled(false) + , wireframe(false) +{ + setVertices(verts); +} + +Mesh::~Mesh() +{ + delete vbo; + delete ibo; +} + +void Mesh::setVertices(const std::vector &verts) +{ + if (verts.size() < 3) + throw love::Exception("At least 3 vertices are required."); + + size_t size = sizeof(Vertex) * verts.size(); + + if (vbo && size > vbo->getSize()) + { + delete vbo; + vbo = nullptr; + } + + if (!vbo) + { + // Full memory backing because we might access the data at any time. + vbo = VertexBuffer::Create(size, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, VertexBuffer::BACKING_FULL); + } + + vertex_count = verts.size(); + + VertexBuffer::Bind vbo_bind(*vbo); + VertexBuffer::Mapper vbo_mapper(*vbo); + + // Fill the buffer with the vertices. + memcpy(vbo_mapper.get(), &verts[0], size); +} + +const Vertex *Mesh::getVertices() const +{ + if (vbo) + { + VertexBuffer::Bind vbo_bind(*vbo); + return (Vertex *) vbo->map(); + } + + return nullptr; +} + +void Mesh::setVertex(size_t index, const Vertex &v) +{ + if (index >= vertex_count) + throw love::Exception("Invalid vertex index: %ld", index + 1); + + VertexBuffer::Bind vbo_bind(*vbo); + + // We unmap the vertex buffer in Mesh::draw. This lets us coalesce the + // buffer transfer calls into just one. + Vertex *vertices = (Vertex *) vbo->map(); + vertices[index] = v; +} + +Vertex Mesh::getVertex(size_t index) const +{ + if (index >= vertex_count) + throw love::Exception("Invalid vertex index: %ld", index + 1); + + VertexBuffer::Bind vbo_bind(*vbo); + + // We unmap the vertex buffer in Mesh::draw. + Vertex *vertices = (Vertex *) vbo->map(); + return vertices[index]; +} + +size_t Mesh::getVertexCount() const +{ + return vertex_count; +} + +void Mesh::setVertexMap(const std::vector &map) +{ + for (size_t i = 0; i < map.size(); i++) + { + if (map[i] >= vertex_count) + throw love::Exception("Invalid vertex map value: %d", map[i] + 1); + } + + size_t size = sizeof(uint32) * map.size(); + + if (ibo && size > ibo->getSize()) + { + delete ibo; + ibo = nullptr; + } + + if (!ibo && size > 0) + { + // Full memory backing because we might access the data at any time. + ibo = VertexBuffer::Create(size, GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, VertexBuffer::BACKING_FULL); + } + + element_count = map.size(); + + if (ibo && element_count > 0) + { + VertexBuffer::Bind ibo_bind(*ibo); + VertexBuffer::Mapper ibo_map(*ibo); + + // Fill the buffer. + memcpy(ibo_map.get(), &map[0], size); + } +} + +const uint32 *Mesh::getVertexMap() const +{ + if (ibo && element_count > 0) + { + VertexBuffer::Bind ibo_bind(*ibo); + + // We unmap the buffer in Mesh::draw and Mesh::setVertexMap. + return (uint32 *) ibo->map(); + } + + return 0; +} + +size_t Mesh::getVertexMapCount() const +{ + return element_count; +} + +void Mesh::setTexture(Texture *tex) +{ + tex->retain(); + + if (texture) + texture->release(); + + texture = tex; +} + +void Mesh::setTexture() +{ + if (texture) + texture->release(); + + texture = nullptr; +} + +Texture *Mesh::getTexture() const +{ + return texture; +} + +void Mesh::setDrawMode(Mesh::DrawMode mode) +{ + draw_mode = mode; +} + +Mesh::DrawMode Mesh::getDrawMode() const +{ + return draw_mode; +} + +void Mesh::setVertexColors(bool enable) +{ + colors_enabled = enable; +} + +bool Mesh::hasVertexColors() const +{ + return colors_enabled; +} + +void Mesh::setWireframe(bool enable) +{ + wireframe = enable; +} + +bool Mesh::isWireframe() const +{ + return wireframe; +} + +void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +{ + const size_t pos_offset = offsetof(Vertex, x); + const size_t tex_offset = offsetof(Vertex, s); + const size_t color_offset = offsetof(Vertex, r); + + if (vertex_count == 0) + return; + + if (texture) + texture->predraw(); + else + gl.bindTexture(0); + + Matrix m; + m.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + + glPushMatrix(); + glMultMatrixf(m.getElements()); + + VertexBuffer::Bind vbo_bind(*vbo); + + // Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.) + vbo->unmap(); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vbo->getPointer(pos_offset)); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), vbo->getPointer(tex_offset)); + + if (hasVertexColors()) + { + // Per-vertex colors. + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), vbo->getPointer(color_offset)); + } + + if (wireframe) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + GLenum mode = getGLDrawMode(draw_mode); + + gl.prepareDraw(); + + if (ibo && element_count > 0) + { + VertexBuffer::Bind ibo_bind(*ibo); + + // Make sure the index buffer isn't mapped (sends data to GPU if needed.) + ibo->unmap(); + + // Use the custom vertex map to draw the vertices. + glDrawElements(mode, element_count, GL_UNSIGNED_INT, ibo->getPointer(0)); + } + else + { + // Normal non-indexed drawing (no custom vertex map.) + glDrawArrays(mode, 0, vertex_count); + } + + if (wireframe) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (hasVertexColors()) + { + glDisableClientState(GL_COLOR_ARRAY); + // Using the color array leaves the GL constant color undefined. + gl.setColor(gl.getColor()); + } + + glPopMatrix(); + + if (texture) + texture->postdraw(); +} + +GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const +{ + switch (mode) + { + case DRAW_MODE_FAN: + return GL_TRIANGLE_FAN; + case DRAW_MODE_STRIP: + return GL_TRIANGLE_STRIP; + case DRAW_MODE_TRIANGLES: + return GL_TRIANGLES; + case DRAW_MODE_POINTS: + return GL_POINTS; + default: + break; + } + + return GL_TRIANGLES; +} + +bool Mesh::getConstant(const char *in, Mesh::DrawMode &out) +{ + return drawModes.find(in, out); +} + +bool Mesh::getConstant(Mesh::DrawMode in, const char *&out) +{ + return drawModes.find(in, out); +} + +StringMap::Entry Mesh::drawModeEntries[] = +{ + {"fan", Mesh::DRAW_MODE_FAN}, + {"strip", Mesh::DRAW_MODE_STRIP}, + {"triangles", Mesh::DRAW_MODE_TRIANGLES}, + {"points", Mesh::DRAW_MODE_POINTS}, +}; + +StringMap Mesh::drawModes(Mesh::drawModeEntries, sizeof(Mesh::drawModeEntries)); + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h new file mode 100644 index 000000000..498e501ed --- /dev/null +++ b/src/modules/graphics/opengl/Mesh.h @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_GRAPHICS_OPENGL_MESH_H +#define LOVE_GRAPHICS_OPENGL_MESH_H + +// LOVE +#include "common/int.h" +#include "common/math.h" +#include "common/StringMap.h" +#include "graphics/Drawable.h" +#include "Texture.h" +#include "VertexBuffer.h" + +// C++ +#include + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +/** + * Holds and draws arbitrary vertex geometry. + * Each vertex in the Mesh has a position, texture coordinate, and color. + **/ +class Mesh : public Drawable +{ +public: + + // How the Mesh's vertices are used when drawing. + // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png + enum DrawMode + { + DRAW_MODE_FAN, + DRAW_MODE_STRIP, + DRAW_MODE_TRIANGLES, + DRAW_MODE_POINTS, + DRAW_MODE_MAX_ENUM + }; + + /** + * Constructor. + * @param verts The vertices to use in the Mesh. + * @param mode The draw mode to use when drawing the Mesh. + **/ + Mesh(const std::vector &verts, DrawMode mode = DRAW_MODE_FAN); + virtual ~Mesh(); + + /** + * Replaces all the vertices in the Mesh with a new set of vertices. + **/ + void setVertices(const std::vector &verts); + + /** + * Gets all of the vertices in the Mesh as an array. + **/ + const Vertex *getVertices() const; + + /** + * Sets an individual vertex in the Mesh. + * @param index The index into the list of vertices to use. + * @param v The new vertex. + **/ + void setVertex(size_t index, const Vertex &v); + Vertex getVertex(size_t index) const; + + /** + * Gets the total number of vertices in the Mesh. + **/ + size_t getVertexCount() const; + + /** + * Sets the vertex map to use when drawing the Mesh. The vertex map + * determines the order in which vertices are used by the draw mode. + * A 0-element vector is equivalent to the default vertex map: + * {0, 1, 2, 3, 4, ...} + **/ + void setVertexMap(const std::vector &map); + + /** + * Gets a pointer to the vertex map array. The pointer is only valid until + * the next function call in the graphics module. + * May return null if the vertex map is empty. + **/ + const uint32 *getVertexMap() const; + + /** + * Gets the total number of elements in the vertex map array. + **/ + size_t getVertexMapCount() const; + + /** + * Sets the texture used when drawing the Mesh. + **/ + void setTexture(Texture *texture); + + /** + * Disables any texture from being used when drawing the Mesh. + **/ + void setTexture(); + + /** + * Gets the texture used when drawing the Mesh. May return null if no + * texture is set. + **/ + Texture *getTexture() const; + + /** + * Sets the draw mode used when drawing the Mesh. + **/ + void setDrawMode(DrawMode mode); + DrawMode getDrawMode() const; + + /** + * Sets whether per-vertex colors are enabled. If this is disabled, the + * global color (love.graphics.setColor) will be used for the entire Mesh. + **/ + void setVertexColors(bool enable); + bool hasVertexColors() const; + + /** + * Sets whether the Mesh will be drawn as wireframe lines instead of filled + * triangles (has no effect for DRAW_MODE_POINTS.) + * This should only be used as a debugging tool. The wireframe lines do not + * behave the same as regular love.graphics lines. + **/ + void setWireframe(bool enable); + bool isWireframe() const; + + // Implements Drawable. + void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + + static bool getConstant(const char *in, DrawMode &out); + static bool getConstant(DrawMode in, const char *&out); + +private: + + GLenum getGLDrawMode(DrawMode mode) const; + + // Vertex buffer. + VertexBuffer *vbo; + size_t vertex_count; + + // Element (vertex index) buffer, for the vertex map. + VertexBuffer *ibo; + size_t element_count; + + DrawMode draw_mode; + + Texture *texture; + + // Whether the per-vertex colors are used when drawing. + bool colors_enabled; + + bool wireframe; + + static StringMap::Entry drawModeEntries[]; + static StringMap drawModes; + +}; // Mesh + +} // opengl +} // graphics +} // love + +#endif // LOVE_GRAPHICS_OPENGL_MESH_H diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 10afe3c9b..18301f223 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,15 +18,20 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "common/config.h" +#include "OpenGL.h" + +#include "Shader.h" +#include "Canvas.h" #include "common/Exception.h" -#include "OpenGL.h" -#include "Shader.h" - -#include +// C++ #include +// C +#include + namespace love { namespace graphics @@ -34,49 +39,119 @@ namespace graphics namespace opengl { -static bool contextInitialized = false; +OpenGL::OpenGL() + : contextInitialized(false) + , maxAnisotropy(1.0f) + , maxTextureSize(0) + , vendor(VENDOR_UNKNOWN) + , state() +{ +} -static int curTextureUnit = 0; -static std::vector textureUnits; - -void initializeContext() +void OpenGL::initContext() { if (contextInitialized) return; - contextInitialized = true; + initOpenGLFunctions(); + initVendor(); - // initialize multiple texture unit support for shaders, if available - textureUnits.clear(); + // Store the current color so we don't have to get it through GL later. + GLfloat glcolor[4]; + glGetFloatv(GL_CURRENT_COLOR, glcolor); + state.color.r = glcolor[0] * 255; + state.color.g = glcolor[1] * 255; + state.color.b = glcolor[2] * 255; + state.color.a = glcolor[3] * 255; + + // Same with the current clear color. + glGetFloatv(GL_COLOR_CLEAR_VALUE, glcolor); + state.clearColor.r = glcolor[0] * 255; + state.clearColor.g = glcolor[1] * 255; + state.clearColor.b = glcolor[2] * 255; + state.clearColor.a = glcolor[3] * 255; + + // Get the current viewport. + glGetIntegerv(GL_VIEWPORT, (GLint *) &state.viewport.x); + + // And the current scissor - but we need to compensate for GL scissors + // starting at the bottom left instead of top left. + glGetIntegerv(GL_SCISSOR_BOX, (GLint *) &state.scissor.x); + state.scissor.y = state.viewport.h - (state.scissor.y + state.scissor.h); + + // Initialize multiple texture unit support for shaders, if available. + state.textureUnits.clear(); if (Shader::isSupported()) { GLint maxtextureunits; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtextureunits); - textureUnits.resize(maxtextureunits, 0); + state.textureUnits.resize(maxtextureunits, 0); GLenum curgltextureunit; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *) &curgltextureunit); - curTextureUnit = curgltextureunit - GL_TEXTURE0; + state.curTextureUnit = (int) curgltextureunit - GL_TEXTURE0; - // Retrieve currently bound textures for each texture unit - for (size_t i = 0; i < textureUnits.size(); i++) + // Retrieve currently bound textures for each texture unit. + for (size_t i = 0; i < state.textureUnits.size(); i++) { glActiveTexture(GL_TEXTURE0 + i); - glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &textureUnits[i]); + glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &state.textureUnits[i]); } glActiveTexture(curgltextureunit); } else { - // multitexturing not supported, so we only have 1 texture unit - textureUnits.resize(1, 0); - curTextureUnit = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &textureUnits[0]); + // Multitexturing not supported, so we only have 1 texture unit. + state.textureUnits.resize(1, 0); + state.curTextureUnit = 0; + glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &state.textureUnits[0]); } + initMaxValues(); + createDefaultTexture(); + + contextInitialized = true; +} + +void OpenGL::deInitContext() +{ + if (!contextInitialized) + return; + + contextInitialized = false; +} + +void OpenGL::initVendor() +{ + const char *vstr = (const char *) glGetString(GL_VENDOR); + if (!vstr) + { + vendor = VENDOR_UNKNOWN; + return; + } + + // http://feedback.wildfiregames.com/report/opengl/feature/GL_VENDOR + if (strstr(vstr, "ATI Technologies")) + vendor = VENDOR_ATI_AMD; + else if (strstr(vstr, "NVIDIA")) + vendor = VENDOR_NVIDIA; + else if (strstr(vstr, "Intel")) + vendor = VENDOR_INTEL; + else if (strstr(vstr, "Mesa")) + vendor = VENDOR_MESA_SOFT; + else if (strstr(vstr, "Apple Computer")) + vendor = VENDOR_APPLE; + else if (strstr(vstr, "Microsoft")) + vendor = VENDOR_MICROSOFT; + else + vendor = VENDOR_UNKNOWN; +} + +void OpenGL::initOpenGLFunctions() +{ // The functionality of the core and ARB VBOs are identical, so we can // assign the pointers of the core functions to the names of the ARB // functions, if the latter isn't supported but the former is. @@ -95,11 +170,34 @@ void initializeContext() glUnmapBufferARB = (GLEEPFNGLUNMAPBUFFERARBPROC) glUnmapBuffer; } - // Set the 'default' texture (id 0) as a repeating white pixel. - // Otherwise, texture2D inside a shader would return black when drawing graphics primitives, - // which would create the need to use different "passthrough" shaders for untextured primitives vs images. + // Same deal for compressed textures. + if (GLEE_VERSION_1_3 && !GLEE_ARB_texture_compression) + { + glCompressedTexImage2DARB = (GLEEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC) glCompressedTexImage2D; + glCompressedTexSubImage2DARB = (GLEEPFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) glCompressedTexSubImage2D; + glGetCompressedTexImageARB = (GLEEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC) glGetCompressedTexImage; + } +} - GLuint curtexture = textureUnits[curTextureUnit]; +void OpenGL::initMaxValues() +{ + // We'll need this value to clamp anisotropy. + if (GLEE_EXT_texture_filter_anisotropic) + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); + else + maxAnisotropy = 1.0f; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); +} + +void OpenGL::createDefaultTexture() +{ + // Set the 'default' texture (id 0) as a repeating white pixel. Otherwise, + // texture2D calls inside a shader would return black when drawing graphics + // primitives, which would create the need to use different "passthrough" + // shaders for untextured primitives vs images. + + GLuint curtexture = state.textureUnits[state.curTextureUnit]; bindTexture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -108,65 +206,126 @@ void initializeContext() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - GLubyte pixel = 255; - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel); + GLubyte pix = 255; + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pix); bindTexture(curtexture); } -void uninitializeContext() +void OpenGL::prepareDraw() { - contextInitialized = false; + // Make sure the active shader has the correct values for the built-in + // screen params uniform. + if (Shader::current) + Shader::current->checkSetScreenParams(); } -void setActiveTextureUnit(int textureunit) +void OpenGL::setColor(const Color &c) { - if (textureunit < 0 || (size_t) textureunit >= textureUnits.size()) - throw love::Exception("Invalid texture unit index (%d).", textureunit); + glColor4ubv(&c.r); + state.color = c; +} - if (textureunit != curTextureUnit) +Color OpenGL::getColor() const +{ + return state.color; +} + +void OpenGL::setClearColor(const Color &c) +{ + glClearColor(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f); + state.clearColor = c; +} + +Color OpenGL::getClearColor() const +{ + return state.clearColor; +} + +void OpenGL::setViewport(const OpenGL::Viewport &v) +{ + glViewport(v.x, v.y, v.w, v.h); + state.viewport = v; + + // glScissor starts from the lower left, so we compensate when setting the + // scissor. When the viewport is changed, we need to manually update the + // scissor again. + setScissor(state.scissor); +} + +OpenGL::Viewport OpenGL::getViewport() const +{ + return state.viewport; +} + +void OpenGL::setScissor(const OpenGL::Viewport &v) +{ + if (Canvas::current) + glScissor(v.x, v.y, v.w, v.h); + else { - if (textureUnits.size() > 1) - glActiveTexture(GL_TEXTURE0 + textureunit); - else - throw love::Exception("Multitexturing not supported."); + // With no Canvas active, we need to compensate for glScissor starting + // from the lower left of the viewport instead of the top left. + glScissor(v.x, state.viewport.h - (v.y + v.h), v.w, v.h); } - curTextureUnit = textureunit; + state.scissor = v; } -void bindTexture(GLuint texture) +OpenGL::Viewport OpenGL::getScissor() const { - if (texture != textureUnits[curTextureUnit]) + return state.scissor; +} + +void OpenGL::setTextureUnit(int textureunit) +{ + if (textureunit < 0 || (size_t) textureunit >= state.textureUnits.size()) + throw love::Exception("Invalid texture unit index (%d).", textureunit); + + if (textureunit != state.curTextureUnit) { - textureUnits[curTextureUnit] = texture; + if (state.textureUnits.size() > 1) + glActiveTexture(GL_TEXTURE0 + textureunit); + else + throw love::Exception("Multitexturing is not supported."); + } + + state.curTextureUnit = textureunit; +} + +void OpenGL::bindTexture(GLuint texture) +{ + if (texture != state.textureUnits[state.curTextureUnit]) + { + state.textureUnits[state.curTextureUnit] = texture; glBindTexture(GL_TEXTURE_2D, texture); } } -void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev) +void OpenGL::bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev) { - if (textureunit < 0 || (size_t) textureunit >= textureUnits.size()) + if (textureunit < 0 || (size_t) textureunit >= state.textureUnits.size()) throw love::Exception("Invalid texture unit index."); - if (texture != textureUnits[textureunit]) + if (texture != state.textureUnits[textureunit]) { - int oldtextureunit = curTextureUnit; - setActiveTextureUnit(textureunit); + int oldtextureunit = state.curTextureUnit; + setTextureUnit(textureunit); - textureUnits[textureunit] = texture; + state.textureUnits[textureunit] = texture; glBindTexture(GL_TEXTURE_2D, texture); if (restoreprev) - setActiveTextureUnit(oldtextureunit); + setTextureUnit(oldtextureunit); } } -void deleteTexture(GLuint texture) +void OpenGL::deleteTexture(GLuint texture) { - // glDeleteTextures binds texture 0 to all texture units the deleted texture was bound to + // glDeleteTextures binds texture 0 to all texture units the deleted texture + // was bound to before deletion. std::vector::iterator it; - for (it = textureUnits.begin(); it != textureUnits.end(); ++it) + for (it = state.textureUnits.begin(); it != state.textureUnits.end(); ++it) { if (*it == texture) *it = 0; @@ -175,26 +334,26 @@ void deleteTexture(GLuint texture) glDeleteTextures(1, &texture); } -void setTextureFilter(const graphics::Image::Filter &f) +float OpenGL::setTextureFilter(graphics::Texture::Filter &f) { GLint gmin, gmag; - if (f.mipmap == Image::FILTER_NONE) + if (f.mipmap == Texture::FILTER_NONE) { - if (f.min == Image::FILTER_NEAREST) + if (f.min == Texture::FILTER_NEAREST) gmin = GL_NEAREST; - else // f.min == Image::FILTER_LINEAR + else // f.min == Texture::FILTER_LINEAR gmin = GL_LINEAR; } else { - if (f.min == Image::FILTER_NEAREST && f.mipmap == Image::FILTER_NEAREST) + if (f.min == Texture::FILTER_NEAREST && f.mipmap == Texture::FILTER_NEAREST) gmin = GL_NEAREST_MIPMAP_NEAREST; - else if (f.min == Image::FILTER_NEAREST && f.mipmap == Image::FILTER_LINEAR) + else if (f.min == Texture::FILTER_NEAREST && f.mipmap == Texture::FILTER_LINEAR) gmin = GL_NEAREST_MIPMAP_LINEAR; - else if (f.min == Image::FILTER_LINEAR && f.mipmap == Image::FILTER_NEAREST) + else if (f.min == Texture::FILTER_LINEAR && f.mipmap == Texture::FILTER_NEAREST) gmin = GL_LINEAR_MIPMAP_NEAREST; - else if (f.min == Image::FILTER_LINEAR && f.mipmap == Image::FILTER_LINEAR) + else if (f.min == Texture::FILTER_LINEAR && f.mipmap == Texture::FILTER_LINEAR) gmin = GL_LINEAR_MIPMAP_LINEAR; else gmin = GL_LINEAR; @@ -203,10 +362,10 @@ void setTextureFilter(const graphics::Image::Filter &f) switch (f.mag) { - case Image::FILTER_NEAREST: + case Texture::FILTER_NEAREST: gmag = GL_NEAREST; break; - case Image::FILTER_LINEAR: + case Texture::FILTER_LINEAR: default: gmag = GL_LINEAR; break; @@ -214,67 +373,78 @@ void setTextureFilter(const graphics::Image::Filter &f) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gmin); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gmag); + + if (GLEE_EXT_texture_filter_anisotropic) + { + f.anisotropy = std::min(std::max(f.anisotropy, 1.0f), maxAnisotropy); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, f.anisotropy); + } + + return f.anisotropy; } -graphics::Image::Filter getTextureFilter() +graphics::Texture::Filter OpenGL::getTextureFilter() { GLint gmin, gmag; glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &gmin); glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &gmag); - Image::Filter f; + Texture::Filter f; switch (gmin) { case GL_NEAREST: - f.min = Image::FILTER_NEAREST; - f.mipmap = Image::FILTER_NONE; + f.min = Texture::FILTER_NEAREST; + f.mipmap = Texture::FILTER_NONE; break; case GL_NEAREST_MIPMAP_NEAREST: - f.min = f.mipmap = Image::FILTER_NEAREST; + f.min = f.mipmap = Texture::FILTER_NEAREST; break; case GL_NEAREST_MIPMAP_LINEAR: - f.min = Image::FILTER_NEAREST; - f.mipmap = Image::FILTER_LINEAR; + f.min = Texture::FILTER_NEAREST; + f.mipmap = Texture::FILTER_LINEAR; break; case GL_LINEAR_MIPMAP_NEAREST: - f.min = Image::FILTER_LINEAR; - f.mipmap = Image::FILTER_NEAREST; + f.min = Texture::FILTER_LINEAR; + f.mipmap = Texture::FILTER_NEAREST; break; case GL_LINEAR_MIPMAP_LINEAR: - f.min = f.mipmap = Image::FILTER_LINEAR; + f.min = f.mipmap = Texture::FILTER_LINEAR; break; case GL_LINEAR: default: - f.min = Image::FILTER_LINEAR; - f.mipmap = Image::FILTER_NONE; + f.min = Texture::FILTER_LINEAR; + f.mipmap = Texture::FILTER_NONE; break; } switch (gmag) { case GL_NEAREST: - f.mag = Image::FILTER_NEAREST; + f.mag = Texture::FILTER_NEAREST; break; case GL_LINEAR: default: - f.mag = Image::FILTER_LINEAR; + f.mag = Texture::FILTER_LINEAR; break; } + if (GLEE_EXT_texture_filter_anisotropic) + glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &f.anisotropy); + return f; } -void setTextureWrap(const graphics::Image::Wrap &w) +void OpenGL::setTextureWrap(const graphics::Texture::Wrap &w) { GLint gs, gt; switch (w.s) { - case Image::WRAP_CLAMP: + case Texture::WRAP_CLAMP: gs = GL_CLAMP_TO_EDGE; break; - case Image::WRAP_REPEAT: + case Texture::WRAP_REPEAT: default: gs = GL_REPEAT; break; @@ -282,10 +452,10 @@ void setTextureWrap(const graphics::Image::Wrap &w) switch (w.t) { - case Image::WRAP_CLAMP: + case Texture::WRAP_CLAMP: gt = GL_CLAMP_TO_EDGE; break; - case Image::WRAP_REPEAT: + case Texture::WRAP_REPEAT: default: gt = GL_REPEAT; break; @@ -295,40 +465,53 @@ void setTextureWrap(const graphics::Image::Wrap &w) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gt); } -graphics::Image::Wrap getTextureWrap() +graphics::Texture::Wrap OpenGL::getTextureWrap() { GLint gs, gt; glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &gs); glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, >); - Image::Wrap w; + Texture::Wrap w; switch (gs) { case GL_CLAMP_TO_EDGE: - w.s = Image::WRAP_CLAMP; + w.s = Texture::WRAP_CLAMP; break; case GL_REPEAT: default: - w.s = Image::WRAP_REPEAT; + w.s = Texture::WRAP_REPEAT; break; } switch (gt) { case GL_CLAMP_TO_EDGE: - w.t = Image::WRAP_CLAMP; + w.t = Texture::WRAP_CLAMP; break; case GL_REPEAT: default: - w.t = Image::WRAP_REPEAT; + w.t = Texture::WRAP_REPEAT; break; } return w; } +int OpenGL::getMaxTextureSize() const +{ + return maxTextureSize; +} + +OpenGL::Vendor OpenGL::getVendor() const +{ + return vendor; +} + +// OpenGL class instance singleton. +OpenGL gl; + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index bc469da71..29bdcf835 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,7 +22,16 @@ #define LOVE_GRAPHICS_OPENGL_OPENGL_H #include "GLee.h" -#include "graphics/Image.h" + +// LOVE +#include "graphics/Color.h" +#include "graphics/Texture.h" + +// C++ +#include + +// The last argument to AttribPointer takes a buffer offset casted to a pointer. +#define BUFFER_OFFSET(i) ((char *) NULL + (i)) namespace love { @@ -32,65 +41,204 @@ namespace opengl { /** - * Initializes some required context state, - * based on current and default OpenGL state. + * Thin layer between OpenGL and the rest of the program. + * Internally shadows some OpenGL context state for improved efficiency and + * accuracy (compared to glGet etc.) + * A class is more convenient and readable than plain namespaced functions, but + * typically only one OpenGL object should be used (singleton.) **/ -void initializeContext(); +class OpenGL +{ +public: -/** - * Marks current context state as invalid. - **/ -void uninitializeContext(); + // OpenGL GPU vendors. + enum Vendor + { + VENDOR_ATI_AMD, + VENDOR_NVIDIA, + VENDOR_INTEL, + VENDOR_MESA_SOFT, // Software renderer. + VENDOR_APPLE, // Software renderer. + VENDOR_MICROSOFT, // Software renderer. + VENDOR_UNKNOWN + }; -/** - * Helper for setting the active texture unit. - * - * @param textureunit Index in the range of [0, maxtextureunits-1] - **/ -void setActiveTextureUnit(int textureunit); + // A rectangle representing an OpenGL viewport or a scissor box. + struct Viewport + { + int x, y; + int w, h; -/** - * Helper for binding an OpenGL texture. - * Makes sure we aren't redundantly binding textures. - **/ -void bindTexture(GLuint texture); + Viewport() + : x(0), y(0), w(0), h(0) + {} -/** - * Helper for binding a texture to a specific texture unit. - * - * @param textureunit Index in the range of [0, maxtextureunits-1] - * @param resoreprev Restore previously bound texture unit when done. - **/ -void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev); + Viewport(int _x, int _y, int _w, int _h) + : x(_x), y(_y), w(_w), h(_h) + {} + }; -/** - * Helper for deleting an OpenGL texture. - * Cleans up if the texture is currently bound. - **/ -void deleteTexture(GLuint texture); + OpenGL(); -/** - * Sets the image filter mode for the currently bound texture. - */ -void setTextureFilter(const graphics::Image::Filter &f); + /** + * Initializes some required context state based on current and default + * OpenGL state. Call this directly after creating an OpenGL context! + **/ + void initContext(); -/** - * Returns the image filter mode for the currently bound texture. - */ -graphics::Image::Filter getTextureFilter(); + /** + * Marks current context state as invalid and deletes OpenGL objects owned + * by this class instance. Call this directly before potentially deleting + * an OpenGL context! + **/ + void deInitContext(); -/** - * Sets the image wrap mode for the currently bound texture. - */ -void setTextureWrap(const graphics::Image::Wrap &w); + /** + * Set up necessary state (LOVE-provided shader uniforms, etc.) for drawing. + * This *MUST* be called directly before OpenGL drawing functions. + **/ + void prepareDraw(); -/** - * Returns the image wrap mode for the currently bound texture. - */ -graphics::Image::Wrap getTextureWrap(); + /** + * Sets the current constant color. + **/ + void setColor(const Color &c); + + /** + * Gets the current constant color. + **/ + Color getColor() const; + + /** + * Sets the current clear color for all framebuffer objects. + **/ + void setClearColor(const Color &c); + + /** + * Gets the current clear color. + **/ + Color getClearColor() const; + + /** + * Sets the OpenGL rendering viewport to the specified rectangle. + * The y-coordinate starts at the top. + **/ + void setViewport(const Viewport &v); + + /** + * Gets the current OpenGL rendering viewport rectangle. + **/ + Viewport getViewport() const; + + /** + * Sets the scissor box to the specified rectangle. + * The y-coordinate starts at the top and is flipped internally. + **/ + void setScissor(const Viewport &v); + + /** + * Gets the current scissor box (regardless of whether scissoring is enabled.) + **/ + Viewport getScissor() const; + + /** + * Helper for setting the active texture unit. + * + * @param textureunit Index in the range of [0, maxtextureunits-1] + **/ + void setTextureUnit(int textureunit); + + /** + * Helper for binding an OpenGL texture. + * Makes sure we aren't redundantly binding textures. + **/ + void bindTexture(GLuint texture); + + /** + * Helper for binding a texture to a specific texture unit. + * + * @param textureunit Index in the range of [0, maxtextureunits-1] + * @param restoreprev Restore previously bound texture unit when done. + **/ + void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev); + + /** + * Helper for deleting an OpenGL texture. + * Cleans up if the texture is currently bound. + **/ + void deleteTexture(GLuint texture); + + /** + * Sets the texture filter mode for the currently bound texture. + * Returns the actual amount of anisotropic filtering set. + **/ + float setTextureFilter(graphics::Texture::Filter &f); + + /** + * Returns the texture filter mode for the currently bound texture. + **/ + graphics::Texture::Filter getTextureFilter(); + + /** + * Sets the texture wrap mode for the currently bound texture. + **/ + void setTextureWrap(const graphics::Texture::Wrap &w); + + /** + * Returns the texture wrap mode for the currently bound texture. + **/ + graphics::Texture::Wrap getTextureWrap(); + + /** + * Returns the maximum supported width or height of a texture. + **/ + int getMaxTextureSize() const; + + /** + * Get the GPU vendor of this OpenGL context. + **/ + Vendor getVendor() const; + +private: + + void initVendor(); + void initOpenGLFunctions(); + void initMaxValues(); + void createDefaultTexture(); + + bool contextInitialized; + + float maxAnisotropy; + int maxTextureSize; + + Vendor vendor; + + // Tracked OpenGL state. + struct + { + // Current constant color. + Color color; + + Color clearColor; + + // Texture unit state (currently bound texture for each texture unit.) + std::vector textureUnits; + + // Currently active texture unit. + int curTextureUnit; + + Viewport viewport; + Viewport scissor; + + } state; + +}; // OpenGL + +// OpenGL class instance singleton. +extern OpenGL gl; } // opengl } // graphics } // love -#endif +#endif // LOVE_GRAPHICS_OPENGL_OPENGL_H diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp index 7f10ee5ce..dbc26eb2e 100644 --- a/src/modules/graphics/opengl/ParticleSystem.cpp +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,11 +18,16 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +//LOVE +#include "common/config.h" #include "ParticleSystem.h" #include "common/math.h" - +#include "modules/math/RandomGenerator.h" #include "OpenGL.h" + +// STD +#include #include #include @@ -35,36 +40,35 @@ namespace opengl namespace { + +love::math::RandomGenerator rng; + Colorf colorToFloat(const Color &c) { - return Colorf((GLfloat)c.r/255.0f, (GLfloat)c.g/255.0f, (GLfloat)c.b/255.0f, (GLfloat)c.a/255.0f); -} + return Colorf((float)c.r/255.0f, (float)c.g/255.0f, (float)c.b/255.0f, (float)c.a/255.0f); } float calculate_variation(float inner, float outer, float var) { float low = inner - (outer/2.0f)*var; float high = inner + (outer/2.0f)*var; - float r = random(); + float r = (float) rng.random(); return low*(1-r)+high*r; } -StringMap::Entry ParticleSystem::distributionsEntries[] = { - { "none", ParticleSystem::DISTRIBUTION_NONE }, - { "uniform", ParticleSystem::DISTRIBUTION_UNIFORM }, - { "normal", ParticleSystem::DISTRIBUTION_NORMAL }, -}; +} // anonymous namespace -StringMap ParticleSystem::distributions(ParticleSystem::distributionsEntries, sizeof(ParticleSystem::distributionsEntries)); - - -ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer) - : pStart(0) - , pLast(0) - , pEnd(0) - , particleVerts(0) - , sprite(sprite) +ParticleSystem::ParticleSystem(Texture *texture, uint32 size) + : pMem(nullptr) + , pFree(nullptr) + , pHead(nullptr) + , pTail(nullptr) + , particleVerts(nullptr) + , texture(texture) , active(true) + , insertMode(INSERT_MODE_TOP) + , maxParticles(0) + , activeParticles(0) , emissionRate(0) , emitCounter(0) , areaSpreadDistribution(DISTRIBUTION_NONE) @@ -74,11 +78,10 @@ ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer) , particleLifeMax(0) , direction(0) , spread(0) - , relative(false) , speedMin(0) , speedMax(0) - , gravityMin(0) - , gravityMax(0) + , linearAccelerationMin(0, 0) + , linearAccelerationMax(0, 0) , radialAccelerationMin(0) , radialAccelerationMax(0) , tangentialAccelerationMin(0) @@ -89,143 +92,365 @@ ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer) , spinStart(0) , spinEnd(0) , spinVariation(0) - , offsetX(sprite->getWidth()*0.5f) - , offsetY(sprite->getHeight()*0.5f) + , offsetX(float(texture->getWidth())*0.5f) + , offsetY(float(texture->getHeight())*0.5f) { + if (size == 0 || size > MAX_PARTICLES) + throw love::Exception("Invalid ParticleSystem size."); + sizes.push_back(1.0f); colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); - setBufferSize(buffer); - sprite->retain(); + setBufferSize(size); + texture->retain(); +} + +ParticleSystem::ParticleSystem(const ParticleSystem &p) + : pMem(nullptr) + , pFree(nullptr) + , pHead(nullptr) + , pTail(nullptr) + , particleVerts(nullptr) + , texture(p.texture) + , active(p.active) + , insertMode(p.insertMode) + , maxParticles(p.maxParticles) + , activeParticles(0) + , emissionRate(p.emissionRate) + , emitCounter(0.0f) + , position(p.position) + , areaSpreadDistribution(p.areaSpreadDistribution) + , areaSpread(p.areaSpread) + , lifetime(p.lifetime) + , life(p.lifetime) // Initialize with the maximum life time. + , particleLifeMin(p.particleLifeMin) + , particleLifeMax(p.particleLifeMax) + , direction(p.direction) + , spread(p.spread) + , speedMin(p.speedMin) + , speedMax(p.speedMax) + , linearAccelerationMin(p.linearAccelerationMin) + , linearAccelerationMax(p.linearAccelerationMax) + , radialAccelerationMin(p.radialAccelerationMin) + , radialAccelerationMax(p.radialAccelerationMax) + , tangentialAccelerationMin(p.tangentialAccelerationMin) + , tangentialAccelerationMax(p.tangentialAccelerationMax) + , sizes(p.sizes) + , sizeVariation(p.sizeVariation) + , rotationMin(p.rotationMin) + , rotationMax(p.rotationMax) + , spinStart(p.spinStart) + , spinEnd(p.spinEnd) + , spinVariation(p.spinVariation) + , offsetX(p.offsetX) + , offsetY(p.offsetY) + , colors(p.colors) +{ + setBufferSize(maxParticles); + + if (texture != nullptr) + texture->retain(); } ParticleSystem::~ParticleSystem() { - if (this->sprite != 0) - this->sprite->release(); + if (texture != nullptr) + texture->release(); - if (pStart != 0) - delete [] pStart; - - if (particleVerts != 0) - delete [] particleVerts; + deleteBuffers(); } -void ParticleSystem::add() +ParticleSystem *ParticleSystem::clone() { - if (isFull()) return; + return new ParticleSystem(*this); +} +void ParticleSystem::createBuffers(size_t size) +{ + try + { + pFree = pMem = new particle[size]; + particleVerts = new love::Vertex[size * 4]; + maxParticles = (uint32) size; + } + catch (std::bad_alloc &) + { + deleteBuffers(); + throw love::Exception("Out of memory"); + } +} + +void ParticleSystem::deleteBuffers() +{ + // Clean up for great gracefulness! + delete[] pMem; + delete[] particleVerts; + + pMem = nullptr; + particleVerts = nullptr; + maxParticles = 0; + activeParticles = 0; +} + +void ParticleSystem::setBufferSize(uint32 size) +{ + if (size == 0 || size > MAX_PARTICLES) + throw love::Exception("Invalid buffer size"); + deleteBuffers(); + createBuffers(size); + reset(); +} + +uint32 ParticleSystem::getBufferSize() const +{ + return maxParticles; +} + +void ParticleSystem::addParticle() +{ + if (isFull()) + return; + + // Gets a free particle and updates the allocation pointer. + particle *p = pFree++; + initParticle(p); + + switch (insertMode) + { + default: + case INSERT_MODE_TOP: + insertTop(p); + break; + case INSERT_MODE_BOTTOM: + insertBottom(p); + break; + case INSERT_MODE_RANDOM: + insertRandom(p); + break; + } + + activeParticles++; +} + +void ParticleSystem::initParticle(particle *p) +{ float min,max; min = particleLifeMin; max = particleLifeMax; if (min == max) - pLast->life = min; + p->life = min; else - pLast->life = random(min, max); - pLast->lifetime = pLast->life; + p->life = (float) rng.random(min, max); + p->lifetime = p->life; - pLast->position[0] = position.getX(); - pLast->position[1] = position.getY(); + p->position[0] = position.getX(); + p->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; + case DISTRIBUTION_UNIFORM: + p->position[0] += (float) rng.random(-areaSpread.getX(), areaSpread.getX()); + p->position[1] += (float) rng.random(-areaSpread.getY(), areaSpread.getY()); + break; + case DISTRIBUTION_NORMAL: + p->position[0] += (float) rng.randomNormal(areaSpread.getX()); + p->position[1] += (float) rng.randomNormal(areaSpread.getY()); + break; + case DISTRIBUTION_NONE: + default: + break; } min = direction - spread/2.0f; max = direction + spread/2.0f; - pLast->direction = random(min, max); + p->direction = (float) rng.random(min, max); - pLast->origin = position; + p->origin = position; min = speedMin; max = speedMax; - float speed = random(min, max); - pLast->speed = love::Vector(cos(pLast->direction), sin(pLast->direction)); - pLast->speed *= speed; + float speed = (float) rng.random(min, max); + p->speed = love::Vector(cosf(p->direction), sinf(p->direction)); + p->speed *= speed; - min = gravityMin; - max = gravityMax; - pLast->gravity = random(min, max); + p->linearAcceleration.x = (float) rng.random(linearAccelerationMin.x, linearAccelerationMax.x); + p->linearAcceleration.y = (float) rng.random(linearAccelerationMin.y, linearAccelerationMax.y); min = radialAccelerationMin; max = radialAccelerationMax; - pLast->radialAcceleration = random(min, max); + p->radialAcceleration = (float) rng.random(min, max); min = tangentialAccelerationMin; max = tangentialAccelerationMax; - pLast->tangentialAcceleration = random(min, max); + p->tangentialAcceleration = (float) rng.random(min, max); - pLast->sizeOffset = random(sizeVariation); // time offset for size change - pLast->sizeIntervalSize = (1.0f - random(sizeVariation)) - pLast->sizeOffset; - pLast->size = sizes[(size_t)(pLast->sizeOffset - .5f) * (sizes.size() - 1)]; + p->sizeOffset = (float) rng.random(sizeVariation); // time offset for size change + p->sizeIntervalSize = (1.0f - (float) rng.random(sizeVariation)) - p->sizeOffset; + p->size = sizes[(size_t)(p->sizeOffset - .5f) * (sizes.size() - 1)]; min = rotationMin; max = rotationMax; - pLast->spinStart = calculate_variation(spinStart, spinEnd, spinVariation); - pLast->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation); - pLast->rotation = random(min, max); + p->spinStart = calculate_variation(spinStart, spinEnd, spinVariation); + p->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation); + p->rotation = (float) rng.random(min, max); - pLast->color = colors[0]; - - pLast++; + p->color = colors[0]; } -void ParticleSystem::remove(particle *p) +void ParticleSystem::insertTop(particle *p) { - if (!isEmpty()) + if (pHead == nullptr) { - *p = *(--pLast); + pHead = p; + p->prev = nullptr; } + else + { + pTail->next = p; + p->prev = pTail; + } + p->next = nullptr; + pTail = p; } -void ParticleSystem::setSprite(Image *image) +void ParticleSystem::insertBottom(particle *p) { - if (sprite != 0) - sprite->release(); - - sprite = image; - sprite->retain(); + if (pTail == nullptr) + { + pTail = p; + p->next = nullptr; + } + else + { + pHead->prev = p; + p->next = pHead; + } + p->prev = nullptr; + pHead = p; } -void ParticleSystem::setBufferSize(unsigned int size) +void ParticleSystem::insertRandom(particle *p) { - // delete previous data - if (pStart != 0) - delete [] pStart; + // Nonuniform, but 64-bit is so large nobody will notice. Hopefully. + uint64 pos = rng.rand() % ((int64) activeParticles + 1); - pLast = pStart = new particle[size]; + // Special case where the particle gets inserted before the head. + if (pos == activeParticles) + { + particle *pA = pHead; + if (pA) + pA->prev = p; + p->prev = nullptr; + p->next = pA; + pHead = p; + return; + } - pEnd = pStart + size; + // Inserts the particle after the randomly selected particle. + particle *pA = pMem + pos; + particle *pB = pA->next; + pA->next = p; + if (pB) + pB->prev = p; + else + pTail = p; + p->prev = pA; + p->next = pB; +} - if (particleVerts != 0) - delete [] particleVerts; +ParticleSystem::particle *ParticleSystem::removeParticle(particle *p) +{ + // The linked list is updated in this function and old pointers may be + // invalidated. The returned pointer will inform the caller of the new + // pointer to the next particle. + particle *pNext = nullptr; - // each particle has 4 vertices - particleVerts = new vertex[size*4]; + // Removes the particle from the linked list. + if (p->prev) + p->prev->next = p->next; + else + pHead = p->next; + + if (p->next) + { + p->next->prev = p->prev; + pNext = p->next; + } + else + pTail = p->prev; + + // The (in memory) last particle can now be moved into the free slot. + // It will skip the moving if it happens to be the removed particle. + pFree--; + if (p != pFree) + { + *p = *pFree; + if (pNext == pFree) + pNext = p; + + if (p->prev) + p->prev->next = p; + else + pHead = p; + + if (p->next) + p->next->prev = p; + else + pTail = p; + } + + activeParticles--; + return pNext; +} + +void ParticleSystem::setTexture(Texture *texture) +{ + Object::AutoRelease imagerelease(this->texture); + + this->texture = texture; + + if (texture) + texture->retain(); +} + +Texture *ParticleSystem::getTexture() const +{ + return texture; +} + +void ParticleSystem::setInsertMode(InsertMode mode) +{ + insertMode = mode; +} + +ParticleSystem::InsertMode ParticleSystem::getInsertMode() const +{ + return insertMode; } void ParticleSystem::setEmissionRate(int rate) { + if (rate < 0) + throw love::Exception("Invalid emission rate"); emissionRate = rate; } -void ParticleSystem::setLifetime(float life) +int ParticleSystem::getEmissionRate() const +{ + return emissionRate; +} + +void ParticleSystem::setEmitterLifetime(float life) { this->life = lifetime = life; } -void ParticleSystem::setParticleLife(float min, float max) +float ParticleSystem::getEmitterLifetime() const +{ + return lifetime; +} + +void ParticleSystem::setParticleLifetime(float min, float max) { particleLifeMin = min; if (max == 0) @@ -234,11 +459,23 @@ void ParticleSystem::setParticleLife(float min, float max) particleLifeMax = max; } +void ParticleSystem::getParticleLifetime(float *min, float *max) const +{ + if (min) + *min = particleLifeMin; + if (max) + *max = particleLifeMax; +} + void ParticleSystem::setPosition(float x, float y) { position = love::Vector(x, y); } +const love::Vector &ParticleSystem::getPosition() const +{ + return position; +} void ParticleSystem::setAreaSpread(AreaSpreadDistribution distribution, float x, float y) { @@ -246,19 +483,34 @@ void ParticleSystem::setAreaSpread(AreaSpreadDistribution distribution, float x, areaSpreadDistribution = distribution; } +ParticleSystem::AreaSpreadDistribution ParticleSystem::getAreaSpreadDistribution() const +{ + return areaSpreadDistribution; +} + +const love::Vector &ParticleSystem::getAreaSpreadParameters() const +{ + return areaSpread; +} + void ParticleSystem::setDirection(float direction) { this->direction = direction; } +float ParticleSystem::getDirection() const +{ + return direction; +} + void ParticleSystem::setSpread(float spread) { this->spread = spread; } -void ParticleSystem::setRelativeDirection(bool relative) +float ParticleSystem::getSpread() const { - this->relative = relative; + return spread; } void ParticleSystem::setSpeed(float speed) @@ -272,15 +524,32 @@ void ParticleSystem::setSpeed(float min, float max) speedMax = max; } -void ParticleSystem::setGravity(float gravity) +void ParticleSystem::getSpeed(float *min, float *max) const { - gravityMin = gravityMax = gravity; + if (min) + *min = speedMin; + if (max) + *max = speedMax; } -void ParticleSystem::setGravity(float min, float max) +void ParticleSystem::setLinearAcceleration(float x, float y) { - gravityMin = min; - gravityMax = max; + linearAccelerationMin.x = linearAccelerationMax.x = x; + linearAccelerationMin.y = linearAccelerationMax.y = y; +} + +void ParticleSystem::setLinearAcceleration(float xmin, float ymin, float xmax, float ymax) +{ + linearAccelerationMin = love::Vector(xmin, ymin); + linearAccelerationMax = love::Vector(xmax, ymax); +} + +void ParticleSystem::getLinearAcceleration(love::Vector *min, love::Vector *max) const +{ + if (min) + *min = linearAccelerationMin; + if (max) + *max = linearAccelerationMax; } void ParticleSystem::setRadialAcceleration(float acceleration) @@ -294,6 +563,14 @@ void ParticleSystem::setRadialAcceleration(float min, float max) radialAccelerationMax = max; } +void ParticleSystem::getRadialAcceleration(float *min, float *max) const +{ + if (min) + *min = radialAccelerationMin; + if (max) + *max = radialAccelerationMax; +} + void ParticleSystem::setTangentialAcceleration(float acceleration) { tangentialAccelerationMin = tangentialAccelerationMax = acceleration; @@ -305,16 +582,28 @@ void ParticleSystem::setTangentialAcceleration(float min, float max) tangentialAccelerationMax = max; } +void ParticleSystem::getTangentialAcceleration(float *min, float *max) const +{ + if (min) + *min = tangentialAccelerationMin; + if (max) + *max = tangentialAccelerationMax; +} + void ParticleSystem::setSize(float size) { sizes.resize(1); sizes[0] = size; } -void ParticleSystem::setSize(const std::vector &newSizes, float variation) +void ParticleSystem::setSizes(const std::vector &newSizes) { sizes = newSizes; - sizeVariation = variation; +} + +const std::vector &ParticleSystem::getSizes() const +{ + return sizes; } void ParticleSystem::setSizeVariation(float variation) @@ -322,6 +611,11 @@ void ParticleSystem::setSizeVariation(float variation) sizeVariation = variation; } +float ParticleSystem::getSizeVariation() const +{ + return sizeVariation; +} + void ParticleSystem::setRotation(float rotation) { rotationMin = rotationMax = rotation; @@ -333,6 +627,14 @@ void ParticleSystem::setRotation(float min, float max) rotationMax = max; } +void ParticleSystem::getRotation(float *min, float *max) const +{ + if (min) + *min = rotationMin; + if (max) + *max = rotationMax; +} + void ParticleSystem::setSpin(float spin) { spinStart = spin; @@ -345,11 +647,12 @@ void ParticleSystem::setSpin(float start, float end) spinEnd = end; } -void ParticleSystem::setSpin(float start, float end, float variation) +void ParticleSystem::getSpin(float *start, float *end) const { - spinStart = start; - spinEnd = end; - spinVariation = variation; + if (start) + *start = spinStart; + if (end) + *end = spinEnd; } void ParticleSystem::setSpinVariation(float variation) @@ -357,6 +660,22 @@ void ParticleSystem::setSpinVariation(float variation) spinVariation = variation; } +float ParticleSystem::getSpinVariation() const +{ + return spinVariation; +} + +void ParticleSystem::setOffset(float x, float y) +{ + offsetX = x; + offsetY = y; +} + +love::Vector ParticleSystem::getOffset() const +{ + return love::Vector(offsetX, offsetY); +} + void ParticleSystem::setColor(const Color &color) { colors.resize(1); @@ -370,60 +689,25 @@ void ParticleSystem::setColor(const std::vector &newColors) colors[i] = colorToFloat(newColors[i]); } -void ParticleSystem::setOffset(float x, float y) +std::vector ParticleSystem::getColor() const { - offsetX = x; - offsetY = y; + // The particle system stores colors as floats... + std::vector ncolors(colors.size()); + + for (size_t i = 0; i < colors.size(); ++i) + { + ncolors[i].r = (unsigned char) (colors[i].r * 255); + ncolors[i].g = (unsigned char) (colors[i].g * 255); + ncolors[i].b = (unsigned char) (colors[i].b * 255); + ncolors[i].a = (unsigned char) (colors[i].a * 255); + } + + return ncolors; } -float ParticleSystem::getX() const +uint32 ParticleSystem::getCount() const { - return position.getX(); -} - -float ParticleSystem::getY() const -{ - return position.getY(); -} - -const love::Vector &ParticleSystem::getPosition() const -{ - return position; -} - -ParticleSystem::AreaSpreadDistribution ParticleSystem::getAreaSpreadDistribution() const -{ - return areaSpreadDistribution; -} - -const love::Vector &ParticleSystem::getAreaSpreadParameters() const -{ - return areaSpread; -} - -float ParticleSystem::getDirection() const -{ - return direction; -} - -float ParticleSystem::getSpread() const -{ - return spread; -} - -float ParticleSystem::getOffsetX() const -{ - return offsetX; -} - -float ParticleSystem::getOffsetY() const -{ - return offsetY; -} - -int ParticleSystem::count() const -{ - return (int)(pLast - pStart); + return activeParticles; } void ParticleSystem::start() @@ -445,91 +729,123 @@ void ParticleSystem::pause() void ParticleSystem::reset() { - pLast = pStart; + if (pMem == nullptr) + return; + + pFree = pMem; + pHead = nullptr; + pTail = nullptr; + activeParticles = 0; life = lifetime; emitCounter = 0; } +void ParticleSystem::emit(uint32 num) +{ + if (!active) + return; + + num = std::min(num, maxParticles - activeParticles); + + while(num--) + addParticle(); +} + bool ParticleSystem::isActive() const { return active; } +bool ParticleSystem::isPaused() const +{ + return !active && life < lifetime; +} + +bool ParticleSystem::isStopped() const +{ + return !active && life >= lifetime; +} + bool ParticleSystem::isEmpty() const { - return pStart == pLast; + return activeParticles == 0; } bool ParticleSystem::isFull() const { - return pLast == pEnd; + return activeParticles == maxParticles; } void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { - if (sprite == 0) return; // just in case of failure + uint32 pCount = getCount(); + if (pCount == 0 || texture == nullptr || pMem == nullptr || particleVerts == nullptr) + return; - int numParticles = count(); - if (numParticles == 0) return; // don't bother if there's nothing to do + Color curcolor = gl.getColor(); glPushMatrix(); - glPushAttrib(GL_CURRENT_BIT); static Matrix t; t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); glMultMatrixf((const GLfloat *)t.getElements()); - const vertex * imageVerts = sprite->getVertices(); + const Vertex *textureVerts = texture->getVertices(); + Vertex *pVerts = particleVerts; + particle *p = pHead; // set the vertex data for each particle (transformation, texcoords, color) - for (int i = 0; i < numParticles; i++) + while (p) { - particle * p = pStart + i; - - // particle vertices are sprite vertices transformed by particle information + // particle vertices are image vertices transformed by particle information t.setTransformation(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f); - t.transform(&particleVerts[i*4], &imageVerts[0], 4); + t.transform(pVerts, textureVerts, 4); // set the texture coordinate and color data for particle vertices for (int v = 0; v < 4; v++) { - int vi = (i * 4) + v; // current vertex index for particle - - particleVerts[vi].s = imageVerts[v].s; - particleVerts[vi].t = imageVerts[v].t; + pVerts[v].s = textureVerts[v].s; + pVerts[v].t = textureVerts[v].t; // particle colors are stored as floats (0-1) but vertex colors are stored as unsigned bytes (0-255) - particleVerts[vi].r = p->color.r*255; - particleVerts[vi].g = p->color.g*255; - particleVerts[vi].b = p->color.b*255; - particleVerts[vi].a = p->color.a*255; + pVerts[v].r = (unsigned char) (p->color.r*255); + pVerts[v].g = (unsigned char) (p->color.g*255); + pVerts[v].b = (unsigned char) (p->color.b*255); + pVerts[v].a = (unsigned char) (p->color.a*255); } + + pVerts += 4; + p = p->next; } - sprite->bind(); + texture->predraw(); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&particleVerts[0].r); - glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&particleVerts[0].x); - glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&particleVerts[0].s); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid *) &particleVerts[0].r); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &particleVerts[0].x); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *) &particleVerts[0].s); - glDrawArrays(GL_QUADS, 0, numParticles*4); + gl.prepareDraw(); + glDrawArrays(GL_QUADS, 0, pCount * 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); - glPopAttrib(); + texture->postdraw(); + glPopMatrix(); + + gl.setColor(curcolor); } void ParticleSystem::update(float dt) { - // Traverse all particles and update. - particle *p = pStart; + if (pMem == nullptr || dt == 0.0f) + return; // Make some more particles. if (active) @@ -538,7 +854,7 @@ void ParticleSystem::update(float dt) emitCounter += dt; while (emitCounter > rate) { - add(); + addParticle(); emitCounter -= rate; } /*int particles = (int)(emissionRate * dt); @@ -550,16 +866,20 @@ void ParticleSystem::update(float dt) stop(); } - while (p != pLast) + // Traverse all particles and update. + particle *p = pHead; + + while (p) { // Decrease lifespan. p->life -= dt; - if (p->life > 0) + if (p->life <= 0) + p = removeParticle(p); + else { - // Temp variables. - love::Vector radial, tangential, gravity(0, p->gravity); + love::Vector radial, tangential; love::Vector ppos(p->position[0], p->position[1]); // Get vector from particle center to particle. @@ -581,7 +901,7 @@ void ParticleSystem::update(float dt) tangential *= p->tangentialAcceleration; // Update position. - p->speed += (radial+tangential+gravity)*dt; + p->speed += (radial+tangential+p->linearAcceleration)*dt; // Modify position. ppos += p->speed * dt; @@ -617,16 +937,9 @@ void ParticleSystem::update(float dt) p->color = colors[i] * (1.0f - s) + colors[k] * s; // Next particle. - p++; + p = p->next; } - else - { - remove(p); - - if (p >= pLast) - return; - } // else - } // while + } } bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out) @@ -639,6 +952,34 @@ bool ParticleSystem::getConstant(AreaSpreadDistribution in, const char *&out) return distributions.find(in, out); } +bool ParticleSystem::getConstant(const char *in, InsertMode &out) +{ + return insertModes.find(in, out); +} + +bool ParticleSystem::getConstant(InsertMode in, const char *&out) +{ + return insertModes.find(in, out); +} + +StringMap::Entry ParticleSystem::distributionsEntries[] = +{ + { "none", ParticleSystem::DISTRIBUTION_NONE }, + { "uniform", ParticleSystem::DISTRIBUTION_UNIFORM }, + { "normal", ParticleSystem::DISTRIBUTION_NORMAL }, +}; + +StringMap ParticleSystem::distributions(ParticleSystem::distributionsEntries, sizeof(ParticleSystem::distributionsEntries)); + +StringMap::Entry ParticleSystem::insertModesEntries[] = +{ + { "top", ParticleSystem::INSERT_MODE_TOP }, + { "bottom", ParticleSystem::INSERT_MODE_BOTTOM }, + { "random", ParticleSystem::INSERT_MODE_RANDOM }, +}; + +StringMap ParticleSystem::insertModes(ParticleSystem::insertModesEntries, sizeof(ParticleSystem::insertModesEntries)); + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/ParticleSystem.h b/src/modules/graphics/opengl/ParticleSystem.h index 36602e737..08f692cb5 100644 --- a/src/modules/graphics/opengl/ParticleSystem.h +++ b/src/modules/graphics/opengl/ParticleSystem.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,12 +22,14 @@ #define LOVE_GRAPHICS_OPENGL_PARTICLE_SYSTEM_H // LOVE - +#include "common/int.h" #include "common/math.h" #include "common/Vector.h" #include "graphics/Drawable.h" #include "graphics/Color.h" -#include "Image.h" +#include "Texture.h" + +// STL #include namespace love @@ -37,34 +39,6 @@ namespace graphics namespace opengl { -// Represents a single particle. -struct particle -{ - float lifetime; - float life; - - float position[2]; - float direction; - - // Particles gravitate towards this point. - love::Vector origin; - - love::Vector speed; - float gravity; - float radialAcceleration; - float tangentialAcceleration; - - float size; - float sizeOffset; - float sizeIntervalSize; - - float rotation; - float spinStart; - float spinEnd; - - Colorf color; -}; - /** * A class for creating, moving and drawing particles. * A big thanks to bobthebloke.org @@ -80,13 +54,32 @@ public: DISTRIBUTION_NONE, DISTRIBUTION_UNIFORM, DISTRIBUTION_NORMAL, - DISTRIBUTION_MAX_ENUM, + DISTRIBUTION_MAX_ENUM }; /** - * Creates a particle system with the specified buffersize and sprite. + * Insertion modes of new particles in the list: top, bottom, random. + */ + enum InsertMode + { + INSERT_MODE_TOP, + INSERT_MODE_BOTTOM, + INSERT_MODE_RANDOM, + INSERT_MODE_MAX_ENUM, + }; + + /** + * Maximum numbers of particles in a ParticleSystem. + * This limit comes from the fact that a quad requires four vertices and the + * OpenGL API where GLsizei is a signed int. **/ - ParticleSystem(Image *sprite, unsigned int buffer); + static const uint32 MAX_PARTICLES = LOVE_INT32_MAX / 4; + + /** + * Creates a particle system with the specified buffer size and texture. + **/ + ParticleSystem(Texture *texture, uint32 buffer); + ParticleSystem(const ParticleSystem &p); /** * Deletes any allocated memory. @@ -94,16 +87,45 @@ public: virtual ~ParticleSystem(); /** - * Sets the sprite used in the particle system. - * @param sprite The new sprite. + * Creates an identical copy of this ParticleSystem. The clone does not + * duplicate any existing particles from this ParticleSystem, just the + * settable parameters. **/ - void setSprite(Image *image); + ParticleSystem *clone(); + + /** + * Sets the texture used in the particle system. + * @param texture The new texture. + **/ + void setTexture(Texture *texture); + + /** + * Returns the texture used when drawing the particle system. + **/ + Texture *getTexture() const; /** * Clears the current buffer and allocates the appropriate amount of space for the buffer. * @param size The new buffer size. **/ - void setBufferSize(unsigned int size); + void setBufferSize(uint32 size); + + /** + * Returns the total amount of particles this ParticleSystem can have active + * at any given point in time. + **/ + uint32 getBufferSize() const; + + /** + * Sets the insert mode for new particles. + * @param mode The new insert mode. + */ + void setInsertMode(InsertMode mode); + + /** + * Returns the current insert mode. + */ + InsertMode getInsertMode() const; /** * Sets the emission rate. @@ -111,27 +133,49 @@ public: **/ void setEmissionRate(int rate); + /** + * Returns the number of particles created per second. + **/ + int getEmissionRate() const; + /** * Sets the lifetime of the particle emitter (-1 means eternal) * @param life The lifetime (in seconds). **/ - void setLifetime(float life); + void setEmitterLifetime(float life); + + /** + * Returns the lifetime of the particle emitter. + **/ + float getEmitterLifetime() const; /** * Sets the life range of the particles. - * @param lifeMin The minimum life. - * @param lifeMax The maximum life (if 0, then becomes the same as minimum life). + * @param min The minimum life. + * @param max The maximum life (if 0, then becomes the same as minimum life). **/ - void setParticleLife(float min, float max = 0); + void setParticleLifetime(float min, float max = 0); /** - * Sets the position of the center of the emitter and the direction (if set to relative). + * Gets the lifetime of a particle. + * @param[out] min The minimum life. + * @param[out] max The maximum life. + **/ + void getParticleLifetime(float *min, float *max) const; + + /** + * Sets the position of the center of the emitter. * Used to move the emitter without changing the position of already existing particles. * @param x The x-coordinate. * @param y The y-coordinate. **/ void setPosition(float x, float y); + /** + * Returns the position of the emitter. + **/ + const love::Vector &getPosition() const; + /** * Sets the emission area spread parameters and distribution type. The interpretation of * the parameters depends on the distribution type: @@ -142,26 +186,40 @@ public: * @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. + * Returns area spread distribution type. + **/ + AreaSpreadDistribution getAreaSpreadDistribution() const; + + /** + * Returns area spread parameters. + **/ + const love::Vector &getAreaSpreadParameters() const; + + /** + * Sets the direction of the particle emitter. * @param direction The direction (in degrees). **/ void setDirection(float direction); + /** + * Returns the direction of the particle emitter (in radians). + **/ + float getDirection() const; + /** * Sets the spread of the particle emitter. - * @param spread The spread (in degrees). + * @param spread The spread (in radians). **/ void setSpread(float spread); /** - * Sets whether the direction should be relative to the particle emitters movement. Used in conjunction with setPosition. - * @param relative Whether to have relative direction. + * Returns the directional spread of the emitter (in radians). **/ - void setRelativeDirection(bool relative); + float getSpread() const; /** * Sets the speed of the particles. @@ -177,17 +235,34 @@ public: void setSpeed(float min, float max); /** - * Sets the gravity of the particles (the acceleration along the y-axis). - * @param gravity The amount of gravity. + * Gets the speed of the particles. + * @param[out] min The minimum speed. + * @param[out] max The maximum speed. **/ - void setGravity(float gravity); + void getSpeed(float *min, float *max) const; /** - * Sets the gravity of the particles (the acceleration along the y-axis). - * @param min The minimum gravity. - * @param max The maximum gravity. + * Sets the linear acceleration (the acceleration along the x and y axes). + * @param x The acceleration along the x-axis. + * @param y The acceleration along the y-axis. **/ - void setGravity(float min, float max); + void setLinearAcceleration(float x, float y); + + /** + * Sets the linear acceleration (the acceleration along the x and y axes). + * @param xmin The minimum amount of acceleration along the x-axis. + * @param ymin The minimum amount of acceleration along the y-axis. + * @param xmax The maximum amount of acceleration along the x-axis. + * @param ymax The maximum amount of acceleration along the y-axis. + **/ + void setLinearAcceleration(float xmin, float ymin, float xmax, float ymax); + + /** + * Gets the linear acceleration of the particles. + * @param[out] min The minimum acceleration. + * @param[out] max The maximum acceleration. + **/ + void getLinearAcceleration(love::Vector *min, love::Vector *max) const; /** * Sets the radial acceleration (the acceleration towards the particle emitter). @@ -202,6 +277,13 @@ public: **/ void setRadialAcceleration(float min, float max); + /** + * Gets the radial acceleration. + * @param[out] min The minimum amount of radial acceleration. + * @param[out] max The maximum amount of radial acceleration. + **/ + void getRadialAcceleration(float *min, float *max) const; + /** * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction). * @param acceleration The amount of acceleration. @@ -215,6 +297,13 @@ public: **/ void setTangentialAcceleration(float min, float max); + /** + * Gets the tangential acceleration. + * @param[out] min The minimum tangential acceleration. + * @param[out] max The maximum tangential acceleration. + **/ + void getTangentialAcceleration(float *min, float *max) const; + /** * Sets the size of the sprite (1.0 being the default size). * @param size The size of the sprite. @@ -222,11 +311,15 @@ public: void setSize(float size); /** - * Sets the size of the sprite upon creation and upon death (1.0 being the default size) and any variation. + * Sets the sizes of the sprite upon creation and upon death (1.0 being the default size). * @param newSizes Array of sizes - * @param variation The amount of variation on the starting size (0 being no variation and 1.0 a random size between start and end). **/ - void setSize(const std::vector &newSizes, float variation = 0.0f); + void setSizes(const std::vector &newSizes); + + /** + * Returns the sizes of the particle sprites. + **/ + const std::vector &getSizes() const; /** * Sets the amount of variation to the sprite's beginning size (0 being no variation and 1.0 a random size between start and end). @@ -234,6 +327,11 @@ public: **/ void setSizeVariation(float variation); + /** + * Returns the amount of initial size variation between particles. + **/ + float getSizeVariation() const; + /** * Sets the amount of rotation a sprite starts out with. * @param rotation The amount of rotation. @@ -247,6 +345,13 @@ public: **/ void setRotation(float min, float max); + /** + * Gets the initial amount of rotation of a particle, in radians. + * @param[out] min The minimum initial rotation. + * @param[out] max The maximum initial rotation. + **/ + void getRotation(float *min, float *max) const; + /** * Sets the spin of the sprite. * @param spin The spin of the sprite (in degrees). @@ -255,30 +360,28 @@ public: /** * Sets the spin of the sprite upon particle creation and death. - * @param start The spin of the sprite upon creation (in degrees). - * @param end The spin of the sprite upon death (in degrees). + * @param start The spin of the sprite upon creation (in radians / second). + * @param end The spin of the sprite upon death (in radians / second). **/ void setSpin(float start, float end); /** - * Sets the spin of the sprite upon particle creation and death and the variation. - * @param start The spin of the sprite upon creation (in degrees). - * @param end The spin of the sprite upon death (in degrees). - * @param variation The variation of the start spin (0 being no variation and 1 beign a random spin between start and end). + * Gets the amount of spin of a particle during its lifetime. + * @param[out] start The initial spin, in radians / s. + * @param[out] end The final spin, in radians / s. **/ - void setSpin(float start, float end, float variation); + void getSpin(float *start, float *end) const; /** - * Sets the variation of the start spin (0 being no variation and 1 beign a random spin between start and end). - * @param variation The variation in degrees. + * Sets the variation of the start spin (0 being no variation and 1 being a random spin between start and end). + * @param variation The variation. **/ void setSpinVariation(float variation); /** - * Sets the color of the particles. - * @param color The color. + * Returns the amount of variation of the start spin of a particle. **/ - void setColor(const Color &color); + float getSpinVariation() const; /** * Sets the particles' offsets for rotation. @@ -287,6 +390,17 @@ public: **/ void setOffset(float x, float y); + /** + * Returns of the particle offset. + **/ + love::Vector getOffset() const; + + /** + * Sets the color of the particles. + * @param color The color. + **/ + void setColor(const Color &color); + /** * Sets the color of the particles. * @param newColors Array of colors @@ -294,54 +408,14 @@ public: void setColor(const std::vector &newColors); /** - * Returns the x-coordinate of the emitter's position. + * Returns the color of the particles. **/ - float getX() const; - - /** - * Returns the y-coordinate of the emitter's position. - **/ - float getY() const; - - /** - * Returns the position of the emitter. - **/ - 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). - **/ - float getDirection() const; - - /** - * Returns the directional spread of the emitter (in degrees). - **/ - float getSpread() const; - - /** - * Returns the X offset of the particles. - **/ - float getOffsetX() const; - - /** - * Returns the Y offset of the particles. - **/ - float getOffsetY() const; + std::vector getColor() const; /** * Returns the amount of particles that are currently active in the system. **/ - int count() const; + uint32 getCount() const; /** * Starts/resumes the particle emitter. @@ -363,11 +437,24 @@ public: **/ void reset(); + /** + * Instantly emits a number of particles. + * @param num The number of particles to emit. + **/ + void emit(uint32 num); + /** * Returns whether the particle emitter is active. **/ bool isActive() const; + /** + * Returns whether the particle emitter is paused. + **/ + bool isPaused() const; + + bool isStopped() const; + /** * Returns whether the particle system is empty of particles or not. **/ @@ -393,29 +480,72 @@ public: static bool getConstant(const char *in, AreaSpreadDistribution &out); static bool getConstant(AreaSpreadDistribution in, const char *&out); + + static bool getConstant(const char *in, InsertMode &out); + static bool getConstant(InsertMode in, const char *&out); + protected: + // Represents a single particle. + struct particle + { + particle *prev; + particle *next; - // The max amount of particles. - unsigned int bufferSize; + float lifetime; + float life; - // Pointer to the first particle. - particle *pStart; + float position[2]; + float direction; - // Pointer to the next available free space. - particle *pLast; + // Particles gravitate towards this point. + love::Vector origin; - // Pointer to the end of the memory allocation. - particle *pEnd; + love::Vector speed; + love::Vector linearAcceleration; + float radialAcceleration; + float tangentialAcceleration; + + float size; + float sizeOffset; + float sizeIntervalSize; + + float rotation; + float spinStart; + float spinEnd; + + Colorf color; + }; + + // Pointer to the beginning of the allocated memory. + particle *pMem; + + // Pointer to a free particle. + particle *pFree; + + // Pointer to the start of the linked list. + particle *pHead; + + // Pointer to the end of the linked list. + particle *pTail; // array of transformed vertex data for all particles, for drawing - vertex * particleVerts; + Vertex *particleVerts; - // The sprite to be drawn. - Image *sprite; + // The texture to be drawn. + Texture *texture; // Whether the particle emitter is active. bool active; + // Insert mode of new particles. + InsertMode insertMode; + + // The maximum number of particles. + uint32 maxParticles; + + // The number of active particles. + uint32 activeParticles; + // The emission rate (particles/sec). int emissionRate; @@ -441,16 +571,13 @@ protected: float direction; float spread; - // Whether the direction should be relative to the emitter's movement. - bool relative; - // The speed. float speedMin; float speedMax; - // Acceleration towards the bottom of the screen - float gravityMin; - float gravityMax; + // Acceleration along the x and y axes. + love::Vector linearAccelerationMin; + love::Vector linearAccelerationMax; // Acceleration towards the emitter's center float radialAccelerationMin; @@ -480,11 +607,23 @@ protected: // Color. std::vector colors; - void add(); - void remove(particle *p); + void createBuffers(size_t size); + void deleteBuffers(); + + void addParticle(); + particle *removeParticle(particle *p); + + // Called by addParticle. + void initParticle(particle *p); + void insertTop(particle *p); + void insertBottom(particle *p); + void insertRandom(particle *p); static StringMap::Entry distributionsEntries[]; static StringMap distributions; + + static StringMap::Entry insertModesEntries[]; + static StringMap insertModes; }; } // opengl diff --git a/src/modules/graphics/opengl/Polyline.cpp b/src/modules/graphics/opengl/Polyline.cpp new file mode 100644 index 000000000..24d09405c --- /dev/null +++ b/src/modules/graphics/opengl/Polyline.cpp @@ -0,0 +1,381 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include + +// LOVE +#include "Polyline.h" + +// OpenGL +#include "OpenGL.h" + +// treat adjacent segments with angles between their directions <5 degree as straight +static const float LINES_PARALLEL_EPS = 0.05f; + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +void Polyline::render(const float *coords, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw) +{ + static std::vector anchors; + anchors.clear(); + anchors.reserve(size_hint); + + static std::vector normals; + normals.clear(); + normals.reserve(size_hint); + + // prepare vertex arrays + if (draw_overdraw) + halfwidth -= pixel_size * .3; + + // compute sleeve + bool is_looping = (coords[0] == coords[count - 2]) && (coords[1] == coords[count - 1]); + Vector s; + if (!is_looping) // virtual starting point at second point mirrored on first point + s = Vector(coords[2] - coords[0], coords[3] - coords[1]); + else // virtual starting point at last vertex + s = Vector(coords[0] - coords[count - 4], coords[1] - coords[count - 3]); + + float len_s = s.getLength(); + Vector ns = s.getNormal(halfwidth / len_s); + + Vector q, r(coords[0], coords[1]); + for (size_t i = 0; i + 3 < count; i += 2) + { + q = r; + r = Vector(coords[i + 2], coords[i + 3]); + renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth); + } + + q = r; + r = is_looping ? Vector(coords[2], coords[3]) : r + s; + renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth); + + vertex_count = normals.size(); + vertices = new Vector[vertex_count]; + for (size_t i = 0; i < vertex_count; ++i) + vertices[i] = anchors[i] + normals[i]; + + if (draw_overdraw) + render_overdraw(normals, pixel_size, is_looping); +} + +void NoneJoinPolyline::renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw) +{ + anchors.push_back(q); + anchors.push_back(q); + normals.push_back(ns); + normals.push_back(-ns); + + s = (r - q); + len_s = s.getLength(); + ns = s.getNormal(hw / len_s); + + anchors.push_back(q); + anchors.push_back(q); + normals.push_back(-ns); + normals.push_back(ns); +} + + +/** Calculate line boundary points. + * + * Sketch: + * + * u1 + * -------------+---...___ + * | ```'''-- --- + * p- - - - - - q- - . _ _ | w/2 + * | ` ' ' r + + * -------------+---...___ | w/2 + * u2 ```'''-- --- + * + * u1 and u2 depend on four things: + * - the half line width w/2 + * - the previous line vertex p + * - the current line vertex q + * - the next line vertex r + * + * u1/u2 are the intersection points of the parallel lines to p-q and q-r, + * i.e. the point where + * + * (q + w/2 * ns) + lambda * (q - p) = (q + w/2 * nt) + mu * (r - q) (u1) + * (q - w/2 * ns) + lambda * (q - p) = (q - w/2 * nt) + mu * (r - q) (u2) + * + * with nt,nt being the normals on the segments s = p-q and t = q-r, + * + * ns = perp(s) / |s| + * nt = perp(t) / |t|. + * + * Using the linear equation system (similar for u2) + * + * q + w/2 * ns + lambda * s - (q + w/2 * nt + mu * t) = 0 (u1) + * <=> q-q + lambda * s - mu * t = (nt - ns) * w/2 + * <=> lambda * s - mu * t = (nt - ns) * w/2 + * + * the intersection points can be efficiently calculated using Cramer's rule. + */ +void MiterJoinPolyline::renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw) +{ + Vector t = (r - q); + float len_t = t.getLength(); + Vector nt = t.getNormal(hw / len_t); + + anchors.push_back(q); + anchors.push_back(q); + + float det = s ^ t; + if (fabs(det) / (len_s * len_t) < LINES_PARALLEL_EPS && s * t > 0) + { + // lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2 + normals.push_back(ns); + normals.push_back(-ns); + } + else + { + // cramers rule + float lambda = ((nt - ns) ^ t) / det; + Vector d = ns + s * lambda; + normals.push_back(d); + normals.push_back(-d); + } + + s = t; + ns = nt; + len_s = len_t; +} + +/** Calculate line boundary points. + * + * Sketch: + * + * uh1___uh2 + * .' '. + * .' q '. + * .' ' ' '. + *.' ' .'. ' '. + * ' .' ul'. ' + * p .' '. r + * + * + * ul can be found as above, uh1 and uh2 are much simpler: + * + * uh1 = q + ns * w/2, uh2 = q + nt * w/2 + */ +void BevelJoinPolyline::renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw) +{ + Vector t = (r - q); + float len_t = t.getLength(); + + float det = s ^ t; + if (fabs(det) / (len_s * len_t) < LINES_PARALLEL_EPS && s * t > 0) + { + // lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2 + Vector n = t.getNormal(hw / len_t); + anchors.push_back(q); + anchors.push_back(q); + normals.push_back(n); + normals.push_back(-n); + s = t; + len_s = len_t; + return; // early out + } + + // cramers rule + Vector nt= t.getNormal(hw / len_t); + float lambda = ((nt - ns) ^ t) / det; + Vector d = ns + s * lambda; + + anchors.push_back(q); + anchors.push_back(q); + anchors.push_back(q); + anchors.push_back(q); + if (det > 0) // 'left' turn -> intersection on the top + { + normals.push_back(d); + normals.push_back(-ns); + normals.push_back(d); + normals.push_back(-nt); + } + else + { + normals.push_back(ns); + normals.push_back(-d); + normals.push_back(nt); + normals.push_back(-d); + } + s = t; + len_s = len_t; + ns = nt; +} + +void Polyline::render_overdraw(const std::vector &normals, float pixel_size, bool is_looping) +{ + overdraw_vertex_count = 2 * vertex_count + (is_looping ? 0 : 2); + overdraw = new Vector[overdraw_vertex_count]; + // upper segment + for (size_t i = 0; i + 1 < vertex_count; i += 2) + { + overdraw[i] = vertices[i]; + overdraw[i+1] = vertices[i] + normals[i] * (pixel_size / normals[i].getLength()); + } + // lower segment + for (size_t i = 0; i + 1 < vertex_count; i += 2) + { + size_t k = vertex_count - i - 1; + overdraw[vertex_count + i] = vertices[k]; + overdraw[vertex_count + i+1] = vertices[k] + normals[k] * (pixel_size / normals[i].getLength()); + } + + // if not looping, the outer overdraw vertices need to be displaced + // to cover the line endings, i.e.: + // +- - - - //- - + +- - - - - //- - - + + // +-------//-----+ : +-------//-----+ : + // | core // line | --> : | core // line | : + // +-----//-------+ : +-----//-------+ : + // +- - //- - - - + +- - - //- - - - - + + if (!is_looping) + { + // left edge + Vector spacer = (overdraw[1] - overdraw[3]); + spacer.normalize(pixel_size); + overdraw[1] += spacer; + overdraw[overdraw_vertex_count - 3] += spacer; + + // right edge + spacer = (overdraw[vertex_count-1] - overdraw[vertex_count-3]); + spacer.normalize(pixel_size); + overdraw[vertex_count-1] += spacer; + overdraw[vertex_count+1] += spacer; + + // we need to draw two more triangles to close the + // overdraw at the line start. + overdraw[overdraw_vertex_count-2] = overdraw[0]; + overdraw[overdraw_vertex_count-1] = overdraw[1]; + } +} + +void NoneJoinPolyline::render_overdraw(const std::vector &/*normals*/, float pixel_size, bool /*is_looping*/) +{ + overdraw_vertex_count = 4 * (vertex_count-2); // less than ideal + overdraw = new Vector[overdraw_vertex_count]; + for (size_t i = 2; i + 3 < vertex_count; i += 4) + { + Vector s = vertices[i] - vertices[i+3]; + Vector t = vertices[i] - vertices[i+1]; + s.normalize(pixel_size); + t.normalize(pixel_size); + + const size_t k = 4 * (i - 2); + overdraw[k ] = vertices[i]; + overdraw[k+1] = vertices[i] + s + t; + overdraw[k+2] = vertices[i+1] + s - t; + overdraw[k+3] = vertices[i+1]; + + overdraw[k+4] = vertices[i+1]; + overdraw[k+5] = vertices[i+1] + s - t; + overdraw[k+6] = vertices[i+2] - s - t; + overdraw[k+7] = vertices[i+2]; + + overdraw[k+8] = vertices[i+2]; + overdraw[k+9] = vertices[i+2] - s - t; + overdraw[k+10] = vertices[i+3] - s + t; + overdraw[k+11] = vertices[i+3]; + + overdraw[k+12] = vertices[i+3]; + overdraw[k+13] = vertices[i+3] - s + t; + overdraw[k+14] = vertices[i] + s + t; + overdraw[k+15] = vertices[i]; + } +} + +Polyline::~Polyline() +{ + if (vertices) + delete[] vertices; + if (overdraw) + delete[] overdraw; +} + +void Polyline::draw() +{ + gl.prepareDraw(); + + // draw the core line + gl.bindTexture(0); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *)vertices); + glDrawArrays(draw_mode, 0, vertex_count); + + if (overdraw) + { + // prepare colors: + Color c = gl.getColor(); + Color *colors = new Color[overdraw_vertex_count]; + fill_color_array(colors, c); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); + glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *)overdraw); + glDrawArrays(draw_mode, 0, overdraw_vertex_count); + glDisableClientState(GL_COLOR_ARRAY); + + delete[] colors; + + gl.setColor(c); + } + + glDisableClientState(GL_VERTEX_ARRAY); +} + +void Polyline::fill_color_array(Color *colors, const Color &c) +{ + for (size_t i = 0; i < overdraw_vertex_count; ++i) + { + colors[i] = c; + // avoids branching. equiv to if (i%2 == 1) colors[i].a = 0; + colors[i].a *= GLubyte((i+1) % 2); + } +} + +void NoneJoinPolyline::fill_color_array(Color *colors, const Color &c) +{ + for (size_t i = 0; i < overdraw_vertex_count; ++i) + { + colors[i] = c; + // if (i % 4 == 1 || i % 4 == 2) colors[i].a = 0 + colors[i].a *= GLubyte((i+1) % 4 < 2); + } +} + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/Polyline.h b/src/modules/graphics/opengl/Polyline.h new file mode 100644 index 000000000..746bd4821 --- /dev/null +++ b/src/modules/graphics/opengl/Polyline.h @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_GRAPHICS_OPENGL_POLYLINE_H +#define LOVE_GRAPHICS_OPENGL_POLYLINE_H + +#include + +// LOVE +#include "common/Vector.h" + +// OpenGL +#include "OpenGL.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +/** + * Abstract base class for a chain of segments. + * @author Matthias Richter + **/ +class Polyline +{ +public: + Polyline(GLenum mode = GL_TRIANGLE_STRIP) + : vertices(NULL) + , overdraw(NULL) + , vertex_count(0) + , overdraw_vertex_count(0) + , draw_mode(mode) + {} + virtual ~Polyline(); + + /** + * @param vertices Vertices defining the core line segments + * @param count Number of coordinates (= size of the array vertices) + * @param size_hint Expected number of vertices of the rendering sleeve around the core line. + * @param halfwidth linewidth / 2. + * @param pixel_size Dimension of one pixel on the screen in world coordinates. + * @param draw_overdraw Fake antialias the line. + */ + void render(const float *vertices, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw); + + /** Draws the line on the screen + */ + void draw(); + +protected: + virtual void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping); + virtual void fill_color_array(Color *colors, const Color &c); + + /** Calculate line boundary points. + * + * @param[out] anchors Anchor points defining the core line. + * @param[out] normals Normals defining the edge of the sleeve. + * @param[in,out] s Direction of segment pq (updated to the segment qr). + * @param[in,out] len_s Length of segment pq (updated to the segment qr). + * @param[in,out] ns Normal on the segment pq (updated to the segment qr). + * @param[in] q Current point on the line. + * @param[in] r Next point on the line. + * @param[in] hw Half line width (see Polyline.render()). + */ + virtual void renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw) = 0; + + Vector *vertices; + Vector *overdraw; + size_t vertex_count; + size_t overdraw_vertex_count; + GLenum draw_mode; + +}; // Polyline + + +/** + * A Polyline whose segments are not connected. + * @author Matthias Richter + */ +class NoneJoinPolyline : public Polyline +{ +public: + NoneJoinPolyline() + : Polyline(GL_QUADS) + {} + + void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw) + { + Polyline::render(vertices, count, 2 * count - 4, halfwidth, pixel_size, draw_overdraw); + // discard the first and last two vertices. (these are redundant) + for (size_t i = 0; i < vertex_count - 2; ++i) + this->vertices[i] = this->vertices[i+2]; + vertex_count -= 2; + } + +protected: + virtual void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping); + virtual void fill_color_array(Color *colors, const Color &c); + virtual void renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw); +}; + + +/** + * A Polyline whose segments are connected by a sharp edge. + * @author Matthias Richter + */ +class MiterJoinPolyline : public Polyline +{ +public: + void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw) + { + Polyline::render(vertices, count, count, halfwidth, pixel_size, draw_overdraw); + } + +protected: + virtual void renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw); +}; + + +/** + * A Polyline whose segments are connected by a flat edge. + * @author Matthias Richter + */ +class BevelJoinPolyline : public Polyline +{ +public: + void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw) + { + Polyline::render(vertices, count, 2 * count - 4, halfwidth, pixel_size, draw_overdraw); + } + +protected: + virtual void renderEdge(std::vector &anchors, std::vector &normals, + Vector &s, float &len_s, Vector &ns, + const Vector &q, const Vector &r, float hw); +}; + +} // opengl +} // graphics +} // love + +#endif // LOVE_GRAPHICS_OPENGL_POLYLINE_H diff --git a/src/modules/graphics/opengl/Quad.cpp b/src/modules/graphics/opengl/Quad.cpp deleted file mode 100644 index 7f70e512c..000000000 --- a/src/modules/graphics/opengl/Quad.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2006-2013 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. - **/ - -#include "Quad.h" -#include "common/Matrix.h" - -// OpenGL -#include "OpenGL.h" - -// STD -#include // For memcpy - -namespace love -{ -namespace graphics -{ -namespace opengl -{ - -Quad::Quad(const Viewport &v, float sw, float sh) - : sw(sw) - , sh(sh) -{ - memset(vertices, 255, sizeof(vertex)*NUM_VERTICES); - refresh(v, sw, sh); -} - -Quad::~Quad() -{ -} - -void Quad::refresh(const Viewport &v, float sw, float sh) -{ - if (!GLEE_ARB_texture_non_power_of_two) - { - sw = next_p2(sw); - sh = next_p2(sh); - } - viewport = v; - - vertices[0].x = 0; - vertices[0].y = 0; - vertices[1].x = 0; - vertices[1].y = v.h; - vertices[2].x = v.w; - vertices[2].y = v.h; - vertices[3].x = v.w; - vertices[3].y = 0; - - vertices[0].s = v.x/sw; - vertices[0].t = v.y/sh; - vertices[1].s = v.x/sw; - vertices[1].t = (v.y+v.h)/sh; - vertices[2].s = (v.x+v.w)/sw; - vertices[2].t = (v.y+v.h)/sh; - vertices[3].s = (v.x+v.w)/sw; - vertices[3].t = v.y/sh; -} - -void Quad::setViewport(const Quad::Viewport &v) -{ - refresh(v, sw, sh); -} - -Quad::Viewport Quad::getViewport() const -{ - return viewport; -} - -void Quad::flip(bool x, bool y) -{ - vertex temp[4]; - if (x) - { - memcpy(temp, vertices, sizeof(vertex)*NUM_VERTICES); - vertices[0].s = temp[3].s; - vertices[0].t = temp[3].t; - vertices[1].s = temp[2].s; - vertices[1].t = temp[2].t; - vertices[2].s = temp[1].s; - vertices[2].t = temp[1].t; - vertices[3].s = temp[0].s; - vertices[3].t = temp[0].t; - } - if (y) - { - memcpy(temp, vertices, sizeof(vertex)*NUM_VERTICES); - vertices[0].s = temp[1].s; - vertices[0].t = temp[1].t; - vertices[1].s = temp[0].s; - vertices[1].t = temp[0].t; - vertices[2].s = temp[3].s; - vertices[2].t = temp[3].t; - vertices[3].s = temp[2].s; - vertices[3].t = temp[2].t; - } -} - -const vertex *Quad::getVertices() const -{ - return vertices; -} - -} // opengl -} // graphics -} // love diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index 7050d1f0f..88ebbdac3 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,11 +18,13 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "common/config.h" #include "Shader.h" -#include "Graphics.h" +#include "Canvas.h" +// C++ #include namespace love @@ -47,10 +49,10 @@ namespace ~TemporaryAttacher() { - if (prevShader != NULL) + if (prevShader != nullptr) prevShader->attach(); else - Shader::detach(); + curShader->detach(); } Shader *curShader; @@ -59,25 +61,30 @@ namespace } // anonymous namespace -Shader *Shader::current = NULL; +Shader *Shader::current = nullptr; -GLint Shader::maxTextureUnits = 0; +GLint Shader::maxTexUnits = 0; std::vector Shader::textureCounters; Shader::Shader(const ShaderSources &sources) : shaderSources(sources) , program(0) + , builtinUniforms() + , lastCanvas((Canvas *) -1) { if (shaderSources.empty()) throw love::Exception("Cannot create shader: no source code!"); - GLint maxtexunits; - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtexunits); - maxTextureUnits = std::max(maxtexunits - 1, 0); + if (maxTexUnits <= 0) + { + GLint maxtexunits; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtexunits); + maxTexUnits = std::max(maxtexunits - 1, 0); + } // initialize global texture id counters if needed - if (textureCounters.size() < (size_t) maxTextureUnits) - textureCounters.resize(maxTextureUnits, 0); + if (textureCounters.size() < (size_t) maxTexUnits) + textureCounters.resize(maxTexUnits, 0); // load shader source and create program object loadVolatile(); @@ -88,23 +95,30 @@ Shader::~Shader() if (current == this) detach(); + for (auto it = boundRetainables.begin(); it != boundRetainables.end(); ++it) + { + it->second->release(); + boundRetainables.erase(it); + } + unloadVolatile(); } GLuint Shader::compileCode(ShaderType type, const std::string &code) { GLenum glshadertype; - const char *shadertypename = NULL; + const char *typestr; + + if (!typeNames.find(type, typestr)) + typestr = ""; switch (type) { case TYPE_VERTEX: glshadertype = GL_VERTEX_SHADER; - shadertypename = "vertex"; break; - case TYPE_FRAGMENT: + case TYPE_PIXEL: glshadertype = GL_FRAGMENT_SHADER; - shadertypename = "fragment"; break; default: throw love::Exception("Cannot create shader object: unknown shader type."); @@ -120,10 +134,10 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code) { GLenum err = glGetError(); - if (err == GL_INVALID_ENUM) // invalid or unsupported shader type - throw love::Exception("Cannot create %s shader object: %s shaders not supported.", shadertypename, shadertypename); - else // other errors should only happen between glBegin() and glEnd() - throw love::Exception("Cannot create %s shader object.", shadertypename); + if (err == GL_INVALID_ENUM) + throw love::Exception("Cannot create %s shader object: %s shaders not supported.", typestr, typestr); + else + throw love::Exception("Cannot create %s shader object.", typestr); } const char *src = code.c_str(); @@ -132,23 +146,26 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code) glCompileShader(shaderid); + // Get any warnings the shader compiler may have produced. + GLint infologlen; + glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen); + + GLchar *infolog = new GLchar[infologlen + 1]; + glGetShaderInfoLog(shaderid, infologlen, nullptr, infolog); + + // Save any warnings for later querying. + if (infologlen > 0) + shaderWarnings[type] = infolog; + + delete[] infolog; + GLint status; glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { - GLint infologlen; - glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen); - - GLchar *errorlog = new GLchar[infologlen + 1]; - glGetShaderInfoLog(shaderid, infologlen, NULL, errorlog); - - std::string tmp(errorlog); - - delete[] errorlog; - glDeleteShader(shaderid); - - throw love::Exception("Cannot compile %s shader code:\n%s", shadertypename, tmp.c_str()); + throw love::Exception("Cannot compile %s shader code:\n%s", + typestr, shaderWarnings[type].c_str()); } return shaderid; @@ -157,7 +174,7 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code) void Shader::createProgram(const std::vector &shaderids) { program = glCreateProgram(); - if (program == 0) // should only fail when called between glBegin() and glEnd() + if (program == 0) throw love::Exception("Cannot create shader program object."); std::vector::const_iterator it; @@ -166,26 +183,78 @@ void Shader::createProgram(const std::vector &shaderids) glLinkProgram(program); + // flag shaders for auto-deletion when the program object is deleted. for (it = shaderids.begin(); it != shaderids.end(); ++it) - glDeleteShader(*it); // flag shaders for auto-deletion when program object is deleted + glDeleteShader(*it); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { - const std::string warnings = getWarnings(); + std::string warnings = getProgramWarnings(); glDeleteProgram(program); + program = 0; throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str()); } } +void Shader::mapActiveUniforms() +{ + uniforms.clear(); + + GLint numuniforms; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numuniforms); + + GLsizei bufsize; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint *) &bufsize); + + if (bufsize <= 0) + return; + + for (int i = 0; i < numuniforms; i++) + { + GLchar *cname = new GLchar[bufsize]; + GLsizei namelength; + + Uniform u; + + glGetActiveUniform(program, (GLuint) i, bufsize, &namelength, &u.count, &u.type, cname); + + u.name = std::string(cname, (size_t) namelength); + u.location = glGetUniformLocation(program, u.name.c_str()); + u.baseType = getUniformBaseType(u.type); + + delete[] cname; + + // glGetActiveUniform appends "[0]" to the end of array uniform names... + if (u.name.length() > 3) + { + size_t findpos = u.name.find("[0]"); + if (findpos != std::string::npos && findpos == u.name.length() - 3) + u.name.erase(u.name.length() - 3); + } + + // If this is a built-in (LOVE-created) uniform, store the location. + BuiltinExtern builtin; + if (builtinNames.find(u.name.c_str(), builtin)) + builtinUniforms[int(builtin)] = u.location; + + if (u.location != -1) + uniforms[u.name] = u; + } +} + bool Shader::loadVolatile() { // zero out active texture list - activeTextureUnits.clear(); - activeTextureUnits.insert(activeTextureUnits.begin(), maxTextureUnits, 0); + activeTexUnits.clear(); + activeTexUnits.insert(activeTexUnits.begin(), maxTexUnits, 0); + + // Built-in uniform locations default to -1 (nonexistant.) + for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++) + builtinUniforms[i] = -1; std::vector shaderids; @@ -201,9 +270,13 @@ bool Shader::loadVolatile() createProgram(shaderids); + // Retreive all active uniform variables in this shader from OpenGL. + mapActiveUniforms(); + if (current == this) { - current = NULL; // make sure glUseProgram gets called + // make sure glUseProgram gets called. + current = nullptr; attach(); } @@ -216,29 +289,37 @@ void Shader::unloadVolatile() glUseProgram(0); if (program != 0) + { glDeleteProgram(program); - - program = 0; + program = 0; + } // decrement global texture id counters for texture units which had textures bound from this shader - for (size_t i = 0; i < activeTextureUnits.size(); ++i) + for (size_t i = 0; i < activeTexUnits.size(); ++i) { - if (activeTextureUnits[i] > 0) + if (activeTexUnits[i] > 0) textureCounters[i] = std::max(textureCounters[i] - 1, 0); } // active texture list is probably invalid, clear it - activeTextureUnits.clear(); - activeTextureUnits.insert(activeTextureUnits.begin(), maxTextureUnits, 0); + activeTexUnits.clear(); + activeTexUnits.insert(activeTexUnits.begin(), maxTexUnits, 0); // same with uniform location list uniforms.clear(); + + // And the locations of any built-in uniform variables. + for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++) + builtinUniforms[i] = -1; + + shaderWarnings.clear(); } -std::string Shader::getWarnings() const +std::string Shader::getProgramWarnings() const { GLint strlen, nullpos; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strlen); + char *tempstr = new char[strlen+1]; // be extra sure that the error string will be 0-terminated memset(tempstr, '\0', strlen+1); @@ -247,194 +328,383 @@ std::string Shader::getWarnings() const std::string warnings(tempstr); delete[] tempstr; + + return warnings; +} + +std::string Shader::getWarnings() const +{ + std::string warnings; + const char *typestr; + + // Get the individual shader stage warnings + std::map::const_iterator it; + for (it = shaderWarnings.begin(); it != shaderWarnings.end(); ++it) + { + if (typeNames.find(it->first, typestr)) + warnings += std::string(typestr) + std::string(" shader:\n") + it->second; + } + + warnings += getProgramWarnings(); + return warnings; } void Shader::attach(bool temporary) { if (current != this) - glUseProgram(program); + { + if (current != nullptr) + current->release(); - current = this; + glUseProgram(program); + current = this; + + current->retain(); + } if (!temporary) { // make sure all sent textures are properly bound to their respective texture units // note: list potentially contains texture ids of deleted/invalid textures! - for (size_t i = 0; i < activeTextureUnits.size(); ++i) + for (size_t i = 0; i < activeTexUnits.size(); ++i) { - if (activeTextureUnits[i] > 0) - bindTextureToUnit(activeTextureUnits[i], i + 1, false); + if (activeTexUnits[i] > 0) + gl.bindTextureToUnit(activeTexUnits[i], i + 1, false); } - setActiveTextureUnit(0); + + // We always want to use texture unit 0 for everyhing else. + gl.setTextureUnit(0); } } void Shader::detach() { - if (current != NULL) + if (current != nullptr) glUseProgram(0); - current = NULL; + current = nullptr; +} + +const Shader::Uniform &Shader::getUniform(const std::string &name) const +{ + std::map::const_iterator it = uniforms.find(name); + + if (it == uniforms.end()) + throw love::Exception("Variable '%s' does not exist.\n" + "A common error is to define but not use the variable.", name.c_str()); + + return it->second; +} + +int Shader::getUniformTypeSize(GLenum type) const +{ + switch (type) + { + case GL_INT: + case GL_FLOAT: + case GL_BOOL: + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + return 1; + case GL_INT_VEC2: + case GL_FLOAT_VEC2: + case GL_FLOAT_MAT2: + case GL_BOOL_VEC2: + return 2; + case GL_INT_VEC3: + case GL_FLOAT_VEC3: + case GL_FLOAT_MAT3: + case GL_BOOL_VEC3: + return 3; + case GL_INT_VEC4: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT4: + case GL_BOOL_VEC4: + return 4; + default: + break; + } + + return 1; +} + +Shader::UniformType Shader::getUniformBaseType(GLenum type) const +{ + switch (type) + { + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + return UNIFORM_INT; + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: + return UNIFORM_FLOAT; + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: + return UNIFORM_BOOL; + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + return UNIFORM_SAMPLER; + default: + break; + } + + return UNIFORM_UNKNOWN; +} + +void Shader::checkSetUniformError(const Uniform &u, int size, int count, UniformType sendtype) const +{ + if (!program) + throw love::Exception("No active shader program."); + + int realsize = getUniformTypeSize(u.type); + + if (size != realsize) + throw love::Exception("Value size of %d does not match variable size of %d.", size, realsize); + + if ((u.count == 1 && count > 1) || count < 0) + throw love::Exception("Invalid number of values (expected %d, got %d).", u.count, count); + + if (u.baseType == UNIFORM_SAMPLER && sendtype != u.baseType) + throw love::Exception("Cannot send a value of this type to an Image variable."); + + if ((sendtype == UNIFORM_FLOAT && u.baseType == UNIFORM_INT) || (sendtype == UNIFORM_INT && u.baseType == UNIFORM_FLOAT)) + throw love::Exception("Cannot convert between float and int."); +} + +void Shader::sendInt(const std::string &name, int size, const GLint *vec, int count) +{ + TemporaryAttacher attacher(this); + + const Uniform &u = getUniform(name); + checkSetUniformError(u, size, count, UNIFORM_INT); + + switch (size) + { + case 4: + glUniform4iv(u.location, count, vec); + break; + case 3: + glUniform3iv(u.location, count, vec); + break; + case 2: + glUniform2iv(u.location, count, vec); + break; + case 1: + default: + glUniform1iv(u.location, count, vec); + break; + } } void Shader::sendFloat(const std::string &name, int size, const GLfloat *vec, int count) { TemporaryAttacher attacher(this); - GLint location = getUniformLocation(name); - if (size < 1 || size > 4) - throw love::Exception("Invalid variable size: %d (expected 1-4).", size); + const Uniform &u = getUniform(name); + checkSetUniformError(u, size, count, UNIFORM_FLOAT); switch (size) { case 4: - glUniform4fv(location, count, vec); + glUniform4fv(u.location, count, vec); break; case 3: - glUniform3fv(location, count, vec); + glUniform3fv(u.location, count, vec); break; case 2: - glUniform2fv(location, count, vec); + glUniform2fv(u.location, count, vec); break; case 1: default: - glUniform1fv(location, count, vec); + glUniform1fv(u.location, count, vec); break; } - - // throw error if needed - checkSetUniformError(); } void Shader::sendMatrix(const std::string &name, int size, const GLfloat *m, int count) { TemporaryAttacher attacher(this); - GLint location = getUniformLocation(name); if (size < 2 || size > 4) { throw love::Exception("Invalid matrix size: %dx%d " - "(can only set 2x2, 3x3 or 4x4 matrices).", size,size); + "(can only set 2x2, 3x3 or 4x4 matrices.)", size,size); } + const Uniform &u = getUniform(name); + checkSetUniformError(u, size, count, UNIFORM_FLOAT); + switch (size) { case 4: - glUniformMatrix4fv(location, count, GL_FALSE, m); + glUniformMatrix4fv(u.location, count, GL_FALSE, m); break; case 3: - glUniformMatrix3fv(location, count, GL_FALSE, m); + glUniformMatrix3fv(u.location, count, GL_FALSE, m); break; case 2: default: - glUniformMatrix2fv(location, count, GL_FALSE, m); + glUniformMatrix2fv(u.location, count, GL_FALSE, m); break; } - - // throw error if needed - checkSetUniformError(); } -void Shader::sendTexture(const std::string &name, GLuint texture) +void Shader::sendTexture(const std::string &name, Texture *texture) { + GLuint gltex = texture->getGLTexture(); + TemporaryAttacher attacher(this); - GLint location = getUniformLocation(name); - int textureunit = getTextureUnit(name); + + int texunit = getTextureUnit(name); + + const Uniform &u = getUniform(name); + checkSetUniformError(u, 1, 1, UNIFORM_SAMPLER); // bind texture to assigned texture unit and send uniform to shader program - bindTextureToUnit(texture, textureunit, false); - glUniform1i(location, textureunit); + gl.bindTextureToUnit(gltex, texunit, false); + + glUniform1i(u.location, texunit); // reset texture unit - setActiveTextureUnit(0); - - // throw error if needed - checkSetUniformError(); + gl.setTextureUnit(0); // increment global shader texture id counter for this texture unit, if we haven't already - if (activeTextureUnits[textureunit-1] == 0) - ++textureCounters[textureunit-1]; + if (activeTexUnits[texunit-1] == 0) + ++textureCounters[texunit-1]; - // store texture id so it can be re-bound to the proper texture unit when necessary - activeTextureUnits[textureunit-1] = texture; + // store texture id so it can be re-bound to the proper texture unit later + activeTexUnits[texunit-1] = gltex; + + retainObject(name, texture); } -void Shader::sendImage(const std::string &name, const Image &image) +void Shader::retainObject(const std::string &name, Object *object) { - sendTexture(name, image.getTextureName()); -} + auto it = boundRetainables.find(name); + if (it != boundRetainables.end()) + it->second->release(); -void Shader::sendCanvas(const std::string &name, const Canvas &canvas) -{ - sendTexture(name, canvas.getTextureName()); -} - -GLint Shader::getUniformLocation(const std::string &name) -{ - std::map::const_iterator it = uniforms.find(name); - if (it != uniforms.end()) - return it->second; - - GLint location = glGetUniformLocation(program, name.c_str()); - if (location == -1) - { - throw love::Exception( - "Cannot get location of shader variable `%s'.\n" - "A common error is to define but not use the variable.", name.c_str()); - } - - uniforms[name] = location; - return location; + object->retain(); + boundRetainables[name] = object; } int Shader::getTextureUnit(const std::string &name) { - std::map::const_iterator it = textureUnitPool.find(name); + auto it = texUnitPool.find(name); - if (it != textureUnitPool.end()) + if (it != texUnitPool.end()) return it->second; - int textureunit = 1; + int texunit = 1; // prefer texture units which are unused by all other shaders - std::vector::iterator nextfreeunit = std::find(textureCounters.begin(), textureCounters.end(), 0); + auto freeunit_it = std::find(textureCounters.begin(), textureCounters.end(), 0); - if (nextfreeunit != textureCounters.end()) - textureunit = std::distance(textureCounters.begin(), nextfreeunit) + 1; // we don't want to use unit 0 + if (freeunit_it != textureCounters.end()) + { + // we don't want to use unit 0 + texunit = std::distance(textureCounters.begin(), freeunit_it) + 1; + } else { // no completely unused texture units exist, try to use next free slot in our own list - std::vector::iterator nexttexunit = std::find(activeTextureUnits.begin(), activeTextureUnits.end(), 0); + auto nextunit_it = std::find(activeTexUnits.begin(), activeTexUnits.end(), 0); - if (nexttexunit == activeTextureUnits.end()) + if (nextunit_it == activeTexUnits.end()) throw love::Exception("No more texture units available for shader."); - textureunit = std::distance(activeTextureUnits.begin(), nexttexunit) + 1; // we don't want to use unit 0 + // we don't want to use unit 0 + texunit = std::distance(activeTexUnits.begin(), nextunit_it) + 1; } - textureUnitPool[name] = textureunit; - return textureunit; + texUnitPool[name] = texunit; + return texunit; } -void Shader::checkSetUniformError() +bool Shader::hasBuiltinExtern(BuiltinExtern builtin) const { - GLenum error_code = glGetError(); - if (GL_INVALID_OPERATION == error_code) + return builtinUniforms[int(builtin)] != -1; +} + +bool Shader::sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *vec, int count) +{ + if (!hasBuiltinExtern(builtin)) + return false; + + GLint location = builtinUniforms[int(builtin)]; + + TemporaryAttacher attacher(this); + + switch (size) { - throw love::Exception( - "Invalid operation:\n" - "- Trying to send the wrong value type to shader variable, or\n" - "- Trying to send array values with wrong dimension, or\n" - "- Invalid variable name."); + case 1: + glUniform1fv(location, count, vec); + break; + case 2: + glUniform2fv(location, count, vec); + break; + case 3: + glUniform3fv(location, count, vec); + break; + case 4: + glUniform4fv(location, count, vec); + break; + default: + return false; } + + return true; +} + +void Shader::checkSetScreenParams() +{ + if (lastCanvas == Canvas::current) + return; + + // In the shader, we do pixcoord.y = gl_FragCoord.y * params[0] + params[1]. + // This lets us flip pixcoord.y when needed, to be consistent (Canvases + // have flipped y-values for pixel coordinates.) + GLfloat params[] = {0.0f, 0.0f}; + + if (Canvas::current != nullptr) + { + // gl_FragCoord.y is flipped in Canvases, so we un-flip: + // pixcoord.y = gl_FragCoord.y * -1.0 + height. + params[0] = -1.0f; + params[1] = (float) Canvas::current->getHeight(); + } + else + { + // No flipping: pixcoord.y = gl_FragCoord.y * 1.0 + 0.0. + params[0] = 1.0f; + params[1] = 0.0f; + } + + sendBuiltinFloat(BUILTIN_SCREEN_PARAMS, 2, params, 1); + lastCanvas = Canvas::current; } std::string Shader::getGLSLVersion() { - // GL_SHADING_LANGUAGE_VERSION may not be available in OpenGL < 2.0. - const char *tmp = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); - if (tmp == NULL) + const char *tmp = nullptr; + + // GL_SHADING_LANGUAGE_VERSION isn't available in OpenGL < 2.0. + if (GLEE_VERSION_2_0 || GLEE_ARB_shading_language_100) + tmp = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); + + if (tmp == nullptr) return "0.0"; // the version string always begins with a version number of the format @@ -452,6 +722,21 @@ bool Shader::isSupported() return GLEE_VERSION_2_0 && getGLSLVersion() >= "1.2"; } +StringMap::Entry Shader::typeNameEntries[] = +{ + {"vertex", Shader::TYPE_VERTEX}, + {"pixel", Shader::TYPE_PIXEL}, +}; + +StringMap Shader::typeNames(Shader::typeNameEntries, sizeof(Shader::typeNameEntries)); + +StringMap::Entry Shader::builtinNameEntries[] = +{ + {"love_ScreenParams", Shader::BUILTIN_SCREEN_PARAMS}, +}; + +StringMap Shader::builtinNames(Shader::builtinNameEntries, sizeof(Shader::builtinNameEntries)); + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index 4143cb9c4..97fcafc43 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,13 +21,16 @@ #ifndef LOVE_GRAPHICS_SHADER_H #define LOVE_GRAPHICS_SHADER_H +// LOVE #include "common/Object.h" +#include "common/StringMap.h" +#include "OpenGL.h" +#include "Texture.h" + +// STL #include #include #include -#include "OpenGL.h" -#include "Image.h" -#include "Canvas.h" namespace love { @@ -35,6 +38,9 @@ namespace graphics { namespace opengl { + +class Canvas; + // A GLSL shader class Shader : public Object, public Volatile { @@ -46,16 +52,23 @@ public: enum ShaderType { TYPE_VERTEX, - TYPE_FRAGMENT, + TYPE_PIXEL, TYPE_MAX_ENUM }; + // Built-in extern (uniform) variables. + enum BuiltinExtern + { + BUILTIN_SCREEN_PARAMS, + BUILTIN_MAX_ENUM + }; + // Type for a list of shader source codes in the form of sources[shadertype] = code typedef std::map ShaderSources; /** * Creates a new Shader using a list of source codes. - * Sources must contain either vertex or fragment shader code, or both. + * Sources must contain either vertex or pixel shader code, or both. **/ Shader(const ShaderSources &sources); @@ -83,14 +96,25 @@ public: **/ std::string getWarnings() const; + /** + * Send at least one integer or int-vector value to this Shader as a uniform. + * + * @param name The name of the uniform variable in the source code. + * @param size Number of elements in each vector to send. + * A value of 1 indicates a single-component vector (an int). + * @param vec Pointer to the integer or int-vector values. + * @param count Number of integer or int-vector values. + **/ + void sendInt(const std::string &name, int size, const GLint *vec, int count); + /** * Send at least one float or vector value to this Shader as a uniform. * * @param name The name of the uniform variable in the source code. * @param size Number of elements in each vector to send. * A value of 1 indicates a single-component vector (a float). - * @param vec Pointer to the float or vector values. - * @param count Number of float or vector values. + * @param vec Pointer to the float or float-vector values. + * @param count Number of float or float-vector values. **/ void sendFloat(const std::string &name, int size, const GLfloat *vec, int count); @@ -105,51 +129,100 @@ public: void sendMatrix(const std::string &name, int size, const GLfloat *m, int count); /** - * Send an image to this Shader as a uniform. + * Send a texture to this Shader as a uniform. * * @param name The name of the uniform variable in the source code. **/ - void sendImage(const std::string &name, const Image &image); + void sendTexture(const std::string &name, Texture *texture); /** - * Send a canvas to this Shader as a uniform. - * - * @param name The name of the uniform variable in the source code. + * Internal use only. **/ - void sendCanvas(const std::string &name, const Canvas &canvas); + bool hasBuiltinExtern(BuiltinExtern builtin) const; + bool sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *m, int count); + void checkSetScreenParams(); static std::string getGLSLVersion(); static bool isSupported(); private: - GLint getUniformLocation(const std::string &name); - void checkSetUniformError(); + // Types of potential uniform variables used in love's shaders. + enum UniformType + { + UNIFORM_FLOAT, + UNIFORM_INT, + UNIFORM_BOOL, + UNIFORM_SAMPLER, + UNIFORM_UNKNOWN + }; + + // Represents a single uniform/extern shader variable. + struct Uniform + { + GLint location; + GLint count; + GLenum type; + UniformType baseType; + std::string name; + }; + + // Map active uniform names to their locations. + void mapActiveUniforms(); + + const Uniform &getUniform(const std::string &name) const; + + int getUniformTypeSize(GLenum type) const; + UniformType getUniformBaseType(GLenum type) const; + void checkSetUniformError(const Uniform &u, int size, int count, UniformType sendtype) const; GLuint compileCode(ShaderType type, const std::string &code); void createProgram(const std::vector &shaderids); int getTextureUnit(const std::string &name); - void sendTexture(const std::string &name, GLuint texture); + void retainObject(const std::string &name, Object *object); + + // Get any warnings or errors generated only by the shader program object. + std::string getProgramWarnings() const; // List of all shader code attached to this Shader ShaderSources shaderSources; - GLuint program; // volatile + // Shader compiler warning strings for individual shader stages. + std::map shaderWarnings; + + // volatile + GLuint program; + + // Location values for any built-in uniform variables. + GLint builtinUniforms[BUILTIN_MAX_ENUM]; // Uniform location buffer map - std::map uniforms; + std::map uniforms; // Texture unit pool for setting images - std::map textureUnitPool; // textureUnitPool[name] = textureunit - std::vector activeTextureUnits; // activeTextureUnits[textureunit-1] = textureid + std::map texUnitPool; // texUnitPool[name] = textureunit + std::vector activeTexUnits; // activeTexUnits[textureunit-1] = textureid + + // Uniform name to retainable objects + std::map boundRetainables; + + // Pointer to the active Canvas when the screen params were last checked. + Canvas *lastCanvas; // Max GPU texture units available for sent images - static GLint maxTextureUnits; + static GLint maxTexUnits; // Counts total number of textures bound to each texture unit in all shaders static std::vector textureCounters; + + static StringMap::Entry typeNameEntries[]; + static StringMap typeNames; + + // Names for the built-in uniform variables. + static StringMap::Entry builtinNameEntries[]; + static StringMap builtinNames; }; } // opengl diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 2145e9bc0..7b583c4b8 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,15 +18,21 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +#include "common/config.h" #include "SpriteBatch.h" // OpenGL #include "OpenGL.h" // LOVE -#include "Image.h" -#include "Quad.h" #include "VertexBuffer.h" +#include "Texture.h" + +// C++ +#include + +// C +#include namespace love { @@ -35,16 +41,18 @@ namespace graphics namespace opengl { -SpriteBatch::SpriteBatch(Image *image, int size, int usage) - : image(image) +SpriteBatch::SpriteBatch(Texture *texture, int size, int usage) + : texture(texture) , size(size) , next(0) , color(0) , array_buf(0) , element_buf(0) { - GLenum gl_usage; + if (size <= 0) + throw love::Exception("Invalid SpriteBatch size."); + GLenum gl_usage; switch (usage) { default: @@ -59,7 +67,7 @@ SpriteBatch::SpriteBatch(Image *image, int size, int usage) break; } - const size_t vertex_size = sizeof(vertex) * 4 * size; + const size_t vertex_size = sizeof(Vertex) * 4 * size; try { @@ -79,12 +87,12 @@ SpriteBatch::SpriteBatch(Image *image, int size, int usage) throw love::Exception("Out of memory."); } - image->retain(); + texture->retain(); } SpriteBatch::~SpriteBatch() { - image->release(); + texture->release(); delete color; delete array_buf; @@ -98,16 +106,15 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl return -1; // Needed for colors. - memcpy(sprite, image->getVertices(), sizeof(vertex)*4); + memcpy(sprite, texture->getVertices(), sizeof(Vertex) * 4); // Transform. - Matrix t; + static Matrix t; t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); t.transform(sprite, sprite, 4); if (color) setColorv(sprite, *color); - addv(sprite, (index == -1) ? next : index); @@ -125,10 +132,9 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, return -1; // Needed for colors. - memcpy(sprite, quad->getVertices(), sizeof(vertex)*4); + memcpy(sprite, quad->getVertices(), sizeof(Vertex) * 4); - // Transform. - Matrix t; + static Matrix t; t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); t.transform(sprite, sprite, 4); @@ -164,16 +170,17 @@ void SpriteBatch::unlock() array_buf->unmap(); } -void SpriteBatch::setImage(Image *newimage) +void SpriteBatch::setTexture(Texture *newtexture) { - image->release(); - image = newimage; - image->retain(); + Object::AutoRelease imagerelease(texture); + + newtexture->retain(); + texture = newtexture; } -Image *SpriteBatch::getImage() +Texture *SpriteBatch::getTexture() { - return image; + return texture; } void SpriteBatch::setColor(const Color &color) @@ -190,21 +197,80 @@ void SpriteBatch::setColor() color = 0; } -bool SpriteBatch::isEmpty() const +const Color *SpriteBatch::getColor() const { - return next == 0; + return color; } -bool SpriteBatch::isFull() const +int SpriteBatch::getCount() const { - return next >= size; + return next; +} + +void SpriteBatch::setBufferSize(int newsize) +{ + if (newsize <= 0) + throw love::Exception("Invalid SpriteBatch size."); + + if (newsize == size) + return; + + // Map (lock) the old VertexBuffer to get a pointer to its data. + void *old_data = lock(); + + size_t vertex_size = sizeof(Vertex) * 4 * newsize; + + VertexBuffer *new_array_buf = 0; + VertexIndex *new_element_buf = 0; + void *new_data = 0; + + try + { + new_array_buf = VertexBuffer::Create(vertex_size, array_buf->getTarget(), array_buf->getUsage()); + new_element_buf = new VertexIndex(newsize); + + // VBO::map can throw an exception. Also we want to scope the bind. + VertexBuffer::Bind bind(*new_array_buf); + new_data = new_array_buf->map(); + } + catch (love::Exception &) + { + delete new_array_buf; + delete new_element_buf; + unlock(); + throw; + } + + // Copy as much of the old data into the new VertexBuffer as can fit. + memcpy(new_data, old_data, sizeof(Vertex) * 4 * std::min(newsize, size)); + + // We don't need to unmap the old VertexBuffer since we're deleting it. + delete array_buf; + delete element_buf; + + array_buf = new_array_buf; + element_buf = new_element_buf; + size = newsize; + + next = std::min(next, newsize); + + // But we should unmap (unlock) the new one! + unlock(); +} + +int SpriteBatch::getBufferSize() const +{ + return size; } void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { - const int color_offset = 0; - const int vertex_offset = sizeof(unsigned char) * 4; - const int texel_offset = sizeof(unsigned char) * 4 + sizeof(float) * 2; + const size_t vertex_offset = offsetof(Vertex, x); + const size_t texel_offset = offsetof(Vertex, s); + const size_t color_offset = offsetof(Vertex, r); + + if (next == 0) + return; static Matrix t; @@ -213,62 +279,59 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); glMultMatrixf((const GLfloat *)t.getElements()); - image->bind(); + texture->predraw(); VertexBuffer::Bind array_bind(*array_buf); VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer()); + Color curcolor = gl.getColor(); + // Apply per-sprite color, if a color is set. if (color) { glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), array_buf->getPointer(color_offset)); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), array_buf->getPointer(color_offset)); } glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(vertex), array_buf->getPointer(vertex_offset)); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(vertex_offset)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), array_buf->getPointer(texel_offset)); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset)); + gl.prepareDraw(); glDrawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0)); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (color) + { glDisableClientState(GL_COLOR_ARRAY); + gl.setColor(curcolor); + } + + texture->postdraw(); glPopMatrix(); } -void SpriteBatch::addv(const vertex *v, int index) +void SpriteBatch::addv(const Vertex *v, int index) { - int sprite_size = sizeof(vertex) * 4; - + static const int sprite_size = 4 * sizeof(Vertex); // bytecount VertexBuffer::Bind bind(*array_buf); - array_buf->fill(index * sprite_size, sprite_size, v); } -void SpriteBatch::setColorv(vertex *v, const Color &color) +void SpriteBatch::setColorv(Vertex *v, const Color &color) { - v[0].r = color.r; - v[0].g = color.g; - v[0].b = color.b; - v[0].a = color.a; - v[1].r = color.r; - v[1].g = color.g; - v[1].b = color.b; - v[1].a = color.a; - v[2].r = color.r; - v[2].g = color.g; - v[2].b = color.b; - v[2].a = color.a; - v[3].r = color.r; - v[3].g = color.g; - v[3].b = color.b; - v[3].a = color.a; + for (size_t i = 0; i < 4; ++i) + { + v[i].r = color.r; + v[i].g = color.g; + v[i].b = color.b; + v[i].a = color.a; + } } bool SpriteBatch::getConstant(const char *in, UsageHint &out) diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 42c9b008a..de14bf099 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -32,6 +32,7 @@ #include "graphics/Drawable.h" #include "graphics/Volatile.h" #include "graphics/Color.h" +#include "graphics/Quad.h" namespace love { @@ -41,8 +42,7 @@ namespace opengl { // Forward declarations. -class Image; -class Quad; +class Texture; class VertexBuffer; class VertexIndex; @@ -58,7 +58,7 @@ public: USAGE_MAX_ENUM }; - SpriteBatch(Image *image, int size, int usage); + SpriteBatch(Texture *texture, int size, int usage); virtual ~SpriteBatch(); int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1); @@ -68,33 +68,45 @@ public: void *lock(); void unlock(); - void setImage(Image *newimage); - Image *getImage(); + void setTexture(Texture *newtexture); + Texture *getTexture(); /** - * Set the current color for this SpriteBatch. The geometry added + * Set the current color for this SpriteBatch. The sprites added * after this call will use this color. Note that global color * will not longer apply to the SpriteBatch if this is used. * - * @param color The color to use for the following geometry. + * @param color The color to use for the following sprites. */ void setColor(const Color &color); /** - * Disable per-quad colors for this SpriteBatch. The next call to + * Disable per-sprite colors for this SpriteBatch. The next call to * draw will use the global color for all sprites. */ void setColor(); /** - * Returns whether the SpriteBatch is empty of sprites or not. + * Get the current color for this SpriteBatch. Returns NULL if no color is + * set. **/ - bool isEmpty() const; + const Color *getColor() const; /** - * Returns whether the amount of sprites has reached the buffer limit or not. + * Get the number of sprites currently in this SpriteBatch. **/ - bool isFull() const; + int getCount() const; + + /** + * Sets the total number of sprites this SpriteBatch can hold. + * Leaves existing sprite data intact when possible. + **/ + void setBufferSize(int newsize); + + /** + * Get the total number of sprites this SpriteBatch can hold. + **/ + int getBufferSize() const; // Implements Drawable. void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; @@ -104,7 +116,7 @@ public: private: - void addv(const vertex *v, int index); + void addv(const Vertex *v, int index); /** * Set the color for vertices. @@ -113,12 +125,9 @@ private: * of size 4. * @param color The color to assign to each vertex. */ - void setColorv(vertex *v, const Color &color); + void setColorv(Vertex *v, const Color &color); - static StringMap::Entry usageHintEntries[]; - static StringMap usageHints; - - Image *image; + Texture *texture; // Max number of sprites in the batch. int size; @@ -126,15 +135,18 @@ private: // The next free element. int next; - vertex sprite[4]; + Vertex sprite[4]; // Current color. This color, if present, will be applied to the next - // added quad. + // added sprite. Color *color; VertexBuffer *array_buf; VertexIndex *element_buf; + static StringMap::Entry usageHintEntries[]; + static StringMap usageHints; + }; // SpriteBatch } // opengl diff --git a/src/modules/graphics/opengl/Texture.h b/src/modules/graphics/opengl/Texture.h new file mode 100644 index 000000000..6dee55350 --- /dev/null +++ b/src/modules/graphics/opengl/Texture.h @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_GRAPHICS_OPENGL_TEXTURE_H +#define LOVE_GRAPHICS_OPENGL_TEXTURE_H + +// LOVE +#include "graphics/Texture.h" +#include "graphics/Volatile.h" +#include "OpenGL.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +class Texture : public love::graphics::Texture, public Volatile +{ +public: + + virtual ~Texture() {} + + /** + * Gets the OpenGL id for this texture. + **/ + virtual GLuint getGLTexture() const = 0; + + /** + * Any setup the texture might need to do before drawing, e.g. binding + * the OpenGL texture for use. + **/ + virtual void predraw() const {} + + /** + * Any cleanup the texture might need to do directly after drawing. + **/ + virtual void postdraw() const {} + + +}; // Texture + +} // opengl +} // graphics +} // love + +#endif // LOVE_GRAPHICS_OPENGL_TEXTURE_H diff --git a/src/modules/graphics/opengl/VertexBuffer.cpp b/src/modules/graphics/opengl/VertexBuffer.cpp index 877da1f82..181c0aea8 100644 --- a/src/modules/graphics/opengl/VertexBuffer.cpp +++ b/src/modules/graphics/opengl/VertexBuffer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -42,24 +42,27 @@ namespace opengl // VertexBuffer -VertexBuffer *VertexBuffer::Create(size_t size, GLenum target, GLenum usage) +VertexBuffer *VertexBuffer::Create(size_t size, GLenum target, GLenum usage, MemoryBacking backing) { try { // Try to create a VBO. - return new VBO(size, target, usage); + return new VBO(size, target, usage, backing); } catch(const love::Exception &) { // VBO not supported ... create regular array. - return new VertexArray(size, target, usage); + return new VertexArray(size, target, usage, backing); } } -VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage) - : size(size) +VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacking backing) + : is_bound(false) + , is_mapped(false) + , size(size) , target(target) , usage(usage) + , backing(backing) { } @@ -69,8 +72,8 @@ VertexBuffer::~VertexBuffer() // VertexArray -VertexArray::VertexArray(size_t size, GLenum target, GLenum usage) - : VertexBuffer(size, target, usage) +VertexArray::VertexArray(size_t size, GLenum target, GLenum usage, MemoryBacking backing) + : VertexBuffer(size, target, usage, backing) , buf(new char[size]) { } @@ -82,19 +85,23 @@ VertexArray::~VertexArray() void *VertexArray::map() { + is_mapped = true; return buf; } void VertexArray::unmap() { + is_mapped = false; } void VertexArray::bind() { + is_bound = true; } void VertexArray::unbind() { + is_bound = false; } void VertexArray::fill(size_t offset, size_t size, const void *data) @@ -109,20 +116,25 @@ const void *VertexArray::getPointer(size_t offset) const // VBO -VBO::VBO(size_t size, GLenum target, GLenum usage) - : VertexBuffer(size, target, usage) +VBO::VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing) + : VertexBuffer(size, target, usage, backing) , vbo(0) , memory_map(0) - , is_mapped(false) , is_dirty(true) { if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5)) throw love::Exception("Not supported"); + if (getMemoryBacking() == BACKING_FULL) + memory_map = malloc(getSize()); + bool ok = load(false); if (!ok) + { + free(memory_map); throw love::Exception("Could not load VBO."); + } } VBO::~VBO() @@ -147,10 +159,12 @@ void *VBO::map() } if (is_dirty) - glGetBufferSubDataARB(getTarget(), 0, getSize(), memory_map); + { + glGetBufferSubDataARB(getTarget(), 0, (GLsizeiptr) getSize(), memory_map); + is_dirty = false; + } is_mapped = true; - is_dirty = false; return memory_map; } @@ -160,41 +174,76 @@ void VBO::unmap() if (!is_mapped) return; - // "orphan" current buffer to avoid implicit synchronisation on the gpu: + // VBO::bind is a no-op when the VBO is mapped, so we have to make sure it's + // bound here. + if (!is_bound) + { + glBindBufferARB(getTarget(), vbo); + is_bound = true; + } + + // "orphan" current buffer to avoid implicit synchronisation on the GPU: // http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf - glBufferDataARB(getTarget(), getSize(), NULL, getUsage()); - glBufferDataARB(getTarget(), getSize(), memory_map, getUsage()); + glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), NULL, getUsage()); + glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), memory_map, getUsage()); + is_mapped = false; } void VBO::bind() { if (!is_mapped) + { glBindBufferARB(getTarget(), vbo); + is_bound = true; + } } void VBO::unbind() { - if (!is_mapped) + if (is_bound) glBindBufferARB(getTarget(), 0); + + is_bound = false; } void VBO::fill(size_t offset, size_t size, const void *data) { - if (is_mapped) - { + if (is_mapped || getMemoryBacking() == BACKING_FULL) memcpy(static_cast(memory_map) + offset, data, size); - } - else + + if (!is_mapped) { - glBufferSubDataARB(getTarget(), offset, size, data); - is_dirty = true; + // Not all systems have access to some faster paths... + if (GLEE_APPLE_flush_buffer_range) + { + void *mapdata = glMapBufferARB(getTarget(), GL_WRITE_ONLY); + + if (mapdata) + { + // We specified in VBO::load that we'll do manual flushing. + // Now we tell the driver it only needs to deal with the data + // we changed. + memcpy(static_cast(mapdata) + offset, data, size); + glFlushMappedBufferRangeAPPLE(getTarget(), (GLintptr) offset, (GLsizei) size); + } + + glUnmapBufferARB(getTarget()); + } + else + { + // Fall back to a possibly slower SubData (more chance of syncing.) + glBufferSubDataARB(getTarget(), (GLintptr) offset, (GLsizeiptr) size, data); + } + + if (getMemoryBacking() != BACKING_FULL) + is_dirty = true; } } const void *VBO::getPointer(size_t offset) const { - return reinterpret_cast(offset); + return BUFFER_OFFSET(offset); } bool VBO::loadVolatile() @@ -219,8 +268,14 @@ bool VBO::load(bool restore) while (GL_NO_ERROR != glGetError()) /* clear error messages */; + // We don't want to flush the entire buffer when we just modify a small + // portion of it (VBO::fill without VBO::map), so we'll handle the flushing + // ourselves when we can. + if (GLEE_APPLE_flush_buffer_range) + glBufferParameteriAPPLE(getTarget(), GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); + // Note that if 'src' is '0', no data will be copied. - glBufferDataARB(getTarget(), getSize(), src, getUsage()); + glBufferDataARB(getTarget(), (GLsizeiptr) getSize(), src, getUsage()); GLenum err = glGetError(); return (GL_NO_ERROR == err); @@ -228,16 +283,15 @@ bool VBO::load(bool restore) void VBO::unload(bool save) { - // Save data before unloading. - if (save) + // Save data before unloading, if we need to. + if (save && getMemoryBacking() == BACKING_PARTIAL) { VertexBuffer::Bind bind(*this); - GLint size; - glGetBufferParameterivARB(getTarget(), GL_BUFFER_SIZE, &size); + bool mapped = is_mapped; map(); // saves buffer content to memory_map. - unmap(); + is_mapped = mapped; } glDeleteBuffersARB(1, &vbo); diff --git a/src/modules/graphics/opengl/VertexBuffer.h b/src/modules/graphics/opengl/VertexBuffer.h index bb03b8c76..d29710cc4 100644 --- a/src/modules/graphics/opengl/VertexBuffer.h +++ b/src/modules/graphics/opengl/VertexBuffer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -48,6 +48,18 @@ class VertexBuffer { public: + // Different guarantees for VertexBuffer data storage. + enum MemoryBacking + { + // The VertexBuffer is will have a valid copy of its data in main memory + // at all times. + BACKING_FULL, + + // The VertexBuffer will have a valid copy of its data in main memory + // when it needs to be reloaded and when it's mapped. + BACKING_PARTIAL + }; + /** * Create a new VertexBuffer (either a plain vertex array, or a VBO), * based on what's supported on the system. @@ -58,9 +70,10 @@ public: * @param size The size of the VertexBuffer (in bytes). * @param target GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER. * @param usage GL_DYNAMIC_DRAW, etc. + * @param backing Determines what guarantees are placed on the data. * @return A new VertexBuffer. */ - static VertexBuffer *Create(size_t size, GLenum target, GLenum usage); + static VertexBuffer *Create(size_t size, GLenum target, GLenum usage, MemoryBacking backing = BACKING_PARTIAL); /** * Constructor. @@ -68,8 +81,9 @@ public: * @param size The size of the VertexBuffer in bytes. * @param target The target VertexBuffer object, e.g. GL_ARRAY_BUFFER. * @param usage Usage hint, e.g. GL_DYNAMIC_DRAW. + * @param backing Determines what guarantees are placed on the data. */ - VertexBuffer(size_t size, GLenum target, GLenum usage); + VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacking backing = BACKING_PARTIAL); /** * Destructor. Does nothing, but must be declared virtual. @@ -106,6 +120,21 @@ public: return usage; } + bool isBound() const + { + return is_bound; + } + + bool isMapped() const + { + return is_mapped; + } + + MemoryBacking getMemoryBacking() const + { + return backing; + } + /** * Map the VertexBuffer to client memory. * @@ -127,10 +156,8 @@ public: virtual void unmap() = 0; /** - * Bind the VertexBuffer to the specified target. - * (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER). - * - * @param target GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER. + * Bind the VertexBuffer to its specified target. + * (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, etc). */ virtual void bind() = 0; @@ -222,6 +249,14 @@ public: void *elems; }; +protected: + + // Whether the buffer is currently bound. + bool is_bound; + + // Whether the buffer is currently mapped to main memory. + bool is_mapped; + private: // The size of the buffer, in bytes. @@ -232,6 +267,9 @@ private: // Usage hint. GL_[DYNAMIC, STATIC, STREAM]_DRAW. GLenum usage; + + // + MemoryBacking backing; }; /** @@ -245,9 +283,9 @@ class VertexArray : public VertexBuffer public: /** - * @copydoc VertexBuffer(int, GLenum, GLenum) + * @copydoc VertexBuffer(int, GLenum, GLenum, Backing) */ - VertexArray(size_t size, GLenum target, GLenum usage); + VertexArray(size_t size, GLenum target, GLenum usage, MemoryBacking backing); /** * Frees the data we've allocated. @@ -273,19 +311,19 @@ private: * This will be used on all systems that support it. It's in general * faster than vertex arrays, but especially in use-cases where there * is no need to update the data every frame. - */ + **/ class VBO : public VertexBuffer, public Volatile { public: /** - * @copydoc VertexBuffer(size_t, GLenum, GLenum) - */ - VBO(size_t size, GLenum target, GLenum usage); + * @copydoc VertexBuffer(size_t, GLenum, GLenum, Backing) + **/ + VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing); /** * Deletes the VBOs from OpenGL. - */ + **/ virtual ~VBO(); // Implements VertexBuffer. @@ -324,10 +362,6 @@ private: // call to map(). void *memory_map; - // Set if the vbo currently operates on main instead of gpu - // memory. - bool is_mapped; - // Set if the buffer was modified while operating on gpu memory // and needs to be synchronized. bool is_dirty; diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index f9dab3ee4..4d5ab1282 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,7 +18,6 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "Graphics.h" #include "wrap_Canvas.h" namespace love @@ -44,10 +43,10 @@ int w_Canvas_renderTo(lua_State *L) } Canvas *canvas = luax_checkcanvas(L, 1); - if (!lua_isfunction(L, 2)) - return luaL_error(L, "Need a function to render to canvas."); + luaL_checktype(L, 2, LUA_TFUNCTION); + + EXCEPT_GUARD(canvas->startGrab();) - canvas->startGrab(); lua_settop(L, 2); // make sure the function is on top of the stack lua_call(L, 0, 0); canvas->stopGrab(); @@ -60,7 +59,7 @@ int w_Canvas_getImageData(lua_State *L) Canvas *canvas = luax_checkcanvas(L, 1); love::image::Image *image = luax_getmodule(L, "image", MODULE_IMAGE_T); love::image::ImageData *img = canvas->getImageData(image); - luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)img); + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, img); return 1; } @@ -70,14 +69,9 @@ int w_Canvas_getPixel(lua_State * L) int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); unsigned char c[4]; - try - { - canvas->getPixel(c, x, y); - } - catch (love::Exception & e) - { - return luaL_error(L, "%s", e.what()); - } + + EXCEPT_GUARD(canvas->getPixel(c, x, y);) + lua_pushnumber(L, c[0]); lua_pushnumber(L, c[1]); lua_pushnumber(L, c[2]); @@ -85,130 +79,38 @@ int w_Canvas_getPixel(lua_State * L) return 4; } -int w_Canvas_setFilter(lua_State *L) -{ - Canvas *canvas = luax_checkcanvas(L, 1); - - Image::Filter f; - - const char *minstr = luaL_checkstring(L, 2); - const char *magstr = luaL_optstring(L, 3, minstr); - - if (!Image::getConstant(minstr, f.min)) - return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, f.mag)) - return luaL_error(L, "Invalid filter mode: %s", magstr); - - canvas->setFilter(f); - - return 0; - -} - -int w_Canvas_getFilter(lua_State *L) -{ - Canvas *canvas = luax_checkcanvas(L, 1); - const Image::Filter f = canvas->getFilter(); - - const char *minstr; - const char *magstr; - Image::getConstant(f.min, minstr); - Image::getConstant(f.mag, magstr); - - lua_pushstring(L, minstr); - lua_pushstring(L, magstr); - - return 2; -} - -int w_Canvas_setWrap(lua_State *L) -{ - Canvas *canvas = luax_checkcanvas(L, 1); - - Image::Wrap w; - - const char *sstr = luaL_checkstring(L, 2); - const char *tstr = luaL_optstring(L, 3, sstr); - - if (!Image::getConstant(sstr, w.s)) - return luaL_error(L, "Invalid wrap mode: %s", sstr); - if (!Image::getConstant(tstr, w.t)) - return luaL_error(L, "Invalid wrap mode, %s", tstr); - - canvas->setWrap(w); - - return 0; -} - -int w_Canvas_getWrap(lua_State *L) -{ - Canvas *canvas = luax_checkcanvas(L, 1); - const Image::Wrap w = canvas->getWrap(); - - const char *wrap_s; - const char *wrap_t; - Image::getConstant(w.s, wrap_s); - Image::getConstant(w.t, wrap_t); - - lua_pushstring(L, wrap_s); - lua_pushstring(L, wrap_t); - - return 2; -} - int w_Canvas_clear(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); Color c; if (lua_isnoneornil(L, 2)) { - c.r = 0; - c.g = 0; - c.b = 0; - c.a = 0; + c.set(0, 0, 0, 0); } else if (lua_istable(L, 2)) { - lua_pushinteger(L, 1); - lua_gettable(L, 2); - c.r = (unsigned char)luaL_checkint(L, -1); - lua_pushinteger(L, 2); - lua_gettable(L, 2); - c.g = (unsigned char)luaL_checkint(L, -1); - lua_pushinteger(L, 3); - lua_gettable(L, 2); - c.b = (unsigned char)luaL_checkint(L, -1); - lua_pushinteger(L, 4); - lua_gettable(L, 2); - c.g = (unsigned char)luaL_optint(L, -1, 255); + for (int i = 1; i <= 4; i++) + lua_rawgeti(L, 2, i); + + c.r = (unsigned char)luaL_checkinteger(L, -4); + c.g = (unsigned char)luaL_checkinteger(L, -3); + c.b = (unsigned char)luaL_checkinteger(L, -2); + c.a = (unsigned char)luaL_optinteger(L, -1, 255); + lua_pop(L, 4); } else { - c.r = (unsigned char)luaL_checkint(L, 2); - c.g = (unsigned char)luaL_checkint(L, 3); - c.b = (unsigned char)luaL_checkint(L, 4); - c.a = (unsigned char)luaL_optint(L, 5, 255); + c.r = (unsigned char)luaL_checkinteger(L, 2); + c.g = (unsigned char)luaL_checkinteger(L, 3); + c.b = (unsigned char)luaL_checkinteger(L, 4); + c.a = (unsigned char)luaL_optinteger(L, 5, 255); } canvas->clear(c); return 0; } -int w_Canvas_getWidth(lua_State *L) -{ - Canvas *canvas = luax_checkcanvas(L, 1); - lua_pushnumber(L, canvas->getWidth()); - return 1; -} - -int w_Canvas_getHeight(lua_State *L) -{ - Canvas *canvas = luax_checkcanvas(L, 1); - lua_pushnumber(L, canvas->getHeight()); - return 1; -} - int w_Canvas_getType(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); @@ -221,16 +123,19 @@ int w_Canvas_getType(lua_State *L) static const luaL_Reg functions[] = { + // From wrap_Texture. + { "getWidth", w_Texture_getWidth }, + { "getHeight", w_Texture_getHeight }, + { "getDimensions", w_Texture_getDimensions }, + { "setFilter", w_Texture_setFilter }, + { "getFilter", w_Texture_getFilter }, + { "setWrap", w_Texture_setWrap }, + { "getWrap", w_Texture_getWrap }, + { "renderTo", w_Canvas_renderTo }, { "getImageData", w_Canvas_getImageData }, { "getPixel", w_Canvas_getPixel }, - { "setFilter", w_Canvas_setFilter }, - { "getFilter", w_Canvas_getFilter }, - { "setWrap", w_Canvas_setWrap }, - { "getWrap", w_Canvas_getWrap }, { "clear", w_Canvas_clear }, - { "getWidth", w_Canvas_getWidth }, - { "getHeight", w_Canvas_getHeight }, { "getType", w_Canvas_getType }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Canvas.h b/src/modules/graphics/opengl/wrap_Canvas.h index 2281fe713..4a6bea87b 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.h +++ b/src/modules/graphics/opengl/wrap_Canvas.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,6 +24,7 @@ // LOVE #include "common/runtime.h" #include "Canvas.h" +#include "wrap_Texture.h" namespace love { @@ -37,13 +38,7 @@ Canvas *luax_checkcanvas(lua_State *L, int idx); int w_Canvas_renderTo(lua_State *L); int w_Canvas_getImageData(lua_State *L); int w_Canvas_getPixel(lua_State * L); -int w_Canvas_setFilter(lua_State *L); -int w_Canvas_getFilter(lua_State *L); -int w_Canvas_setWrap(lua_State *L); -int w_Canvas_getWrap(lua_State *L); int w_Canvas_clear(lua_State *L); -int w_Canvas_getWidth(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); diff --git a/src/modules/graphics/opengl/wrap_Font.cpp b/src/modules/graphics/opengl/wrap_Font.cpp index fda13c776..e30fa12c2 100644 --- a/src/modules/graphics/opengl/wrap_Font.cpp +++ b/src/modules/graphics/opengl/wrap_Font.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -44,14 +44,8 @@ int w_Font_getWidth(lua_State *L) { Font *t = luax_checkfont(L, 1); const char *str = luaL_checkstring(L, 2); - try - { - lua_pushinteger(L, t->getWidth(str)); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } + + EXCEPT_GUARD(lua_pushinteger(L, t->getWidth(str));) return 1; } @@ -61,15 +55,12 @@ int w_Font_getWrap(lua_State *L) const char *str = luaL_checkstring(L, 2); float wrap = (float) luaL_checknumber(L, 3); int max_width = 0, numlines = 0; - try - { + + EXCEPT_GUARD( std::vector lines = t->getWrap(str, wrap, &max_width); numlines = lines.size(); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } + ) + lua_pushinteger(L, max_width); lua_pushinteger(L, numlines); return 2; @@ -93,39 +84,34 @@ int w_Font_getLineHeight(lua_State *L) int w_Font_setFilter(lua_State *L) { Font *t = luax_checkfont(L, 1); - Image::Filter f = t->getFilter(); + Texture::Filter f = t->getFilter(); const char *minstr = luaL_checkstring(L, 2); const char *magstr = luaL_optstring(L, 3, minstr); - if (!Image::getConstant(minstr, f.min)) + if (!Texture::getConstant(minstr, f.min)) return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, f.mag)) + if (!Texture::getConstant(magstr, f.mag)) return luaL_error(L, "Invalid filter mode: %s", magstr); - try - { - t->setFilter(f); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } + f.anisotropy = (float) luaL_optnumber(L, 4, 1.0); + EXCEPT_GUARD(t->setFilter(f);) return 0; } int w_Font_getFilter(lua_State *L) { Font *t = luax_checkfont(L, 1); - const Image::Filter f = t->getFilter(); + const Texture::Filter f = t->getFilter(); const char *minstr; const char *magstr; - Image::getConstant(f.min, minstr); - Image::getConstant(f.mag, magstr); + Texture::getConstant(f.min, minstr); + Texture::getConstant(f.mag, magstr); lua_pushstring(L, minstr); lua_pushstring(L, magstr); - return 2; + lua_pushnumber(L, f.anisotropy); + return 3; } int w_Font_getAscent(lua_State *L) @@ -149,6 +135,31 @@ int w_Font_getBaseline(lua_State *L) return 1; } +int w_Font_hasGlyphs(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + bool hasglyph = false; + + int count = lua_gettop(L) - 1; + count = count < 1 ? 1 : count; + + EXCEPT_GUARD( + for (int i = 2; i < count + 2; i++) + { + if (lua_type(L, i) == LUA_TSTRING) + hasglyph = t->hasGlyphs(luax_checkstring(L, i)); + else + hasglyph = t->hasGlyph((uint32) luaL_checknumber(L, i)); + + if (!hasglyph) + break; + } + ) + + luax_pushboolean(L, hasglyph); + return 1; +} + static const luaL_Reg functions[] = { { "getHeight", w_Font_getHeight }, @@ -161,6 +172,7 @@ static const luaL_Reg functions[] = { "getAscent", w_Font_getAscent }, { "getDescent", w_Font_getDescent }, { "getBaseline", w_Font_getBaseline }, + { "hasGlyphs", w_Font_hasGlyphs }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Font.h b/src/modules/graphics/opengl/wrap_Font.h index 3482baf7f..067e222f5 100644 --- a/src/modules/graphics/opengl/wrap_Font.h +++ b/src/modules/graphics/opengl/wrap_Font.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -43,6 +43,7 @@ int w_Font_getFilter(lua_State *L); int w_Font_getAscent(lua_State *L); int w_Font_getDescent(lua_State *L); int w_Font_getBaseline(lua_State *L); +int w_Font_hasGlyphs(lua_State *L); extern "C" int luaopen_font(lua_State *L); } // opengl diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 3d4e639dd..4ceda2c31 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -20,15 +20,13 @@ #include "wrap_Graphics.h" #include "OpenGL.h" -#include "graphics/DrawQable.h" +#include "graphics/Texture.h" #include "image/ImageData.h" #include "font/Rasterizer.h" #include "scripts/graphics.lua.h" #include -using love::window::WindowFlags; - namespace love { namespace graphics @@ -36,102 +34,7 @@ namespace graphics namespace opengl { -static Graphics *instance = 0; - -bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue) -{ - lua_getfield(L, table_index, key); - - bool retval; - if (lua_isnoneornil(L, -1)) - retval = defaultValue; - else - retval = lua_toboolean(L, -1); - - lua_pop(L, 1); - return retval; -} - -int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue) -{ - lua_getfield(L, table_index, key); - - int retval; - if (!lua_isnumber(L, -1)) - retval = defaultValue; - else - retval = lua_tonumber(L, -1); - - lua_pop(L, 1); - return retval; -} - -int w_checkMode(lua_State *L) -{ - int w = luaL_checkint(L, 1); - int h = luaL_checkint(L, 2); - bool fs = luax_toboolean(L, 3); - luax_pushboolean(L, instance->checkMode(w, h, fs)); - return 1; -} - -int w_setMode(lua_State *L) -{ - int w = luaL_checkint(L, 1); - int h = luaL_checkint(L, 2); - if (lua_isnoneornil(L, 3)) - { - luax_pushboolean(L, instance->setMode(w, h, 0)); - return 1; - } - - luaL_checktype(L, 3, LUA_TTABLE); - - WindowFlags flags; - - flags.fullscreen = luax_boolflag(L, 3, "fullscreen", false); - flags.vsync = luax_boolflag(L, 3, "vsync", true); - flags.fsaa = luax_intflag(L, 3, "fsaa", 0); - flags.resizable = luax_boolflag(L, 3, "resizable", false); - flags.borderless = luax_boolflag(L, 3, "borderless", false); - - luax_pushboolean(L, instance->setMode(w, h, &flags)); - return 1; -} - -int w_getMode(lua_State *L) -{ - int w, h; - WindowFlags flags; - instance->getMode(w, h, flags); - lua_pushnumber(L, w); - lua_pushnumber(L, h); - - lua_newtable(L); - - luax_pushboolean(L, flags.fullscreen); - lua_setfield(L, -2, "fullscreen"); - - luax_pushboolean(L, flags.vsync); - lua_setfield(L, -2, "vsync"); - - lua_pushnumber(L, flags.fsaa); - lua_setfield(L, -2, "fsaa"); - - luax_pushboolean(L, flags.resizable); - lua_setfield(L, -2, "resizable"); - - luax_pushboolean(L, flags.borderless); - lua_setfield(L, -2, "borderless"); - - return 3; -} - -int w_toggleFullscreen(lua_State *L) -{ - luax_pushboolean(L, instance->toggleFullscreen()); - return 1; -} +static Graphics *instance = nullptr; int w_reset(lua_State *) { @@ -151,51 +54,37 @@ int w_present(lua_State *) return 0; } -int w_setIcon(lua_State *L) -{ - Image *image = luax_checktype(L, 1, "Image", GRAPHICS_IMAGE_T); - instance->setIcon(image); - return 0; -} - -int w_setCaption(lua_State *L) -{ - const char *str = luaL_checkstring(L, 1); - instance->setCaption(str); - return 0; -} - -int w_getCaption(lua_State *L) -{ - return instance->getCaption(L); -} - -int w_getWidth(lua_State *L) -{ - lua_pushnumber(L, instance->getWidth()); - return 1; -} - -int w_getHeight(lua_State *L) -{ - lua_pushnumber(L, instance->getHeight()); - return 1; -} - int w_isCreated(lua_State *L) { luax_pushboolean(L, instance->isCreated()); return 1; } -int w_getModes(lua_State *L) +int w_getWidth(lua_State *L) { - return instance->getModes(L); + lua_pushinteger(L, instance->getWidth()); + return 1; +} + +int w_getHeight(lua_State *L) +{ + lua_pushinteger(L, instance->getHeight()); + return 1; +} + +int w_getDimensions(lua_State *L) +{ + lua_pushinteger(L, instance->getWidth()); + lua_pushinteger(L, instance->getHeight()); + return 2; } int w_setScissor(lua_State *L) { - if (lua_gettop(L) == 0) + int nargs = lua_gettop(L); + + if (nargs == 0 || (nargs == 4 && lua_isnil(L, 1) && lua_isnil(L, 2) + && lua_isnil(L, 3) && lua_isnil(L, 4))) { instance->setScissor(); return 0; @@ -215,32 +104,31 @@ int w_setScissor(lua_State *L) int w_getScissor(lua_State *L) { - return instance->getScissor(L); -} + int x, y, w, h; + if (!instance->getScissor(x, y, w, h)) + return 0; -int w_newStencil(lua_State *L) -{ - // just return the function - if (!lua_isfunction(L, 1)) - return luaL_typerror(L, 1, "function"); - lua_settop(L, 1); - return 1; + lua_pushinteger(L, x); + lua_pushinteger(L, y); + lua_pushinteger(L, w); + lua_pushinteger(L, h); + + return 4; } static int setStencil(lua_State *L, bool invert) { - // no argument -> clear mask + // no argument -> clear stencil if (lua_isnoneornil(L, 1)) { instance->discardStencil(); return 0; } - if (!lua_isfunction(L, 1)) - return luaL_typerror(L, 1, "mask"); + luaL_checktype(L, 1, LUA_TFUNCTION); instance->defineStencil(); - lua_call(L, lua_gettop(L) - 1, 0); // call mask(...) + lua_call(L, lua_gettop(L) - 1, 0); // call stencil(...) instance->useStencil(invert); return 0; @@ -256,210 +144,176 @@ int w_setInvertedStencil(lua_State *L) return setStencil(L, true); } +int w_getMaxTextureSize(lua_State *L) +{ + lua_pushinteger(L, instance->getMaxTextureSize()); + return 1; +} + int w_newImage(lua_State *L) { - // Convert to File, if necessary. - if (lua_isstring(L, 1)) - luax_convobj(L, 1, "filesystem", "newFile"); + love::image::ImageData *data = 0; + love::image::CompressedData *cdata = 0; - // Convert to ImageData, if necessary. - if (luax_istype(L, 1, FILESYSTEM_FILE_T)) - luax_convobj(L, 1, "image", "newImageData"); + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); - love::image::ImageData *data = luax_checktype(L, 1, "ImageData", IMAGE_IMAGE_DATA_T); + // Convert to ImageData/CompressedData, if necessary. + if (luax_istype(L, 1, FILESYSTEM_FILE_DATA_T)) + { + // Determine whether to convert to ImageData or CompressedData. + luax_getfunction(L, "image", "isCompressed"); + lua_pushvalue(L, 1); + lua_call(L, 1, 1); + + bool compressed = luax_toboolean(L, -1); + lua_pop(L, 1); + + if (compressed) + luax_convobj(L, 1, "image", "newCompressedData"); + else + luax_convobj(L, 1, "image", "newImageData"); + } + + if (luax_istype(L, 1, IMAGE_COMPRESSED_DATA_T)) + cdata = luax_checktype(L, 1, "CompressedData", IMAGE_COMPRESSED_DATA_T); + else + data = luax_checktype(L, 1, "ImageData", IMAGE_IMAGE_DATA_T); + + if (!data && !cdata) + return luaL_error(L, "Error creating image."); // Create the image. Image *image = 0; - try - { - image = instance->newImage(data); - } - catch(love::Exception &e) - { - luaL_error(L, e.what()); - } + EXCEPT_GUARD( + if (cdata) + image = instance->newImage(cdata); + else if (data) + image = instance->newImage(data); + ) if (image == 0) return luaL_error(L, "Could not load image."); - // Push the type. - luax_newtype(L, "Image", GRAPHICS_IMAGE_T, (void *)image); - + luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, image); return 1; } int w_newQuad(lua_State *L) { - float x = (float) luaL_checknumber(L, 1); - float y = (float) luaL_checknumber(L, 2); - float w = (float) luaL_checknumber(L, 3); - float h = (float) luaL_checknumber(L, 4); + Quad::Viewport v; + v.x = (float) luaL_checknumber(L, 1); + v.y = (float) luaL_checknumber(L, 2); + v.w = (float) luaL_checknumber(L, 3); + v.h = (float) luaL_checknumber(L, 4); + float sw = (float) luaL_checknumber(L, 5); float sh = (float) luaL_checknumber(L, 6); - Quad *frame = instance->newQuad(x, y, w, h, sw, sh); - - if (frame == 0) - return luaL_error(L, "Could not create frame."); - - luax_newtype(L, "Quad", GRAPHICS_QUAD_T, (void *)frame); + Quad *quad = instance->newQuad(v, sw, sh); + luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad); return 1; } int w_newFont(lua_State *L) { - Data *font_data = NULL; - // Convert to File, if necessary. - if (lua_isstring(L, 1)) - luax_convobj(L, 1, "filesystem", "newFile"); - - // Convert to Data, if necessary. - if (luax_istype(L, 1, FILESYSTEM_FILE_T)) - { - love::filesystem::File *f = luax_checktype(L, 1, "File", FILESYSTEM_FILE_T); - try - { - font_data = f->read(); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } - lua_remove(L, 1); // get rid of the file - luax_newtype(L, "Data", DATA_T, (void *)font_data); - lua_insert(L, 1); // put it at the bottom of the stack - } + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); // Convert to Rasterizer, if necessary. - if (luax_istype(L, 1, DATA_T)) + if (luax_istype(L, 1, FILESYSTEM_FILE_DATA_T)) { int idxs[] = {1, 2}; - int ret = luax_pconvobj(L, idxs, 2, "font", "newRasterizer"); - if (ret != 0) - { - font_data->release(); - return lua_error(L); - } + luax_convobj(L, idxs, 2, "font", "newRasterizer"); } - if (font_data) - font_data->release(); - love::font::Rasterizer *rasterizer = luax_checktype(L, 1, "Rasterizer", FONT_RASTERIZER_T); - Font *font = NULL; - try - { - // Create the font. - font = instance->newFont(rasterizer, instance->getDefaultImageFilter()); - } - catch (love::Exception &e) - { - return luaL_error(L, e.what()); - } + Font *font = 0; + EXCEPT_GUARD(font = instance->newFont(rasterizer, instance->getDefaultFilter());) if (font == 0) return luaL_error(L, "Could not load font."); // Push the type. - luax_newtype(L, "Font", GRAPHICS_FONT_T, (void *)font); - + luax_pushtype(L, "Font", GRAPHICS_FONT_T, font); return 1; } int w_newImageFont(lua_State *L) { - // filter for glyphs, defaults to linear/linear - Image::Filter img_filter; - bool setFilter = false; - - // For the filter modes.. - int startIndex = 2; + // filter for glyphs + Texture::Filter filter = instance->getDefaultFilter(); // 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, FILESYSTEM_FILE_DATA_T)) luax_convobj(L, 1, "image", "newImageData"); else if (luax_istype(L, 1, GRAPHICS_IMAGE_T)) { Image *i = luax_checktype(L, 1, "Image", GRAPHICS_IMAGE_T); - img_filter = i->getFilter(); - setFilter = true; - love::image::ImageData *id = i->getData(); - luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)id, false); + filter = i->getFilter(); + love::image::ImageData *id = i->getImageData(); + if (!id) + return luaL_argerror(L, 1, "Image cannot be compressed."); + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, id, false); lua_replace(L, 1); } // Convert to Rasterizer if necessary. if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T)) { + luaL_checkstring(L, 2); int idxs[] = {1, 2}; luax_convobj(L, idxs, 2, "font", "newRasterizer"); - startIndex = 3; // There's a glyphs args in there, move up } love::font::Rasterizer *rasterizer = luax_checktype(L, 1, "Rasterizer", FONT_RASTERIZER_T); - if (lua_isstring(L, startIndex) && lua_isstring(L, startIndex+1)) - { - Image::FilterMode min; - Image::FilterMode mag; - const char *minstr = luaL_checkstring(L, startIndex); - const char *magstr = luaL_checkstring(L, startIndex+1); - if (!Image::getConstant(minstr, min)) - return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, mag)) - return luaL_error(L, "Invalid filter mode: %s", magstr); - - img_filter.min = min; - img_filter.mag = mag; - setFilter = true; - } - - if (!setFilter) - img_filter = instance->getDefaultImageFilter(); - // Create the font. - Font *font = instance->newFont(rasterizer, img_filter); + Font *font = instance->newFont(rasterizer, filter); if (font == 0) return luaL_error(L, "Could not load font."); // Push the type. - luax_newtype(L, "Font", GRAPHICS_FONT_T, (void *)font); + luax_pushtype(L, "Font", GRAPHICS_FONT_T, font); return 1; } int w_newSpriteBatch(lua_State *L) { - Image *image = luax_checktype(L, 1, "Image", GRAPHICS_IMAGE_T); + Texture *texture = luax_checktexture(L, 1); int size = luaL_optint(L, 2, 1000); SpriteBatch::UsageHint usage = SpriteBatch::USAGE_DYNAMIC; if (lua_gettop(L) > 2) { - if (!SpriteBatch::getConstant(luaL_checkstring(L, 3), usage)) - usage = SpriteBatch::USAGE_DYNAMIC; + const char *usagestr = luaL_checkstring(L, 3); + if (!SpriteBatch::getConstant(usagestr, usage)) + return luaL_error(L, "Invalid SpriteBatch usage hint: %s", usagestr); } - SpriteBatch *t = NULL; - try - { - t = instance->newSpriteBatch(image, size, usage); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } - luax_newtype(L, "SpriteBatch", GRAPHICS_SPRITE_BATCH_T, (void *)t); + + SpriteBatch *t = nullptr; + EXCEPT_GUARD(t = instance->newSpriteBatch(texture, size, usage);) + + luax_pushtype(L, "SpriteBatch", GRAPHICS_SPRITE_BATCH_T, t); return 1; } int w_newParticleSystem(lua_State *L) { - Image *image = luax_checktype(L, 1, "Image", GRAPHICS_IMAGE_T); - int size = luaL_checkint(L, 2); - ParticleSystem *t = instance->newParticleSystem(image, size); - luax_newtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, (void *)t); + Texture *texture = luax_checktexture(L, 1); + lua_Number size = luaL_optnumber(L, 2, 1000); + ParticleSystem *t = 0; + if (size < 1.0 || size > ParticleSystem::MAX_PARTICLES) + return luaL_error(L, "Invalid ParticleSystem size"); + + EXCEPT_GUARD(t = instance->newParticleSystem(texture, int(size));) + + luax_pushtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, t); return 1; } @@ -474,20 +328,13 @@ int w_newCanvas(lua_State *L) if (!Canvas::getConstant(str, texture_type)) return luaL_error(L, "Invalid canvas type: %s", str); - Canvas *canvas = NULL; - try - { - canvas = instance->newCanvas(width, height, texture_type); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + Canvas *canvas = 0; + EXCEPT_GUARD(canvas = instance->newCanvas(width, height, texture_type);) - if (NULL == canvas) + if (canvas == 0) return luaL_error(L, "Canvas not created, but no error thrown. I don't even..."); - luax_newtype(L, "Canvas", GRAPHICS_CANVAS_T, (void *)canvas); + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas); return 1; } @@ -496,49 +343,166 @@ int w_newShader(lua_State *L) if (!Shader::isSupported()) return luaL_error(L, "Sorry, your graphics card does not support shaders."); + // clamp stack to 2 elements + lua_settop(L, 2); + + // read any filepath arguments + for (int i = 1; i <= 2; i++) + { + if (!lua_isstring(L, i)) + continue; + + // call love.filesystem.isFile(arg_i) + luax_getfunction(L, "filesystem", "isFile"); + lua_pushvalue(L, i); + lua_call(L, 1, 1); + + bool isFile = luax_toboolean(L, -1); + lua_pop(L, 1); + + if (isFile) + { + luax_getfunction(L, "filesystem", "read"); + lua_pushvalue(L, i); + lua_call(L, 1, 1); + lua_replace(L, i); + } + } + + bool has_arg1 = lua_isstring(L, 1); + bool has_arg2 = lua_isstring(L, 2); + + // require at least one string argument + if (!(has_arg1 || has_arg2)) + luaL_checkstring(L, 1); + + luax_getfunction(L, "graphics", "_shaderCodeToGLSL"); + + // push vertexcode and pixelcode strings to the top of the stack + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); + + // call effectCodeToGLSL, returned values will be at the top of the stack + if (lua_pcall(L, 2, 2, 0) != 0) + return luaL_error(L, "%s", lua_tostring(L, -1)); + + Shader::ShaderSources sources; + + // vertex shader code + if (lua_isstring(L, -2)) + { + std::string vertexcode(luaL_checkstring(L, -2)); + sources[Shader::TYPE_VERTEX] = vertexcode; + } + else if (has_arg1 && has_arg2) + return luaL_error(L, "Could not parse vertex shader code (missing 'position' function?)"); + + // pixel shader code + if (lua_isstring(L, -1)) + { + std::string pixelcode(luaL_checkstring(L, -1)); + sources[Shader::TYPE_PIXEL] = pixelcode; + } + else if (has_arg1 && has_arg2) + return luaL_error(L, "Could not parse pixel shader code (missing 'effect' function?)"); + + if (sources.empty()) + { + // Original args had source code, but effectCodeToGLSL couldn't translate it + for (int i = 1; i <= 2; i++) + { + if (lua_isstring(L, i)) + return luaL_argerror(L, i, "missing 'position' or 'effect' function?"); + } + } + + bool should_error = false; try { - // clamp stack to 2 elements - lua_settop(L, 2); - - luax_getfunction(L, "graphics", "_effectCodeToGLSL"); - - // push vertcode and fragcode strings to the top of the stack so they become arguments for the function - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - - // call effectCodeToGLSL, returned values will be at the top of the stack - lua_pcall(L, 2, 2, 0); - - Shader::ShaderSources sources; - - // vertex shader code - if (lua_isstring(L, -2)) - { - std::string vertcode(luaL_checkstring(L, -2)); - sources[Shader::TYPE_VERTEX] = vertcode; - } - - // fragment shader code - if (lua_isstring(L, -1)) - { - std::string fragcode(luaL_checkstring(L, -1)); - sources[Shader::TYPE_FRAGMENT] = fragcode; - } - Shader *shader = instance->newShader(sources); - luax_newtype(L, "Shader", GRAPHICS_SHADER_T, (void *)shader); + luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader); } - catch(const love::Exception &e) + catch (love::Exception &e) { - // memory is freed in Graphics::newShader luax_getfunction(L, "graphics", "_transformGLSLErrorMessages"); lua_pushstring(L, e.what()); + + // Function pushes the new error string onto the stack. lua_pcall(L, 1, 1, 0); - const char *err = lua_tostring(L, -1); - return luaL_error(L, "%s", err); + should_error = true; } + if (should_error) + return lua_error(L); + + return 1; +} + +int w_newMesh(lua_State *L) +{ + // Check first argument: mandatory table of vertices. + luaL_checktype(L, 1, LUA_TTABLE); + + // Second argument: optional texture. + Texture *tex = nullptr; + if (!lua_isnoneornil(L, 2)) + tex = luax_checktexture(L, 2); + + // Third argument: optional draw mode. + const char *str = 0; + Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN; + str = lua_isnoneornil(L, 3) ? 0 : luaL_checkstring(L, 3); + + if (str && !Mesh::getConstant(str, mode)) + return luaL_error(L, "Invalid mesh draw mode: %s", str); + + size_t vertex_count = lua_objlen(L, 1); + std::vector vertices; + vertices.reserve(vertex_count); + + bool use_colors = false; + + // Get the vertices from the table. + for (size_t i = 1; i <= vertex_count; i++) + { + lua_rawgeti(L, 1, i); + + if (lua_type(L, -1) != LUA_TTABLE) + return luax_typerror(L, 1, "table of tables"); + + for (int j = 1; j <= 8; j++) + lua_rawgeti(L, -j, j); + + Vertex v; + + v.x = (float) luaL_checknumber(L, -8); + v.y = (float) luaL_checknumber(L, -7); + + v.s = (float) luaL_checknumber(L, -6); + v.t = (float) luaL_checknumber(L, -5); + + v.r = (unsigned char) luaL_optinteger(L, -4, 255); + v.g = (unsigned char) luaL_optinteger(L, -3, 255); + v.b = (unsigned char) luaL_optinteger(L, -2, 255); + v.a = (unsigned char) luaL_optinteger(L, -1, 255); + + // Enable per-vertex coloring if any color is not the default. + if (!use_colors && (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255)) + use_colors = true; + + lua_pop(L, 9); + vertices.push_back(v); + } + + Mesh *t = nullptr; + EXCEPT_GUARD(t = instance->newMesh(vertices, mode);) + + if (tex) + t->setTexture(tex); + + t->setVertexColors(use_colors); + + luax_pushtype(L, "Mesh", GRAPHICS_MESH_T, t); return 1; } @@ -547,22 +511,15 @@ int w_setColor(lua_State *L) Color c; if (lua_istable(L, 1)) { - lua_pushinteger(L, 1); - lua_gettable(L, -2); - c.r = (unsigned char)luaL_checkint(L, -1); - lua_pop(L, 1); - lua_pushinteger(L, 2); - lua_gettable(L, -2); - c.g = (unsigned char)luaL_checkint(L, -1); - lua_pop(L, 1); - lua_pushinteger(L, 3); - lua_gettable(L, -2); - c.b = (unsigned char)luaL_checkint(L, -1); - lua_pop(L, 1); - lua_pushinteger(L, 4); - lua_gettable(L, -2); + for (int i = 1; i <= 4; i++) + lua_rawgeti(L, 1, i); + + c.r = (unsigned char)luaL_checkint(L, -4); + c.g = (unsigned char)luaL_checkint(L, -3); + c.b = (unsigned char)luaL_checkint(L, -2); c.a = (unsigned char)luaL_optint(L, -1, 255); - lua_pop(L, 1); + + lua_pop(L, 4); } else { @@ -590,22 +547,15 @@ int w_setBackgroundColor(lua_State *L) Color c; if (lua_istable(L, 1)) { - lua_pushinteger(L, 1); - lua_gettable(L, -2); - c.r = (unsigned char)luaL_checkint(L, -1); - lua_pop(L, 1); - lua_pushinteger(L, 2); - lua_gettable(L, -2); - c.g = (unsigned char)luaL_checkint(L, -1); - lua_pop(L, 1); - lua_pushinteger(L, 3); - lua_gettable(L, -2); - c.b = (unsigned char)luaL_checkint(L, -1); - lua_pop(L, 1); - lua_pushinteger(L, 4); - lua_gettable(L, -2); + for (int i = 1; i <= 4; i++) + lua_rawgeti(L, 1, i); + + c.r = (unsigned char)luaL_checkint(L, -4); + c.g = (unsigned char)luaL_checkint(L, -3); + c.b = (unsigned char)luaL_checkint(L, -2); c.a = (unsigned char)luaL_optint(L, -1, 255); - lua_pop(L, 1); + + lua_pop(L, 4); } else { @@ -643,10 +593,41 @@ int w_getFont(lua_State *L) return 0; f->retain(); - luax_newtype(L, "Font", GRAPHICS_FONT_T, (void *)f); + luax_pushtype(L, "Font", GRAPHICS_FONT_T, f); return 1; } +int w_setColorMask(lua_State *L) +{ + bool mask[4]; + + if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) + { + // Enable all color components if no argument is given. + mask[0] = mask[1] = mask[2] = mask[3] = true; + } + else + { + for (int i = 0; i < 4; i++) + mask[i] = luax_toboolean(L, i + 1); + } + + // r, g, b, a + instance->setColorMask(mask[0], mask[1], mask[2], mask[3]); + + return 0; +} + +int w_getColorMask(lua_State *L) +{ + const bool *mask = instance->getColorMask(); + + for (int i = 0; i < 4; i++) + luax_pushboolean(L, mask[i]); + + return 4; +} + int w_setBlendMode(lua_State *L) { Graphics::BlendMode mode; @@ -654,88 +635,96 @@ int w_setBlendMode(lua_State *L) if (!Graphics::getConstant(str, mode)) return luaL_error(L, "Invalid blend mode: %s", str); - try - { - instance->setBlendMode(mode); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } - return 0; -} - -int w_setColorMode(lua_State *L) -{ - Graphics::ColorMode mode; - const char *str = luaL_checkstring(L, 1); - if (!Graphics::getConstant(str, mode)) - return luaL_error(L, "Invalid color mode: %s", str); - - instance->setColorMode(mode); - return 0; -} - -int w_setDefaultImageFilter(lua_State *L) -{ - Image::FilterMode min; - Image::FilterMode mag; - - const char *minstr = luaL_checkstring(L, 1); - const char *magstr = luaL_optstring(L, 2, minstr); - - if (!Image::getConstant(minstr, min)) - return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, mag)) - return luaL_error(L, "Invalid filter mode: %s", magstr); - - Image::Filter f; - f.min = min; - f.mag = mag; - - instance->setDefaultImageFilter(f); - + EXCEPT_GUARD(instance->setBlendMode(mode);) return 0; } int w_getBlendMode(lua_State *L) { - try - { - Graphics::BlendMode mode = instance->getBlendMode(); - const char *str; - if (!Graphics::getConstant(mode, str)) - return luaL_error(L, "Unknown blend mode"); - lua_pushstring(L, str); - return 1; - } - catch (love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } -} - -int w_getColorMode(lua_State *L) -{ - Graphics::ColorMode mode = instance->getColorMode(); const char *str; + Graphics::BlendMode mode; + + EXCEPT_GUARD(mode = instance->getBlendMode();) + if (!Graphics::getConstant(mode, str)) - return luaL_error(L, "Unknown color mode"); + return luaL_error(L, "Unknown blend mode"); + lua_pushstring(L, str); return 1; } -int w_getDefaultImageFilter(lua_State *L) +int w_setDefaultFilter(lua_State *L) { - const Image::Filter &f = instance->getDefaultImageFilter(); + Texture::FilterMode min; + Texture::FilterMode mag; + + const char *minstr = luaL_checkstring(L, 1); + const char *magstr = luaL_optstring(L, 2, minstr); + + if (!Texture::getConstant(minstr, min)) + return luaL_error(L, "Invalid filter mode: %s", minstr); + if (!Texture::getConstant(magstr, mag)) + return luaL_error(L, "Invalid filter mode: %s", magstr); + + float anisotropy = (float) luaL_optnumber(L, 3, 1.0); + + Texture::Filter f; + f.min = min; + f.mag = mag; + f.anisotropy = anisotropy; + + instance->setDefaultFilter(f); + + return 0; +} + +int w_getDefaultFilter(lua_State *L) +{ + const Texture::Filter &f = instance->getDefaultFilter(); const char *minstr; const char *magstr; - if (!Image::getConstant(f.min, minstr)) - return luaL_error(L, "Unknown filter mode for argument #1"); - if (!Image::getConstant(f.mag, magstr)) - return luaL_error(L, "Unknown filter mode for argument #2"); + if (!Texture::getConstant(f.min, minstr)) + return luaL_error(L, "Unknown minification filter mode"); + if (!Texture::getConstant(f.mag, magstr)) + return luaL_error(L, "Unknown magnification filter mode"); lua_pushstring(L, minstr); lua_pushstring(L, magstr); + lua_pushnumber(L, f.anisotropy); + return 3; +} + +int w_setDefaultMipmapFilter(lua_State *L) +{ + Texture::FilterMode filter = Texture::FILTER_NONE; + if (!lua_isnoneornil(L, 1)) + { + const char *str = luaL_checkstring(L, 1); + if (!Texture::getConstant(str, filter)) + return luaL_error(L, "Invalid filter mode: %s", str); + } + + float sharpness = (float) luaL_optnumber(L, 2, 0); + + instance->setDefaultMipmapFilter(filter, sharpness); + + return 0; +} + +int w_getDefaultMipmapFilter(lua_State *L) +{ + Texture::FilterMode filter; + float sharpness; + + instance->getDefaultMipmapFilter(&filter, &sharpness); + + const char *str; + if (Texture::getConstant(filter, str)) + lua_pushstring(L, str); + else + lua_pushnil(L); + + lua_pushnumber(L, sharpness); + return 2; } @@ -757,20 +746,14 @@ int w_setLineStyle(lua_State *L) return 0; } -int w_setLine(lua_State *L) +int w_setLineJoin(lua_State *L) { - float width = (float)luaL_checknumber(L, 1); + Graphics::LineJoin join; + const char *str = luaL_checkstring(L, 1); + if (!Graphics::getConstant(str, join)) + return luaL_error(L, "Invalid line join mode: %s", str); - Graphics::LineStyle style = Graphics::LINE_SMOOTH; - - if (lua_gettop(L) >= 2) - { - const char *str = luaL_checkstring(L, 2); - if (!Graphics::getConstant(str, style)) - return luaL_error(L, "Invalid line style: %s", str); - } - - instance->setLine(width, style); + instance->setLineJoin(join); return 0; } @@ -790,6 +773,16 @@ int w_getLineStyle(lua_State *L) return 1; } +int w_getLineJoin(lua_State *L) +{ + Graphics::LineJoin join = instance->getLineJoin(); + const char *str; + if (!Graphics::getConstant(join, str)) + return luaL_error(L, "Unknown line join"); + lua_pushstring(L, str); + return 1; +} + int w_setPointSize(lua_State *L) { float size = (float)luaL_checknumber(L, 1); @@ -809,23 +802,6 @@ int w_setPointStyle(lua_State *L) return 0; } -int w_setPoint(lua_State *L) -{ - float size = (float)luaL_checknumber(L, 1); - - Graphics::PointStyle style = Graphics::POINT_SMOOTH; - - if (lua_gettop(L) >= 2) - { - const char *str = luaL_checkstring(L, 2); - if (!Graphics::getConstant(str, style)) - return luaL_error(L, "Invalid point style: %s", str); - } - - instance->setPoint(size, style); - return 0; -} - int w_getPointSize(lua_State *L) { lua_pushnumber(L, instance->getPointSize()); @@ -851,8 +827,12 @@ int w_getMaxPointSize(lua_State *L) int w_newScreenshot(lua_State *L) { love::image::Image *image = luax_getmodule(L, "image", MODULE_IMAGE_T); - love::image::ImageData *i = instance->newScreenshot(image); - luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)i); + bool copyAlpha = luax_optboolean(L, 1, false); + love::image::ImageData *i = 0; + + EXCEPT_GUARD(i = instance->newScreenshot(image, copyAlpha);) + + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, i); return 1; } @@ -862,16 +842,44 @@ int w_setCanvas(lua_State *L) instance->discardStencil(); // called with none -> reset to default buffer - // nil is an error, to help people with typoes - if (lua_isnone(L,1)) + if (lua_isnoneornil(L,1)) { Canvas::bindDefaultCanvas(); return 0; } - Canvas *canvas = luax_checkcanvas(L, 1); - // this unbinds the previous fbo - canvas->startGrab(); + bool is_table = lua_istable(L, 1); + std::vector attachments; + + Canvas *canvas = 0; + + if (is_table) + { + // grab the first canvas in the array and attach the rest + lua_rawgeti(L, 1, 1); + canvas = luax_checkcanvas(L, -1); + lua_pop(L, 1); + + for (size_t i = 2; i <= lua_objlen(L, 1); i++) + { + lua_rawgeti(L, 1, i); + attachments.push_back(luax_checkcanvas(L, -1)); + lua_pop(L, 1); + } + } + else + { + canvas = luax_checkcanvas(L, 1); + for (int i = 2; i <= lua_gettop(L); i++) + attachments.push_back(luax_checkcanvas(L, i)); + } + + EXCEPT_GUARD( + if (attachments.size() > 0) + canvas->startGrab(attachments); + else + canvas->startGrab(); + ) return 0; } @@ -879,14 +887,25 @@ int w_setCanvas(lua_State *L) int w_getCanvas(lua_State *L) { Canvas *canvas = Canvas::current; + int n = 1; + if (canvas) { canvas->retain(); - luax_newtype(L, "Canvas", GRAPHICS_CANVAS_T, (void *) canvas); + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas); + + const std::vector &attachments = canvas->getAttachedCanvases(); + for (size_t i = 0; i < attachments.size(); i++) + { + attachments[i]->retain(); + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, attachments[i]); + n++; + } } else lua_pushnil(L); - return 1; + + return n; } int w_setShader(lua_State *L) @@ -908,7 +927,7 @@ int w_getShader(lua_State *L) if (shader) { shader->retain(); - luax_newtype(L, "Shader", GRAPHICS_SHADER_T, (void *) shader); + luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader); } else lua_pushnil(L); @@ -925,10 +944,8 @@ int w_isSupported(lua_State *L) { const char *str = luaL_checkstring(L, i); if (!Graphics::getConstant(str, support)) - { - supported = false; - break; - } + return luaL_error(L, "Invalid graphics feature: %s", str); + switch (support) { case Graphics::SUPPORT_CANVAS: @@ -936,7 +953,11 @@ int w_isSupported(lua_State *L) supported = false; break; case Graphics::SUPPORT_HDR_CANVAS: - if (!Canvas::isHdrSupported()) + if (!Canvas::isHDRSupported()) + supported = false; + break; + case Graphics::SUPPORT_MULTI_CANVAS: + if (!Canvas::isMultiCanvasSupported()) supported = false; break; case Graphics::SUPPORT_SHADER: @@ -955,6 +976,14 @@ int w_isSupported(lua_State *L) if (!Image::hasMipmapSupport()) supported = false; break; + case Graphics::SUPPORT_DXT: + if (!Image::hasCompressedTextureSupport(image::CompressedData::FORMAT_DXT5)) + supported = false; + break; + case Graphics::SUPPORT_BC5: + if (!Image::hasCompressedTextureSupport(image::CompressedData::FORMAT_BC5)) + supported = false; + break; default: supported = false; } @@ -965,72 +994,69 @@ int w_isSupported(lua_State *L) return 1; } -/** - * Draws an Image at the specified coordinates, with rotation and - * scaling along both axes. - * @param x The x-coordinate. - * @param y The y-coordinate. - * @param angle The amount of rotation. - * @param sx The scale factor along the x-axis. (1 = normal). - * @param sy The scale factor along the y-axis. (1 = normal). - * @param ox The offset along the x-axis. - * @param oy The offset along the y-axis. - * @param kx Shear along the x-axis. - * @param ky Shear along the y-axis. - **/ -int w_draw(lua_State *L) +int w_getRendererInfo(lua_State *L) { - Drawable *drawable = luax_checktype(L, 1, "Drawable", GRAPHICS_DRAWABLE_T); - float x = (float)luaL_optnumber(L, 2, 0.0f); - float y = (float)luaL_optnumber(L, 3, 0.0f); - float angle = (float)luaL_optnumber(L, 4, 0.0f); - float sx = (float)luaL_optnumber(L, 5, 1.0f); - float sy = (float)luaL_optnumber(L, 6, sx); - float ox = (float)luaL_optnumber(L, 7, 0); - float oy = (float)luaL_optnumber(L, 8, 0); - float kx = (float)luaL_optnumber(L, 9, 0); - float ky = (float)luaL_optnumber(L, 10, 0); - drawable->draw(x, y, angle, sx, sy, ox, oy, kx, ky); - return 0; + std::string name, version, vendor, device; + + EXCEPT_GUARD(name = instance->getRendererInfo(Graphics::RENDERER_INFO_NAME);) + EXCEPT_GUARD(version = instance->getRendererInfo(Graphics::RENDERER_INFO_VERSION);) + EXCEPT_GUARD(vendor = instance->getRendererInfo(Graphics::RENDERER_INFO_VENDOR);) + EXCEPT_GUARD(device = instance->getRendererInfo(Graphics::RENDERER_INFO_DEVICE);) + + luax_pushstring(L, name); + luax_pushstring(L, version); + luax_pushstring(L, vendor); + luax_pushstring(L, device); + + return 4; } -/** - * Draws an Quad of a DrawQable at the specified coordinates, - * with rotation and scaling along both axes. - * - * @param q The Quad to draw. - * @param x The x-coordinate. - * @param y The y-coordinate. - * @param angle The amount of rotation. - * @param sx The scale factor along the x-axis. (1 = normal). - * @param sy The scale factor along the y-axis. (1 = normal). - * @param ox The offset along the x-axis. - * @param oy The offset along the y-axis. - * @param kx Shear along the x-axis. - * @param ky Shear along the y-axis. - **/ -int w_drawq(lua_State *L) +int w_draw(lua_State *L) { - DrawQable *dq = luax_checktype(L, 1, "DrawQable", GRAPHICS_DRAWQABLE_T); - Quad *q = luax_checkframe(L, 2); - float x = (float)luaL_checknumber(L, 3); - float y = (float)luaL_checknumber(L, 4); - float angle = (float)luaL_optnumber(L, 5, 0); - float sx = (float)luaL_optnumber(L, 6, 1); - float sy = (float)luaL_optnumber(L, 7, sx); - float ox = (float)luaL_optnumber(L, 8, 0); - float oy = (float)luaL_optnumber(L, 9, 0); - float kx = (float)luaL_optnumber(L, 10, 0); - float ky = (float)luaL_optnumber(L, 11, 0); - dq->drawq(q, x, y, angle, sx, sy, ox, oy, kx, ky); + Drawable *drawable = nullptr; + Texture *texture = nullptr; + Quad *quad = nullptr; + int startidx = 2; + + if (luax_istype(L, 2, GRAPHICS_QUAD_T)) + { + texture = luax_checktexture(L, 1); + quad = luax_totype(L, 2, "Quad", GRAPHICS_QUAD_T); + startidx = 3; + } + else if (lua_isnil(L, 2) && !lua_isnoneornil(L, 3)) + { + return luax_typerror(L, 2, "Quad"); + } + else + { + drawable = luax_checktype(L, 1, "Drawable", GRAPHICS_DRAWABLE_T); + startidx = 2; + } + + float x = (float) luaL_optnumber(L, startidx + 0, 0.0); + float y = (float) luaL_optnumber(L, startidx + 1, 0.0); + float a = (float) luaL_optnumber(L, startidx + 2, 0.0); + float sx = (float) luaL_optnumber(L, startidx + 3, 1.0); + float sy = (float) luaL_optnumber(L, startidx + 4, sx); + float ox = (float) luaL_optnumber(L, startidx + 5, 0.0); + float oy = (float) luaL_optnumber(L, startidx + 6, 0.0); + float kx = (float) luaL_optnumber(L, startidx + 7, 0.0); + float ky = (float) luaL_optnumber(L, startidx + 8, 0.0); + + if (texture && quad) + texture->drawq(quad, x, y, a, sx, sy, ox, oy, kx, ky); + else if (drawable) + drawable->draw(x, y, a, sx, sy, ox, oy, kx, ky); + return 0; } int w_print(lua_State *L) { - const char *str = luaL_checkstring(L, 1); - float x = (float)luaL_checknumber(L, 2); - float y = (float)luaL_checknumber(L, 3); + std::string str = luax_checkstring(L, 1); + float x = (float)luaL_optnumber(L, 2, 0.0); + float y = (float)luaL_optnumber(L, 3, 0.0); float angle = (float)luaL_optnumber(L, 4, 0.0f); float sx = (float)luaL_optnumber(L, 5, 1.0f); float sy = (float)luaL_optnumber(L, 6, sx); @@ -1038,41 +1064,44 @@ int w_print(lua_State *L) float oy = (float)luaL_optnumber(L, 8, 0.0f); float kx = (float)luaL_optnumber(L, 9, 0.0f); float ky = (float)luaL_optnumber(L, 10, 0.0f); - try - { - instance->print(str, x, y, angle, sx, sy, ox, oy, kx,ky); - } - catch(love::Exception e) - { - return luaL_error(L, "Decoding error: %s", e.what()); - } + + EXCEPT_GUARD(instance->print(str, x, y, angle, sx, sy, ox, oy, kx,ky);) return 0; } int w_printf(lua_State *L) { - const char *str = luaL_checkstring(L, 1); + std::string str = luax_checkstring(L, 1); float x = (float)luaL_checknumber(L, 2); float y = (float)luaL_checknumber(L, 3); float wrap = (float)luaL_checknumber(L, 4); + float angle = 0.0f; + float sx = 1.0f, sy = 1.0f; + float ox = 0.0f, oy = 0.0f; + float kx = 0.0f, ky = 0.0f; + Graphics::AlignMode align = Graphics::ALIGN_LEFT; if (lua_gettop(L) >= 5) { - const char *str = luaL_checkstring(L, 5); - if (!Graphics::getConstant(str, align)) - return luaL_error(L, "Incorrect alignment: %s", str); + if (!lua_isnil(L, 5)) + { + const char *str = luaL_checkstring(L, 5); + if (!Graphics::getConstant(str, align)) + return luaL_error(L, "Incorrect alignment: %s", str); + } + + angle = (float) luaL_optnumber(L, 6, 0.0f); + sx = (float) luaL_optnumber(L, 7, 1.0f); + sy = (float) luaL_optnumber(L, 8, sx); + ox = (float) luaL_optnumber(L, 9, 0.0f); + oy = (float) luaL_optnumber(L, 10, 0.0f); + kx = (float) luaL_optnumber(L, 11, 0.0f); + ky = (float) luaL_optnumber(L, 12, 0.0f); } - try - { - instance->printf(str, x, y, wrap, align); - } - catch(love::Exception e) - { - return luaL_error(L, "Decoding error: %s", e.what()); - } + EXCEPT_GUARD(instance->printf(str, x, y, wrap, align, angle, sx, sy, ox, oy, kx, ky);) return 0; } @@ -1103,8 +1132,7 @@ int w_line(lua_State *L) { for (int i = 0; i < args; ++i) { - lua_pushnumber(L, i + 1); - lua_rawget(L, 1); + lua_rawgeti(L, 1, i + 1); coords[i] = luax_tofloat(L, -1); lua_pop(L, 1); } @@ -1121,23 +1149,6 @@ int w_line(lua_State *L) return 0; } -int w_triangle(lua_State *L) -{ - Graphics::DrawMode mode; - const char *str = luaL_checkstring(L, 1); - if (!Graphics::getConstant(str, mode)) - return luaL_error(L, "Incorrect draw mode %s", str); - - float x1 = (float)luaL_checknumber(L, 2); - float y1 = (float)luaL_checknumber(L, 3); - float x2 = (float)luaL_checknumber(L, 4); - float y2 = (float)luaL_checknumber(L, 5); - float x3 = (float)luaL_checknumber(L, 6); - float y3 = (float)luaL_checknumber(L, 7); - instance->triangle(mode, x1, y1, x2, y2, x3, y3); - return 0; -} - int w_rectangle(lua_State *L) { Graphics::DrawMode mode; @@ -1153,25 +1164,6 @@ int w_rectangle(lua_State *L) return 0; } -int w_quad(lua_State *L) -{ - Graphics::DrawMode mode; - const char *str = luaL_checkstring(L, 1); - if (!Graphics::getConstant(str, mode)) - return luaL_error(L, "Incorrect draw mode %s", str); - - float x1 = (float)luaL_checknumber(L, 2); - float y1 = (float)luaL_checknumber(L, 3); - float x2 = (float)luaL_checknumber(L, 4); - float y2 = (float)luaL_checknumber(L, 5); - float x3 = (float)luaL_checknumber(L, 6); - float y3 = (float)luaL_checknumber(L, 7); - float x4 = (float)luaL_checknumber(L, 8); - float y4 = (float)luaL_checknumber(L, 9); - instance->quad(mode, x1, y1, x2, y2, x3, y3, x4, y4); - return 0; -} - int w_circle(lua_State *L) { Graphics::DrawMode mode; @@ -1242,8 +1234,7 @@ int w_polygon(lua_State *L) { for (int i = 0; i < args; ++i) { - lua_pushnumber(L, i + 1); - lua_rawget(L, 2); + lua_rawgeti(L, 2, i + 1); coords[i] = luax_tofloat(L, -1); lua_pop(L, 1); } @@ -1265,34 +1256,20 @@ int w_polygon(lua_State *L) int w_push(lua_State *L) { - try - { - instance->push(); - } - catch(love::Exception e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance->push();) return 0; } int w_pop(lua_State *L) { - try - { - instance->pop(); - } - catch(love::Exception e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance->pop();) return 0; } int w_rotate(lua_State *L) { - float deg = (float)luaL_checknumber(L, 1); - instance->rotate(deg); + float angle = (float)luaL_checknumber(L, 1); + instance->rotate(angle); return 0; } @@ -1320,20 +1297,16 @@ int w_shear(lua_State *L) return 0; } -int w_hasFocus(lua_State *L) +int w_origin(lua_State * /*L*/) { - luax_pushboolean(L, instance->hasFocus()); - return 1; + instance->origin(); + return 0; } // List of functions to wrap. static const luaL_Reg functions[] = { - { "checkMode", w_checkMode }, - { "setMode", w_setMode }, - { "getMode", w_getMode }, - { "toggleFullscreen", w_toggleFullscreen }, { "reset", w_reset }, { "clear", w_clear }, { "present", w_present }, @@ -1346,6 +1319,7 @@ static const luaL_Reg functions[] = { "newParticleSystem", w_newParticleSystem }, { "newCanvas", w_newCanvas }, { "newShader", w_newShader }, + { "newMesh", w_newMesh }, { "setColor", w_setColor }, { "getColor", w_getColor }, @@ -1355,23 +1329,26 @@ static const luaL_Reg functions[] = { "setFont", w_setFont }, { "getFont", w_getFont }, + { "setColorMask", w_setColorMask }, + { "getColorMask", w_getColorMask }, { "setBlendMode", w_setBlendMode }, - { "setColorMode", w_setColorMode }, - { "setDefaultImageFilter", w_setDefaultImageFilter }, { "getBlendMode", w_getBlendMode }, - { "getColorMode", w_getColorMode }, - { "getDefaultImageFilter", w_getDefaultImageFilter }, + { "setDefaultFilter", w_setDefaultFilter }, + { "getDefaultFilter", w_getDefaultFilter }, + { "setDefaultMipmapFilter", w_setDefaultMipmapFilter }, + { "getDefaultMipmapFilter", w_getDefaultMipmapFilter }, { "setLineWidth", w_setLineWidth }, { "setLineStyle", w_setLineStyle }, - { "setLine", w_setLine }, + { "setLineJoin", w_setLineJoin }, { "getLineWidth", w_getLineWidth }, { "getLineStyle", w_getLineStyle }, + { "getLineJoin", w_getLineJoin }, { "setPointSize", w_setPointSize }, { "setPointStyle", w_setPointStyle }, - { "setPoint", w_setPoint }, { "getPointSize", w_getPointSize }, { "getPointStyle", w_getPointStyle }, { "getMaxPointSize", w_getMaxPointSize }, + { "getMaxTextureSize", w_getMaxTextureSize }, { "newScreenshot", w_newScreenshot }, { "setCanvas", w_setCanvas }, { "getCanvas", w_getCanvas }, @@ -1380,37 +1357,27 @@ static const luaL_Reg functions[] = { "getShader", w_getShader }, { "isSupported", w_isSupported }, + { "getRendererInfo", w_getRendererInfo }, { "draw", w_draw }, - { "drawq", w_drawq }, { "print", w_print }, { "printf", w_printf }, - { "setCaption", w_setCaption }, - { "getCaption", w_getCaption }, - - { "setIcon", w_setIcon }, - + { "isCreated", w_isCreated }, { "getWidth", w_getWidth }, { "getHeight", w_getHeight }, - - { "isCreated", w_isCreated }, - - { "getModes", w_getModes }, + { "getDimensions", w_getDimensions }, { "setScissor", w_setScissor }, { "getScissor", w_getScissor }, - { "newStencil", w_newStencil }, { "setStencil", w_setStencil }, { "setInvertedStencil", w_setInvertedStencil }, { "point", w_point }, { "line", w_line }, - //{ "triangle", w_triangle }, { "rectangle", w_rectangle }, - //{ "quad", w_quad }, { "circle", w_circle }, { "arc", w_arc }, @@ -1422,8 +1389,10 @@ static const luaL_Reg functions[] = { "scale", w_scale }, { "translate", w_translate }, { "shear", w_shear }, + { "origin", w_origin }, - { "hasFocus", w_hasFocus }, + // Deprecated since 0.9.1. + { "getMaxImageSize", w_getMaxTextureSize }, { 0, 0 } }; @@ -1433,11 +1402,12 @@ static const lua_CFunction types[] = { luaopen_font, luaopen_image, - luaopen_frame, + luaopen_quad, luaopen_spritebatch, luaopen_particlesystem, luaopen_canvas, luaopen_shader, + luaopen_mesh, 0 }; @@ -1445,14 +1415,7 @@ extern "C" int luaopen_love_graphics(lua_State *L) { if (instance == 0) { - try - { - instance = new Graphics(); - } - catch (love::Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new Graphics();) } else instance->retain(); @@ -1460,7 +1423,7 @@ extern "C" int luaopen_love_graphics(lua_State *L) WrappedModule w; w.module = instance; w.name = "graphics"; - w.flags = MODULE_T; + w.flags = MODULE_GRAPHICS_T; w.functions = functions; w.types = types; diff --git a/src/modules/graphics/opengl/wrap_Graphics.h b/src/modules/graphics/opengl/wrap_Graphics.h index d11ac1552..4514bb68b 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.h +++ b/src/modules/graphics/opengl/wrap_Graphics.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,6 +29,7 @@ #include "wrap_ParticleSystem.h" #include "wrap_Canvas.h" #include "wrap_Shader.h" +#include "wrap_Mesh.h" #include "Graphics.h" namespace love @@ -38,52 +39,49 @@ namespace graphics namespace opengl { -int w_checkMode(lua_State *L); -int w_setMode(lua_State *L); -int w_getMode(lua_State *L); -int w_toggleFullscreen(lua_State *L); int w_reset(lua_State *L); int w_clear(lua_State *L); int w_present(lua_State *L); -int w_setIcon(lua_State *L); -int w_setCaption(lua_State *L); -int w_getCaption(lua_State *L); +int w_isCreated(lua_State *L); int w_getWidth(lua_State *L); int w_getHeight(lua_State *L); -int w_isCreated(lua_State *L); +int w_getDimensions(lua_State *L); int w_setScissor(lua_State *L); int w_getScissor(lua_State *L); -int w_defineMask(lua_State *L); -int w_setMask(lua_State *L); +int w_setStencil(lua_State *L); +int w_setInvertedStencil(lua_State *L); +int w_getMaxTextureSize(lua_State *L); int w_newImage(lua_State *L); int w_newQuad(lua_State *L); -int w_newFrame(lua_State *L); int w_newFont(lua_State *L); int w_newImageFont(lua_State *L); int w_newSpriteBatch(lua_State *L); int w_newParticleSystem(lua_State *L); int w_newCanvas(lua_State *L); // comments in function int w_newShader(lua_State *L); +int w_newMesh(lua_State *L); int w_setColor(lua_State *L); int w_getColor(lua_State *L); int w_setBackgroundColor(lua_State *L); int w_getBackgroundColor(lua_State *L); int w_setFont(lua_State *L); int w_getFont(lua_State *L); +int w_setColorMask(lua_State *L); +int w_getColorMask(lua_State *L); int w_setBlendMode(lua_State *L); -int w_setColorMode(lua_State *L); -int w_setDefaultImageFilter(lua_State *L); int w_getBlendMode(lua_State *L); -int w_getColorMode(lua_State *L); -int w_getDefaultImageFilter(lua_State *L); +int w_setDefaultFilter(lua_State *L); +int w_getDefaultFilter(lua_State *L); +int w_setDefaultMipmapFilter(lua_State *L); +int w_getDefaultMipmapFilter(lua_State *L); int w_setLineWidth(lua_State *L); int w_setLineStyle(lua_State *L); -int w_setLine(lua_State *L); +int w_setLineJoin(lua_State *L); int w_getLineWidth(lua_State *L); int w_getLineStyle(lua_State *L); +int w_getLineJoin(lua_State *L); int w_setPointSize(lua_State *L); int w_setPointStyle(lua_State *L); -int w_setPoint(lua_State *L); int w_getPointSize(lua_State *L); int w_getPointStyle(lua_State *L); int w_getMaxPointSize(lua_State *L); @@ -93,24 +91,23 @@ int w_getCanvas(lua_State *L); int w_setShader(lua_State *L); int w_getShader(lua_State *L); int w_isSupported(lua_State *L); +int w_getRendererInfo(lua_State *L); int w_draw(lua_State *L); -int w_drawq(lua_State *L); int w_print(lua_State *L); int w_printf(lua_State *L); int w_point(lua_State *L); int w_line(lua_State *L); -int w_triangle(lua_State *L); int w_rectangle(lua_State *L); -int w_quad(lua_State *L); int w_circle(lua_State *L); int w_arc(lua_State *L); +int w_polygon(lua_State *L); int w_push(lua_State *L); int w_pop(lua_State *L); int w_rotate(lua_State *L); int w_scale(lua_State *L); int w_translate(lua_State *L); int w_shear(lua_State *L); -int w_hasFocus(lua_State *L); +int w_origin(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_graphics(lua_State *L); } // opengl diff --git a/src/modules/graphics/opengl/wrap_Image.cpp b/src/modules/graphics/opengl/wrap_Image.cpp index 16d140901..be95571e7 100644 --- a/src/modules/graphics/opengl/wrap_Image.cpp +++ b/src/modules/graphics/opengl/wrap_Image.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,159 +33,104 @@ Image *luax_checkimage(lua_State *L, int idx) return luax_checktype(L, idx, "Image", GRAPHICS_IMAGE_T); } -int w_Image_getWidth(lua_State *L) -{ - Image *t = luax_checkimage(L, 1); - lua_pushnumber(L, t->getWidth()); - return 1; -} - -int w_Image_getHeight(lua_State *L) -{ - Image *t = luax_checkimage(L, 1); - lua_pushnumber(L, t->getHeight()); - return 1; -} - -int w_Image_setFilter(lua_State *L) -{ - Image *t = luax_checkimage(L, 1); - Image::Filter f = t->getFilter(); - - const char *minstr = luaL_checkstring(L, 2); - const char *magstr = luaL_optstring(L, 3, minstr); - - if (!Image::getConstant(minstr, f.min)) - return luaL_error(L, "Invalid filter mode: %s", minstr); - if (!Image::getConstant(magstr, f.mag)) - return luaL_error(L, "Invalid filter mode: %s", magstr); - - try - { - t->setFilter(f); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - - return 0; -} - -int w_Image_getFilter(lua_State *L) -{ - Image *t = luax_checkimage(L, 1); - const Image::Filter f = t->getFilter(); - const char *minstr; - const char *magstr; - Image::getConstant(f.min, minstr); - Image::getConstant(f.mag, magstr); - lua_pushstring(L, minstr); - lua_pushstring(L, magstr); - return 2; -} - int w_Image_setMipmapFilter(lua_State *L) { Image *t = luax_checkimage(L, 1); - Image::Filter f = t->getFilter(); + Texture::Filter f = t->getFilter(); if (lua_isnoneornil(L, 2)) - f.mipmap = Image::FILTER_NONE; // mipmapping is disabled if no argument is given + f.mipmap = Texture::FILTER_NONE; // mipmapping is disabled if no argument is given else { const char *mipmapstr = luaL_checkstring(L, 2); - if (!Image::getConstant(mipmapstr, f.mipmap)) + if (!Texture::getConstant(mipmapstr, f.mipmap)) return luaL_error(L, "Invalid filter mode: %s", mipmapstr); } - try - { - t->setFilter(f); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - + EXCEPT_GUARD(t->setFilter(f);) + + float sharpness = (float) luaL_optnumber(L, 3, 0); + t->setMipmapSharpness(sharpness); + return 0; } int w_Image_getMipmapFilter(lua_State *L) { Image *t = luax_checkimage(L, 1); - const Image::Filter f = t->getFilter(); + + const Texture::Filter &f = t->getFilter(); const char *mipmapstr; - if (!Image::getConstant(f.mipmap, mipmapstr)) - return 0; // only return a mipmap filter if mipmapping is enabled + if (Texture::getConstant(f.mipmap, mipmapstr)) + lua_pushstring(L, mipmapstr); + else + lua_pushnil(L); // only return a mipmap filter if mipmapping is enabled - lua_pushstring(L, mipmapstr); - - return 1; -} - -int w_Image_setWrap(lua_State *L) -{ - Image *i = luax_checkimage(L, 1); - - Image::Wrap w; - - const char *sstr = luaL_checkstring(L, 2); - const char *tstr = luaL_optstring(L, 3, sstr); - - if (!Image::getConstant(sstr, w.s)) - return luaL_error(L, "Invalid wrap mode: %s", sstr); - if (!Image::getConstant(tstr, w.t)) - return luaL_error(L, "Invalid wrap mode, %s", tstr); - - i->setWrap(w); - - return 0; -} - -int w_Image_getWrap(lua_State *L) -{ - Image *i = luax_checkimage(L, 1); - const Image::Wrap w = i->getWrap(); - const char *sstr; - const char *tstr; - Image::getConstant(w.s, sstr); - Image::getConstant(w.t, tstr); - lua_pushstring(L, sstr); - lua_pushstring(L, tstr); + lua_pushnumber(L, t->getMipmapSharpness()); return 2; } -int w_Image_setMipmapSharpness(lua_State *L) +int w_Image_isCompressed(lua_State *L) { Image *i = luax_checkimage(L, 1); + luax_pushboolean(L, i->isCompressed()); + return 1; +} - float sharpness = (float) luaL_checknumber(L, 2); - i->setMipmapSharpness(sharpness); - +int w_Image_refresh(lua_State *L) +{ + Image *i = luax_checkimage(L, 1); + EXCEPT_GUARD(i->refresh();) return 0; } -int w_Image_getMipmapSharpness(lua_State *L) +int w_Image_getData(lua_State *L) { Image *i = luax_checkimage(L, 1); - lua_pushnumber(L, i->getMipmapSharpness()); + + if (i->isCompressed()) + { + love::image::CompressedData *t = i->getCompressedData(); + if (t) + { + t->retain(); + luax_pushtype(L, "CompressedData", IMAGE_COMPRESSED_DATA_T, t); + } + else + lua_pushnil(L); + } + else + { + love::image::ImageData *t = i->getImageData(); + if (t) + { + t->retain(); + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, t); + } + else + lua_pushnil(L); + } + return 1; } static const luaL_Reg functions[] = { - { "getWidth", w_Image_getWidth }, - { "getHeight", w_Image_getHeight }, - { "setFilter", w_Image_setFilter }, - { "getFilter", w_Image_getFilter }, - { "setWrap", w_Image_setWrap }, - { "getWrap", w_Image_getWrap }, + // From wrap_Texture. + { "getWidth", w_Texture_getWidth }, + { "getHeight", w_Texture_getHeight }, + { "getDimensions", w_Texture_getDimensions }, + { "setFilter", w_Texture_setFilter }, + { "getFilter", w_Texture_getFilter }, + { "setWrap", w_Texture_setWrap }, + { "getWrap", w_Texture_getWrap }, + { "setMipmapFilter", w_Image_setMipmapFilter }, { "getMipmapFilter", w_Image_getMipmapFilter }, - { "setMipmapSharpness", w_Image_setMipmapSharpness }, - { "getMipmapSharpness", w_Image_getMipmapSharpness }, + { "isCompressed", w_Image_isCompressed }, + { "refresh", w_Image_refresh }, + { "getData", w_Image_getData }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Image.h b/src/modules/graphics/opengl/wrap_Image.h index a986bed9b..13764d8cb 100644 --- a/src/modules/graphics/opengl/wrap_Image.h +++ b/src/modules/graphics/opengl/wrap_Image.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,6 +24,7 @@ // LOVE #include "common/runtime.h" #include "Image.h" +#include "wrap_Texture.h" namespace love { @@ -33,16 +34,11 @@ namespace opengl { Image *luax_checkimage(lua_State *L, int idx); -int w_Image_getWidth(lua_State *L); -int w_Image_getHeight(lua_State *L); -int w_Image_setFilter(lua_State *L); -int w_image_getFilter(lua_State *L); int w_Image_setMipmapFilter(lua_State *L); int w_Image_getMipmapFilter(lua_State *L); -int w_Image_setWrap(lua_State *L); -int w_Image_getWrap(lua_State *L); -int w_Image_setMipmapSharpness(lua_State *L); -int w_Image_getMipmapSharpness(lua_State *L); +int w_Image_isCompressed(lua_State *L); +int w_Image_refresh(lua_State *L); +int w_Image_getData(lua_State *L); extern "C" int luaopen_image(lua_State *L); } // opengl diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp new file mode 100644 index 000000000..1ea57e755 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -0,0 +1,364 @@ +/** + * Copyright (c) 2006-2014 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 "wrap_Mesh.h" +#include "Image.h" +#include "Canvas.h" +#include "wrap_Texture.h" + +// C++ +#include + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Mesh *luax_checkmesh(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "Mesh", GRAPHICS_MESH_T); +} + +int w_Mesh_setVertex(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + size_t i = size_t(luaL_checkinteger(L, 2) - 1); + + Vertex v; + + if (lua_istable(L, 3)) + { + for (int i = 1; i <= 8; i++) + lua_rawgeti(L, 3, i); + + v.x = luaL_checknumber(L, -8); + v.y = luaL_checknumber(L, -7); + v.s = luaL_checknumber(L, -6); + v.t = luaL_checknumber(L, -5); + v.r = luaL_optinteger(L, -4, 255); + v.g = luaL_optinteger(L, -3, 255); + v.b = luaL_optinteger(L, -2, 255); + v.a = luaL_optinteger(L, -1, 255); + + lua_pop(L, 8); + } + else + { + v.x = luaL_checknumber(L, 3); + v.y = luaL_checknumber(L, 4); + v.s = luaL_checknumber(L, 5); + v.t = luaL_checknumber(L, 6); + v.r = luaL_optinteger(L, 7, 255); + v.g = luaL_optinteger(L, 8, 255); + v.b = luaL_optinteger(L, 9, 255); + v.a = luaL_optinteger(L, 10, 255); + } + + EXCEPT_GUARD(t->setVertex(i, v);) + return 0; +} + +int w_Mesh_getVertex(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + size_t i = (size_t) (luaL_checkinteger(L, 2) - 1); + + Vertex v; + EXCEPT_GUARD(v = t->getVertex(i);) + + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + lua_pushnumber(L, v.s); + lua_pushnumber(L, v.t); + lua_pushnumber(L, v.r); + lua_pushnumber(L, v.g); + lua_pushnumber(L, v.b); + lua_pushnumber(L, v.a); + + return 8; +} + +int w_Mesh_setVertices(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + size_t vertex_count = lua_objlen(L, 2); + std::vector vertices; + vertices.reserve(vertex_count); + + // Get the vertices from the table. + for (size_t i = 1; i <= vertex_count; i++) + { + lua_rawgeti(L, 2, i); + + if (lua_type(L, -1) != LUA_TTABLE) + return luax_typerror(L, 2, "table of tables"); + + for (int j = 1; j <= 8; j++) + lua_rawgeti(L, -j, j); + + Vertex v; + + v.x = (float) luaL_checknumber(L, -8); + v.y = (float) luaL_checknumber(L, -7); + + v.s = (float) luaL_checknumber(L, -6); + v.t = (float) luaL_checknumber(L, -5); + + v.r = (unsigned char) luaL_optinteger(L, -4, 255); + v.g = (unsigned char) luaL_optinteger(L, -3, 255); + v.b = (unsigned char) luaL_optinteger(L, -2, 255); + v.a = (unsigned char) luaL_optinteger(L, -1, 255); + + lua_pop(L, 9); + vertices.push_back(v); + } + + EXCEPT_GUARD(t->setVertices(vertices);) + return 0; +} + +int w_Mesh_getVertices(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + const Vertex *vertices = t->getVertices(); + + size_t count = t->getVertexCount(); + lua_createtable(L, count, 0); + + for (size_t i = 0; i < count; i++) + { + // Create vertex table. + lua_createtable(L, 8, 0); + + lua_pushnumber(L, vertices[i].x); + lua_rawseti(L, -2, 1); + + lua_pushnumber(L, vertices[i].y); + lua_rawseti(L, -2, 2); + + lua_pushnumber(L, vertices[i].s); + lua_rawseti(L, -2, 3); + + lua_pushnumber(L, vertices[i].t); + lua_rawseti(L, -2, 4); + + lua_pushnumber(L, vertices[i].r); + lua_rawseti(L, -2, 5); + + lua_pushnumber(L, vertices[i].g); + lua_rawseti(L, -2, 6); + + lua_pushnumber(L, vertices[i].b); + lua_rawseti(L, -2, 7); + + lua_pushnumber(L, vertices[i].a); + lua_rawseti(L, -2, 8); + + // Insert vertex table into vertices table. + lua_rawseti(L, -2, i + 1); + } + + // Return vertices table. + return 1; +} + +int w_Mesh_getVertexCount(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + lua_pushinteger(L, t->getVertexCount()); + return 1; +} + +int w_Mesh_setVertexMap(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + bool is_table = lua_istable(L, 2); + int nargs = is_table ? lua_objlen(L, 2) : lua_gettop(L) - 1; + + std::vector vertexmap; + vertexmap.reserve(nargs); + + for (int i = 0; i < nargs; i++) + { + if (is_table) + { + lua_rawgeti(L, 2, i + 1); + vertexmap.push_back(uint32(luaL_checkinteger(L, -1) - 1)); + lua_pop(L, 1); + } + else + vertexmap.push_back(uint32(luaL_checkinteger(L, i + 2) - 1)); + } + + EXCEPT_GUARD(t->setVertexMap(vertexmap);) + return 0; +} + +int w_Mesh_getVertexMap(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + const uint32 *vertex_map = 0; + + EXCEPT_GUARD(vertex_map = t->getVertexMap();) + size_t elements = t->getVertexMapCount(); + + lua_createtable(L, elements, 0); + + for (size_t i = 0; i < elements; i++) + { + lua_pushinteger(L, lua_Integer(vertex_map[i]) + 1); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int w_Mesh_setTexture(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + if (lua_isnoneornil(L, 2)) + t->setTexture(); + else + { + Texture *tex = luax_checktexture(L, 2); + t->setTexture(tex); + } + + return 0; +} + +int w_Mesh_getTexture(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + Texture *tex = t->getTexture(); + + if (tex == nullptr) + return 0; + + tex->retain(); + + // FIXME: big hack right here. + if (typeid(*tex) == typeid(Image)) + luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, tex); + else if (typeid(*tex) == typeid(Canvas)) + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, tex); + else + { + tex->release(); + return luaL_error(L, "Unable to determine texture type."); + } + + return 1; +} + +int w_Mesh_setDrawMode(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + const char *str = luaL_checkstring(L, 2); + Mesh::DrawMode mode; + + if (!Mesh::getConstant(str, mode)) + return luaL_error(L, "Invalid mesh draw mode: %s", str); + + t->setDrawMode(mode); + return 0; +} + +int w_Mesh_getDrawMode(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + Mesh::DrawMode mode = t->getDrawMode(); + const char *str; + + if (!Mesh::getConstant(mode, str)) + return luaL_error(L, "Unknown mesh draw mode."); + + lua_pushstring(L, str); + return 1; +} + +int w_Mesh_setVertexColors(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + t->setVertexColors(luax_toboolean(L, 2)); + return 0; +} + +int w_Mesh_hasVertexColors(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + luax_pushboolean(L, t->hasVertexColors()); + return 1; +} + +int w_Mesh_setWireframe(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + t->setWireframe(luax_toboolean(L, 2)); + return 0; +} + +int w_Mesh_isWireframe(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + luax_pushboolean(L, t->isWireframe()); + return 1; +} + +static const luaL_Reg functions[] = +{ + { "setVertex", w_Mesh_setVertex }, + { "getVertex", w_Mesh_getVertex }, + { "setVertices", w_Mesh_setVertices }, + { "getVertices", w_Mesh_getVertices }, + { "getVertexCount", w_Mesh_getVertexCount }, + { "setVertexMap", w_Mesh_setVertexMap }, + { "getVertexMap", w_Mesh_getVertexMap }, + { "setTexture", w_Mesh_setTexture }, + { "getTexture", w_Mesh_getTexture }, + { "setDrawMode", w_Mesh_setDrawMode }, + { "getDrawMode", w_Mesh_getDrawMode }, + { "setVertexColors", w_Mesh_setVertexColors }, + { "hasVertexColors", w_Mesh_hasVertexColors }, + { "setWireframe", w_Mesh_setWireframe }, + { "isWireframe", w_Mesh_isWireframe }, + + // Deprecated since 0.9.1. + { "setImage", w_Mesh_setTexture }, + { "getImage", w_Mesh_getTexture }, + + { 0, 0 } +}; + +extern "C" int luaopen_mesh(lua_State *L) +{ + return luax_register_type(L, "Mesh", functions); +} + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/Quad.h b/src/modules/graphics/opengl/wrap_Mesh.h similarity index 50% rename from src/modules/graphics/opengl/Quad.h rename to src/modules/graphics/opengl/wrap_Mesh.h index a6289fd57..efae413dc 100644 --- a/src/modules/graphics/opengl/Quad.h +++ b/src/modules/graphics/opengl/wrap_Mesh.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,12 +18,12 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_OPENGL_QUAD_H -#define LOVE_GRAPHICS_OPENGL_QUAD_H +#ifndef LOVE_GRAPHICS_OPENGL_WRAP_MESH_H +#define LOVE_GRAPHICS_OPENGL_WRAP_MESH_H // LOVE -#include "common/math.h" -#include +#include "common/runtime.h" +#include "Mesh.h" namespace love { @@ -32,45 +32,28 @@ namespace graphics namespace opengl { -class Quad : public love::graphics::Quad -{ -public: +Mesh *luax_checkmesh(lua_State *L, int idx); - /** - * Creates a new Quad of size (w,h), using (x,y) as the top-left - * anchor point in the source image. The size of the source image is - * is specified by (sw,sh). - * - * @param sw Width of the source image. - * @param sh Height of the source image. - **/ - Quad(const Viewport &v, float sw, float sh); +int w_Mesh_setVertex(lua_State *L); +int w_Mesh_getVertex(lua_State *L); +int w_Mesh_setVertices(lua_State *L); +int w_Mesh_getVertices(lua_State *L); +int w_Mesh_getVertexCount(lua_State *L); +int w_Mesh_setVertexMap(lua_State *L); +int w_Mesh_getVertexMap(lua_State *L); +int w_Mesh_setTexture(lua_State *L); +int w_Mesh_getTexture(lua_State *L); +int w_Mesh_setDrawMode(lua_State *L); +int w_Mesh_getDrawMode(lua_State *L); +int w_Mesh_setVertexColors(lua_State *L); +int w_Mesh_hasVertexColors(lua_State *L); +int w_Mesh_setWireframe(lua_State *L); +int w_Mesh_isWireframe(lua_State *L); - virtual ~Quad(); - - void refresh(const Viewport &v, float sw, float sh); - - void setViewport(const Viewport &v); - Viewport getViewport() const; - - void flip(bool x, bool y); - - /** - * Gets a pointer to the vertices. - **/ - const vertex *getVertices() const; - -protected: - - static const unsigned int NUM_VERTICES = 4; - vertex vertices[NUM_VERTICES]; - - Viewport viewport; - float sw, sh; -}; +extern "C" int luaopen_mesh(lua_State *L); } // opengl } // graphics } // love -#endif // LOVE_GRAPHICS_OPENGL_QUAD_H +#endif // LOVE_GRAPHICS_OPENGL_WRAP_MESH_H diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp index 049b23d75..91517d60c 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,12 +18,20 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "wrap_ParticleSystem.h" - #include "common/Vector.h" +#include "Image.h" +#include "Canvas.h" +#include "wrap_Texture.h" + +// C #include +// C++ +#include + namespace love { namespace graphics @@ -36,47 +44,135 @@ ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx) return luax_checktype(L, idx, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T); } -int w_ParticleSystem_setSprite(lua_State *L) +int w_ParticleSystem_clone(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - Image *i = luax_checkimage(L, 2); - t->setSprite(i); + + ParticleSystem *clone = nullptr; + EXCEPT_GUARD(clone = t->clone();) + + luax_pushtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, clone); + return 1; +} + +int w_ParticleSystem_setTexture(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + Texture *tex = luax_checktexture(L, 2); + t->setTexture(tex); return 0; } +int w_ParticleSystem_getTexture(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + Texture *tex = t->getTexture(); + tex->retain(); + + // FIXME: big hack right here. + if (typeid(*tex) == typeid(Image)) + luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, tex); + else if (typeid(*tex) == typeid(Canvas)) + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, tex); + else + { + tex->release(); + return luaL_error(L, "Unable to determine texture type."); + } + + return 1; +} + int w_ParticleSystem_setBufferSize(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - int arg1 = luaL_checkint(L, 2); - t->setBufferSize((unsigned int)arg1); + lua_Number arg1 = luaL_checknumber(L, 2); + if (arg1 < 1.0 || arg1 > ParticleSystem::MAX_PARTICLES) + return luaL_error(L, "Invalid buffer size"); + + EXCEPT_GUARD(t->setBufferSize((uint32) arg1);) return 0; } +int w_ParticleSystem_getBufferSize(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + lua_pushinteger(L, t->getBufferSize()); + return 1; +} + +int w_ParticleSystem_setInsertMode(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + ParticleSystem::InsertMode mode; + const char *str = luaL_checkstring(L, 2); + if (!ParticleSystem::getConstant(str, mode)) + return luaL_error(L, "Invalid insert mode: '%s'", str); + t->setInsertMode(mode); + return 0; +} + +int w_ParticleSystem_getInsertMode(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + ParticleSystem::InsertMode mode; + mode = t->getInsertMode(); + const char *str; + if (!ParticleSystem::getConstant(mode, str)) + return luaL_error(L, "Unknown insert mode"); + lua_pushstring(L, str); + return 1; +} + int w_ParticleSystem_setEmissionRate(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); int arg1 = luaL_checkint(L, 2); - t->setEmissionRate((unsigned int)arg1); + EXCEPT_GUARD(t->setEmissionRate(arg1);) return 0; } -int w_ParticleSystem_setLifetime(lua_State *L) +int w_ParticleSystem_getEmissionRate(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + lua_pushinteger(L, t->getEmissionRate()); + return 1; +} + +int w_ParticleSystem_setEmitterLifetime(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setLifetime(arg1); + t->setEmitterLifetime(arg1); return 0; } -int w_ParticleSystem_setParticleLife(lua_State *L) +int w_ParticleSystem_getEmitterLifetime(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getEmitterLifetime()); + return 1; +} + +int w_ParticleSystem_setParticleLifetime(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float arg1 = (float)luaL_checknumber(L, 2); float arg2 = (float)luaL_optnumber(L, 3, arg1); - t->setParticleLife(arg1, arg2); + t->setParticleLifetime(arg1, arg2); return 0; } +int w_ParticleSystem_getParticleLifetime(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float min, max; + t->getParticleLifetime(&min, &max); + lua_pushnumber(L, min); + lua_pushnumber(L, max); + return 2; +} + int w_ParticleSystem_setPosition(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -86,24 +182,53 @@ int w_ParticleSystem_setPosition(lua_State *L) return 0; } +int w_ParticleSystem_getPosition(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + love::Vector pos = t->getPosition(); + lua_pushnumber(L, pos.getX()); + lua_pushnumber(L, pos.getY()); + return 2; +} + 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); + ParticleSystem::AreaSpreadDistribution distribution = ParticleSystem::DISTRIBUTION_NONE; + float x = 0.f, y = 0.f; - 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)"); + const char *str = lua_isnoneornil(L, 2) ? 0 : luaL_checkstring(L, 2); + if (str && !ParticleSystem::getConstant(str, distribution)) + return luaL_error(L, "Invalid particle distribution: %s", str); + + if (distribution != ParticleSystem::DISTRIBUTION_NONE) + { + x = (float) luaL_checknumber(L, 3); + 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_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_setDirection(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -112,6 +237,13 @@ int w_ParticleSystem_setDirection(lua_State *L) return 0; } +int w_ParticleSystem_getDirection(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getDirection()); + return 1; +} + int w_ParticleSystem_setSpread(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -120,12 +252,11 @@ int w_ParticleSystem_setSpread(lua_State *L) return 0; } -int w_ParticleSystem_setRelativeDirection(lua_State *L) +int w_ParticleSystem_getSpread(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - bool arg1 = (bool)luax_toboolean(L, 2); - t->setRelativeDirection(arg1); - return 0; + lua_pushnumber(L, t->getSpread()); + return 1; } int w_ParticleSystem_setSpeed(lua_State *L) @@ -137,15 +268,39 @@ int w_ParticleSystem_setSpeed(lua_State *L) return 0; } -int w_ParticleSystem_setGravity(lua_State *L) +int w_ParticleSystem_getSpeed(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - float arg1 = (float)luaL_checknumber(L, 2); - float arg2 = (float)luaL_optnumber(L, 3, arg1); - t->setGravity(arg1, arg2); + float min, max; + t->getSpeed(&min, &max); + lua_pushnumber(L, min); + lua_pushnumber(L, max); + return 2; +} + +int w_ParticleSystem_setLinearAcceleration(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float xmin = (float) luaL_checknumber(L, 2); + float ymin = (float) luaL_checknumber(L, 3); + float xmax = (float) luaL_optnumber(L, 4, xmin); + float ymax = (float) luaL_optnumber(L, 5, ymin); + t->setLinearAcceleration(xmin, ymin, xmax, ymax); return 0; } +int w_ParticleSystem_getLinearAcceleration(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + love::Vector min, max; + t->getLinearAcceleration(&min, &max); + lua_pushnumber(L, min.x); + lua_pushnumber(L, min.y); + lua_pushnumber(L, max.x); + lua_pushnumber(L, max.y); + return 4; +} + int w_ParticleSystem_setRadialAcceleration(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -155,6 +310,16 @@ int w_ParticleSystem_setRadialAcceleration(lua_State *L) return 0; } +int w_ParticleSystem_getRadialAcceleration(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float min, max; + t->getRadialAcceleration(&min, &max); + lua_pushnumber(L, min); + lua_pushnumber(L, max); + return 2; +} + int w_ParticleSystem_setTangentialAcceleration(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -164,6 +329,16 @@ int w_ParticleSystem_setTangentialAcceleration(lua_State *L) return 0; } +int w_ParticleSystem_getTangentialAcceleration(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float min, max; + t->getTangentialAcceleration(&min, &max); + lua_pushnumber(L, min); + lua_pushnumber(L, max); + return 2; +} + int w_ParticleSystem_setSizes(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -183,11 +358,22 @@ int w_ParticleSystem_setSizes(lua_State *L) for (size_t i = 0; i < nSizes; ++i) sizes[i] = luax_checkfloat(L, 1 + i + 1); - t->setSize(sizes); + t->setSizes(sizes); } return 0; } +int w_ParticleSystem_getSizes(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + const std::vector &sizes = t->getSizes(); + + for (size_t i = 0; i < sizes.size(); i++) + lua_pushnumber(L, sizes[i]); + + return sizes.size(); +} + int w_ParticleSystem_setSizeVariation(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -199,6 +385,13 @@ int w_ParticleSystem_setSizeVariation(lua_State *L) return 0; } +int w_ParticleSystem_getSizeVariation(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + lua_pushnumber(L, t->getSizeVariation()); + return 1; +} + int w_ParticleSystem_setRotation(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -208,16 +401,35 @@ int w_ParticleSystem_setRotation(lua_State *L) return 0; } +int w_ParticleSystem_getRotation(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float min, max; + t->getRotation(&min, &max); + lua_pushnumber(L, min); + lua_pushnumber(L, max); + return 2; +} + int w_ParticleSystem_setSpin(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); float arg1 = (float)luaL_checknumber(L, 2); float arg2 = (float)luaL_optnumber(L, 3, arg1); - float arg3 = (float)luaL_optnumber(L, 4, 0); - t->setSpin(arg1, arg2, arg3); + t->setSpin(arg1, arg2); return 0; } +int w_ParticleSystem_getSpin(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + float start, end; + t->getSpin(&start, &end); + lua_pushnumber(L, start); + lua_pushnumber(L, end); + return 2; +} + int w_ParticleSystem_setSpinVariation(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -226,40 +438,11 @@ int w_ParticleSystem_setSpinVariation(lua_State *L) return 0; } -int w_ParticleSystem_setColors(lua_State *L) +int w_ParticleSystem_getSpinVariation(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - int cargs = lua_gettop(L) - 1; - size_t nColors = (cargs + 3) / 4; // nColors = ceil(color_args / 4) - if (cargs % 4 != 0 || cargs == 0) - return luaL_error(L, "Expected red, green, blue, and alpha. Only got %d of 4 components.", cargs % 4); - - if (nColors > 8) - return luaL_error(L, "At most eight (8) colors may be used."); - - if (nColors == 1) - { - int r = luaL_checkint(L, 2); - int g = luaL_checkint(L, 3); - int b = luaL_checkint(L, 4); - int a = luaL_checkint(L, 5); - t->setColor(Color(r,g,b,a)); - } - else - { - std::vector colors(nColors); - for (size_t i = 0; i < nColors; ++i) - { - int r = luaL_checkint(L, 1 + i*4 + 1); - int g = luaL_checkint(L, 1 + i*4 + 2); - int b = luaL_checkint(L, 1 + i*4 + 3); - int a = luaL_checkint(L, 1 + i*4 + 4); - colors[i] = Color(r,g,b,a); - } - t->setColor(colors); - } - - return 0; + lua_pushnumber(L, t->getSpinVariation()); + return 1; } int w_ParticleSystem_setOffset(lua_State *L) @@ -271,76 +454,116 @@ int w_ParticleSystem_setOffset(lua_State *L) return 0; } -int w_ParticleSystem_getX(lua_State *L) +int w_ParticleSystem_getOffset(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->getX()); - return 1; -} - -int w_ParticleSystem_getY(lua_State *L) -{ - ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->getY()); - return 1; -} - -int w_ParticleSystem_getPosition(lua_State *L) -{ - ParticleSystem *t = luax_checkparticlesystem(L, 1); - const love::Vector &p = t->getPosition(); - lua_pushnumber(L, p.x); - lua_pushnumber(L, p.y); + love::Vector offset = t->getOffset(); + lua_pushnumber(L, offset.getX()); + lua_pushnumber(L, offset.getY()); return 2; } -int w_ParticleSystem_getAreaSpread(lua_State *L) +int w_ParticleSystem_setColors(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); + if (lua_istable(L, 2)) // setColors({r,g,b,a}, {r,g,b,a}, ...) + { + size_t nColors = lua_gettop(L) - 1; - return 3; + if (nColors > 8) + return luaL_error(L, "At most eight (8) colors may be used."); + + std::vector colors(nColors); + + for (size_t i = 0; i < nColors; i++) + { + luaL_checktype(L, i + 2, LUA_TTABLE); + + if (lua_objlen(L, i + 2) < 3) + return luaL_argerror(L, i + 2, "expected 4 color components"); + + for (int j = 0; j < 4; j++) + // push args[i+2][j+1] onto the stack + lua_rawgeti(L, i + 2, j + 1); + + unsigned char r = (unsigned char) luaL_checkinteger(L, -4); + unsigned char g = (unsigned char) luaL_checkinteger(L, -3); + unsigned char b = (unsigned char) luaL_checkinteger(L, -2); + unsigned char a = (unsigned char) luaL_optinteger(L, -1, 255); + + // pop the color components from the stack + lua_pop(L, 4); + + colors[i] = Color(r, g, b, a); + } + + t->setColor(colors); + } + else // setColors(r,g,b,a, r,g,b,a, ...) + { + int cargs = lua_gettop(L) - 1; + size_t nColors = (cargs + 3) / 4; // nColors = ceil(color_args / 4) + + if (cargs != 3 && (cargs % 4 != 0 || cargs == 0)) + return luaL_error(L, "Expected red, green, blue, and alpha. Only got %d of 4 components.", cargs % 4); + + if (nColors > 8) + return luaL_error(L, "At most eight (8) colors may be used."); + + if (nColors == 1) + { + unsigned char r = (unsigned char) luaL_checkinteger(L, 2); + unsigned char g = (unsigned char) luaL_checkinteger(L, 3); + unsigned char b = (unsigned char) luaL_checkinteger(L, 4); + unsigned char a = (unsigned char) luaL_optinteger(L, 5, 255); + t->setColor(Color(r,g,b,a)); + } + else + { + std::vector colors(nColors); + for (size_t i = 0; i < nColors; ++i) + { + unsigned char r = (unsigned char) luaL_checkinteger(L, 1 + i*4 + 1); + unsigned char g = (unsigned char) luaL_checkinteger(L, 1 + i*4 + 2); + unsigned char b = (unsigned char) luaL_checkinteger(L, 1 + i*4 + 3); + unsigned char a = (unsigned char) luaL_checkinteger(L, 1 + i*4 + 4); + colors[i] = Color(r,g,b,a); + } + t->setColor(colors); + } + } + + return 0; } -int w_ParticleSystem_getDirection(lua_State *L) +int w_ParticleSystem_getColors(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->getDirection()); - return 1; + + const std::vector &colors =t->getColor(); + + for (size_t i = 0; i < colors.size(); i++) + { + lua_createtable(L, 4, 0); + + lua_pushinteger(L, colors[i].r); + lua_rawseti(L, -2, 1); + lua_pushinteger(L, colors[i].g); + lua_rawseti(L, -2, 2); + lua_pushinteger(L, colors[i].b); + lua_rawseti(L, -2, 3); + lua_pushinteger(L, colors[i].a); + lua_rawseti(L, -2, 4); + } + + return colors.size(); } -int w_ParticleSystem_getSpread(lua_State *L) +int w_ParticleSystem_getCount(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->getSpread()); - return 1; -} - -int w_ParticleSystem_getOffsetX(lua_State *L) -{ - ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->getOffsetX()); - return 1; -} - -int w_ParticleSystem_getOffsetY(lua_State *L) -{ - ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->getOffsetY()); - return 1; -} - -int w_ParticleSystem_count(lua_State *L) -{ - ParticleSystem *t = luax_checkparticlesystem(L, 1); - lua_pushnumber(L, t->count()); + lua_pushnumber(L, t->getCount()); return 1; } @@ -372,6 +595,14 @@ int w_ParticleSystem_reset(lua_State *L) return 0; } +int w_ParticleSystem_emit(lua_State *L) +{ + ParticleSystem *t = luax_checkparticlesystem(L, 1); + int num = luaL_checkint(L, 2); + t->emit(num); + return 0; +} + int w_ParticleSystem_isActive(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); @@ -379,17 +610,17 @@ int w_ParticleSystem_isActive(lua_State *L) return 1; } -int w_ParticleSystem_isEmpty(lua_State *L) +int w_ParticleSystem_isPaused(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - luax_pushboolean(L, t->isEmpty()); + luax_pushboolean(L, t->isPaused()); return 1; } -int w_ParticleSystem_isFull(lua_State *L) +int w_ParticleSystem_isStopped(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); - luax_pushboolean(L, t->isFull()); + luax_pushboolean(L, t->isStopped()); return 1; } @@ -403,44 +634,64 @@ int w_ParticleSystem_update(lua_State *L) static const luaL_Reg functions[] = { - { "setSprite", w_ParticleSystem_setSprite }, + { "clone", w_ParticleSystem_clone }, + { "setTexture", w_ParticleSystem_setTexture }, + { "getTexture", w_ParticleSystem_getTexture }, { "setBufferSize", w_ParticleSystem_setBufferSize }, + { "getBufferSize", w_ParticleSystem_getBufferSize }, + { "setInsertMode", w_ParticleSystem_setInsertMode }, + { "getInsertMode", w_ParticleSystem_getInsertMode }, { "setEmissionRate", w_ParticleSystem_setEmissionRate }, - { "setLifetime", w_ParticleSystem_setLifetime }, - { "setParticleLife", w_ParticleSystem_setParticleLife }, + { "getEmissionRate", w_ParticleSystem_getEmissionRate }, + { "setEmitterLifetime", w_ParticleSystem_setEmitterLifetime }, + { "getEmitterLifetime", w_ParticleSystem_getEmitterLifetime }, + { "setParticleLifetime", w_ParticleSystem_setParticleLifetime }, + { "getParticleLifetime", w_ParticleSystem_getParticleLifetime }, { "setPosition", w_ParticleSystem_setPosition }, - { "setAreaSpread", w_ParticleSystem_setAreaSpread }, - { "setDirection", w_ParticleSystem_setDirection }, - { "setSpread", w_ParticleSystem_setSpread }, - { "setRelativeDirection", w_ParticleSystem_setRelativeDirection }, - { "setSpeed", w_ParticleSystem_setSpeed }, - { "setGravity", w_ParticleSystem_setGravity }, - { "setRadialAcceleration", w_ParticleSystem_setRadialAcceleration }, - { "setTangentialAcceleration", w_ParticleSystem_setTangentialAcceleration }, - { "setSizes", w_ParticleSystem_setSizes }, - { "setSizeVariation", w_ParticleSystem_setSizeVariation }, - { "setRotation", w_ParticleSystem_setRotation }, - { "setSpin", w_ParticleSystem_setSpin }, - { "setSpinVariation", w_ParticleSystem_setSpinVariation }, - { "setColors", w_ParticleSystem_setColors }, - { "setOffset", w_ParticleSystem_setOffset }, - { "getX", w_ParticleSystem_getX }, - { "getY", w_ParticleSystem_getY }, { "getPosition", w_ParticleSystem_getPosition }, + { "setAreaSpread", w_ParticleSystem_setAreaSpread }, { "getAreaSpread", w_ParticleSystem_getAreaSpread }, + { "setDirection", w_ParticleSystem_setDirection }, { "getDirection", w_ParticleSystem_getDirection }, + { "setSpread", w_ParticleSystem_setSpread }, { "getSpread", w_ParticleSystem_getSpread }, - { "getOffsetX", w_ParticleSystem_getOffsetX }, - { "getOffsetY", w_ParticleSystem_getOffsetY }, - { "count", w_ParticleSystem_count }, + { "setSpeed", w_ParticleSystem_setSpeed }, + { "getSpeed", w_ParticleSystem_getSpeed }, + { "setLinearAcceleration", w_ParticleSystem_setLinearAcceleration }, + { "getLinearAcceleration", w_ParticleSystem_getLinearAcceleration }, + { "setRadialAcceleration", w_ParticleSystem_setRadialAcceleration }, + { "getRadialAcceleration", w_ParticleSystem_getRadialAcceleration }, + { "setTangentialAcceleration", w_ParticleSystem_setTangentialAcceleration }, + { "getTangentialAcceleration", w_ParticleSystem_getTangentialAcceleration }, + { "setSizes", w_ParticleSystem_setSizes }, + { "getSizes", w_ParticleSystem_getSizes }, + { "setSizeVariation", w_ParticleSystem_setSizeVariation }, + { "getSizeVariation", w_ParticleSystem_getSizeVariation }, + { "setRotation", w_ParticleSystem_setRotation }, + { "getRotation", w_ParticleSystem_getRotation }, + { "setSpin", w_ParticleSystem_setSpin }, + { "getSpin", w_ParticleSystem_getSpin }, + { "setSpinVariation", w_ParticleSystem_setSpinVariation }, + { "getSpinVariation", w_ParticleSystem_getSpinVariation }, + { "setColors", w_ParticleSystem_setColors }, + { "getColors", w_ParticleSystem_getColors }, + { "setOffset", w_ParticleSystem_setOffset }, + { "getOffset", w_ParticleSystem_getOffset }, + { "getCount", w_ParticleSystem_getCount }, { "start", w_ParticleSystem_start }, { "stop", w_ParticleSystem_stop }, { "pause", w_ParticleSystem_pause }, { "reset", w_ParticleSystem_reset }, + { "emit", w_ParticleSystem_emit }, { "isActive", w_ParticleSystem_isActive }, - { "isEmpty", w_ParticleSystem_isEmpty }, - { "isFull", w_ParticleSystem_isFull }, + { "isPaused", w_ParticleSystem_isPaused }, + { "isStopped", w_ParticleSystem_isStopped }, { "update", w_ParticleSystem_update }, + + // Deprecated since 0.9.1. + { "setImage", w_ParticleSystem_setTexture }, + { "getImage", w_ParticleSystem_getTexture }, + { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.h b/src/modules/graphics/opengl/wrap_ParticleSystem.h index 7fd7cf662..849374745 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.h +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,7 +23,6 @@ // LOVE #include "common/runtime.h" -#include "wrap_Image.h" #include "ParticleSystem.h" namespace love @@ -34,41 +33,58 @@ namespace opengl { ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx); -int w_ParticleSystem_setSprite(lua_State *L); +int w_ParticleSystem_clone(lua_State *L); +int w_ParticleSystem_setTexture(lua_State *L); +int w_ParticleSystem_getTexture(lua_State *L); int w_ParticleSystem_setBufferSize(lua_State *L); +int w_ParticleSystem_getBufferSize(lua_State *L); +int w_ParticleSystem_setInsertMode(lua_State *L); +int w_ParticleSystem_getInsertMode(lua_State *L); int w_ParticleSystem_setEmissionRate(lua_State *L); -int w_ParticleSystem_setLifetime(lua_State *L); -int w_ParticleSystem_setParticleLife(lua_State *L); +int w_ParticleSystem_getEmissionRate(lua_State *L); +int w_ParticleSystem_setEmitterLifetime(lua_State *L); +int w_ParticleSystem_getEmitterLifetime(lua_State *L); +int w_ParticleSystem_setParticleLifetime(lua_State *L); +int w_ParticleSystem_getParticleLifetime(lua_State *L); int w_ParticleSystem_setPosition(lua_State *L); -int w_ParticleSystem_setDirection(lua_State *L); -int w_ParticleSystem_setSpread(lua_State *L); -int w_ParticleSystem_setRelativeDirection(lua_State *L); -int w_ParticleSystem_setSpeed(lua_State *L); -int w_ParticleSystem_setGravity(lua_State *L); -int w_ParticleSystem_setRadialAcceleration(lua_State *L); -int w_ParticleSystem_setTangentialAcceleration(lua_State *L); -int w_ParticleSystem_setSizes(lua_State *L); -int w_ParticleSystem_setSizeVariation(lua_State *L); -int w_ParticleSystem_setRotation(lua_State *L); -int w_ParticleSystem_setSpin(lua_State *L); -int w_ParticleSystem_setSpinVariation(lua_State *L); -int w_ParticleSystem_setColors(lua_State *L); -int w_ParticleSystem_setOffset(lua_State *L); -int w_ParticleSystem_getX(lua_State *L); -int w_ParticleSystem_getY(lua_State *L); int w_ParticleSystem_getPosition(lua_State *L); +int w_ParticleSystem_setAreaSpread(lua_State *L); +int w_ParticleSystem_getAreaSpread(lua_State *L); +int w_ParticleSystem_setDirection(lua_State *L); int w_ParticleSystem_getDirection(lua_State *L); +int w_ParticleSystem_setSpread(lua_State *L); int w_ParticleSystem_getSpread(lua_State *L); -int w_ParticleSystem_getOffsetX(lua_State *L); -int w_ParticleSystem_getOffsetY(lua_State *L); -int w_ParticleSystem_count(lua_State *L); +int w_ParticleSystem_setSpeed(lua_State *L); +int w_ParticleSystem_getSpeed(lua_State *L); +int w_ParticleSystem_setLinearAcceleration(lua_State *L); +int w_ParticleSystem_getLinearAcceleration(lua_State *L); +int w_ParticleSystem_setRadialAcceleration(lua_State *L); +int w_ParticleSystem_getRadialAcceleration(lua_State *L); +int w_ParticleSystem_setTangentialAcceleration(lua_State *L); +int w_ParticleSystem_getTangentialAcceleration(lua_State *L); +int w_ParticleSystem_setSizes(lua_State *L); +int w_ParticleSystem_getSizes(lua_State *L); +int w_ParticleSystem_setSizeVariation(lua_State *L); +int w_ParticleSystem_getSizeVariation(lua_State *L); +int w_ParticleSystem_setRotation(lua_State *L); +int w_ParticleSystem_getRotation(lua_State *L); +int w_ParticleSystem_setSpin(lua_State *L); +int w_ParticleSystem_getSpin(lua_State *L); +int w_ParticleSystem_setSpinVariation(lua_State *L); +int w_ParticleSystem_getSpinVariation(lua_State *L); +int w_ParticleSystem_setColors(lua_State *L); +int w_ParticleSystem_getColors(lua_State *L); +int w_ParticleSystem_setOffset(lua_State *L); +int w_ParticleSystem_getOffset(lua_State *L); +int w_ParticleSystem_getCount(lua_State *L); int w_ParticleSystem_start(lua_State *L); int w_ParticleSystem_stop(lua_State *L); int w_ParticleSystem_pause(lua_State *L); int w_ParticleSystem_reset(lua_State *L); +int w_ParticleSystem_emit(lua_State *L); int w_ParticleSystem_isActive(lua_State *L); -int w_ParticleSystem_isEmpty(lua_State *L); -int w_ParticleSystem_isFull(lua_State *L); +int w_ParticleSystem_isPaused(lua_State *L); +int w_ParticleSystem_isStopped(lua_State *L); int w_ParticleSystem_update(lua_State *L); extern "C" int luaopen_particlesystem(lua_State *L); diff --git a/src/modules/graphics/opengl/wrap_Quad.cpp b/src/modules/graphics/opengl/wrap_Quad.cpp index e091bdbe3..1713ff3d1 100644 --- a/src/modules/graphics/opengl/wrap_Quad.cpp +++ b/src/modules/graphics/opengl/wrap_Quad.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -28,33 +28,36 @@ namespace graphics namespace opengl { -Quad *luax_checkframe(lua_State *L, int idx) +Quad *luax_checkquad(lua_State *L, int idx) { return luax_checktype(L, idx, "Quad", GRAPHICS_QUAD_T); } -int w_Quad_flip(lua_State *L) -{ - Quad *quad = luax_checktype(L, 1, "Quad", GRAPHICS_QUAD_T); - quad->flip(luax_toboolean(L, 2), luax_toboolean(L, 3)); - return 0; -} - int w_Quad_setViewport(lua_State *L) { - Quad *quad = luax_checktype(L, 1, "Quad", GRAPHICS_QUAD_T); + Quad *quad = luax_checkquad(L, 1); + Quad::Viewport v; v.x = (float) luaL_checknumber(L, 2); v.y = (float) luaL_checknumber(L, 3); v.w = (float) luaL_checknumber(L, 4); v.h = (float) luaL_checknumber(L, 5); - quad->setViewport(v); + + if (lua_isnoneornil(L, 6)) + quad->setViewport(v); + else + { + float sw = (float) luaL_checknumber(L, 6); + float sh = (float) luaL_checknumber(L, 7); + quad->refresh(v, sw, sh); + } + return 0; } int w_Quad_getViewport(lua_State *L) { - Quad *quad = luax_checktype(L, 1, "Quad", GRAPHICS_QUAD_T); + Quad *quad = luax_checkquad(L, 1); Quad::Viewport v = quad->getViewport(); lua_pushnumber(L, v.x); lua_pushnumber(L, v.y); @@ -63,17 +66,16 @@ int w_Quad_getViewport(lua_State *L) return 4; } -static const luaL_Reg w_Quad_functions[] = +static const luaL_Reg functions[] = { - { "flip", w_Quad_flip }, { "setViewport", w_Quad_setViewport }, { "getViewport", w_Quad_getViewport }, { 0, 0 } }; -extern "C" int luaopen_frame(lua_State *L) +extern "C" int luaopen_quad(lua_State *L) { - return luax_register_type(L, "Quad", w_Quad_functions); + return luax_register_type(L, "Quad", functions); } } // opengl diff --git a/src/modules/graphics/opengl/wrap_Quad.h b/src/modules/graphics/opengl/wrap_Quad.h index 508bc1f3b..3c27cf7d2 100644 --- a/src/modules/graphics/opengl/wrap_Quad.h +++ b/src/modules/graphics/opengl/wrap_Quad.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,7 +23,7 @@ // LOVE #include "common/runtime.h" -#include "Quad.h" +#include "graphics/Quad.h" namespace love { @@ -32,11 +32,10 @@ namespace graphics namespace opengl { -Quad *luax_checkframe(lua_State *L, int idx); -int w_Quad_flip(lua_State *L); +Quad *luax_checkquad(lua_State *L, int idx); int w_Quad_setViewport(lua_State *L); int w_Quad_getViewport(lua_State *L); -extern "C" int luaopen_frame(lua_State *L); +extern "C" int luaopen_quad(lua_State *L); } // opengl } // graphics diff --git a/src/modules/graphics/opengl/wrap_Shader.cpp b/src/modules/graphics/opengl/wrap_Shader.cpp index a2e424fb7..dde23fde5 100644 --- a/src/modules/graphics/opengl/wrap_Shader.cpp +++ b/src/modules/graphics/opengl/wrap_Shader.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,8 +19,7 @@ **/ #include "wrap_Shader.h" -#include "wrap_Image.h" -#include "wrap_Canvas.h" +#include "wrap_Texture.h" #include #include @@ -43,78 +42,109 @@ int w_Shader_getWarnings(lua_State *L) return 1; } -static int _sendScalars(lua_State *L, Shader *shader, const char *name, int count) +template +static T *_getScalars(lua_State *L, int count, size_t &dimension) { - float *values = new float[count]; + dimension = 1; + T *values = new T[count]; + for (int i = 0; i < count; ++i) { if (lua_isnumber(L, 3 + i)) - values[i] = (float)lua_tonumber(L, 3 + i); + values[i] = static_cast(lua_tonumber(L, 3 + i)); else if (lua_isboolean(L, 3 + i)) - values[i] = (float)lua_toboolean(L, 3 + i); + values[i] = static_cast(lua_toboolean(L, 3 + i)); else { delete[] values; - return luaL_typerror(L, 3 + i, "number or boolean"); + luax_typerror(L, 3 + i, "number or boolean"); + return 0; } - values[i] = (float)lua_tonumber(L, 3 + i); } - try - { - shader->sendFloat(name, 1, values, count); - } - catch(love::Exception &e) - { - delete[] values; - return luaL_error(L, "%s", e.what()); - } - - delete[] values; - return 0; + return values; } -static int _sendVectors(lua_State *L, Shader *shader, const char *name, int count) +template +static T *_getVectors(lua_State *L, int count, size_t &dimension) { - size_t dimension = lua_objlen(L, 3); - float *values = new float[count * dimension]; + dimension = lua_objlen(L, 3); + T *values = new T[count * dimension]; for (int i = 0; i < count; ++i) { if (!lua_istable(L, 3 + i)) { delete[] values; - return luaL_typerror(L, 3 + i, "table"); + luax_typerror(L, 3 + i, "table"); + return 0; } if (lua_objlen(L, 3 + i) != dimension) { delete[] values; - return luaL_error(L, "Error in argument %d: Expected table size %d, got %d.", - 3+i, dimension, lua_objlen(L, 3+i)); + luaL_error(L, "Error in argument %d: Expected table size %d, got %d.", + 3+i, dimension, lua_objlen(L, 3+i)); + return 0; } for (size_t k = 1; k <= dimension; ++k) { lua_rawgeti(L, 3 + i, k); - if (lua_isboolean(L, -1)) - values[i * dimension + k - 1] = (float)lua_toboolean(L, -1); + if (lua_isnumber(L, -1)) + values[i * dimension + k - 1] = static_cast(lua_tonumber(L, -1)); + else if (lua_isboolean(L, -1)) + values[i * dimension + k - 1] = static_cast(lua_toboolean(L, -1)); else - values[i * dimension + k - 1] = (float)lua_tonumber(L, -1); + { + delete[] values; + luax_typerror(L, -1, "number or boolean"); + return 0; + } } lua_pop(L, int(dimension)); } + return values; +} + +int w_Shader_sendInt(lua_State *L) +{ + Shader *shader = luax_checkshader(L, 1); + const char *name = luaL_checkstring(L, 2); + int count = lua_gettop(L) - 2; + + if (count < 1) + return luaL_error(L, "No variable to send."); + + int *values = 0; + size_t dimension = 1; + + if (lua_isnumber(L, 3) || lua_isboolean(L, 3)) + values = _getScalars(L, count, dimension); + else if (lua_istable(L, 3)) + values = _getVectors(L, count, dimension); + else + return luax_typerror(L, 3, "number, boolean, or table"); + + if (!values) + return luaL_error(L, "Error in arguments."); + + bool should_error = false; try { - shader->sendFloat(name, dimension, values, count); + shader->sendInt(name, dimension, values, count); } - catch(love::Exception &e) + catch (love::Exception &e) { - delete[] values; - return luaL_error(L, "%s", e.what()); + should_error = true; + lua_pushstring(L, e.what()); } delete[] values; + + if (should_error) + return luaL_error(L, "%s", lua_tostring(L, -1)); + return 0; } @@ -127,12 +157,36 @@ int w_Shader_sendFloat(lua_State *L) if (count < 1) return luaL_error(L, "No variable to send."); - if (lua_isnumber(L, 3) || lua_isboolean(L, 3)) - return _sendScalars(L, shader, name, count); - else if (lua_istable(L, 3)) - return _sendVectors(L, shader, name, count); + float *values = 0; + size_t dimension = 1; - return luaL_typerror(L, 3, "number, boolean, or table"); + if (lua_isnumber(L, 3) || lua_isboolean(L, 3)) + values = _getScalars(L, count, dimension); + else if (lua_istable(L, 3)) + values = _getVectors(L, count, dimension); + else + return luax_typerror(L, 3, "number, boolean, or table"); + + if (!values) + return luaL_error(L, "Error in arguments."); + + bool should_error = false; + try + { + shader->sendFloat(name, dimension, values, count); + } + catch (love::Exception &e) + { + should_error = true; + lua_pushstring(L, e.what()); + } + + delete[] values; + + if (should_error) + return luaL_error(L, "%s", lua_tostring(L, -1)); + + return 0; } int w_Shader_sendMatrix(lua_State *L) @@ -142,7 +196,7 @@ int w_Shader_sendMatrix(lua_State *L) const char *name = luaL_checkstring(L, 2); if (!lua_istable(L, 3)) - return luaL_typerror(L, 3, "matrix table"); + return luax_typerror(L, 3, "matrix table"); lua_getfield(L, 3, "dimension"); int dimension = lua_tointeger(L, -1); @@ -150,7 +204,7 @@ int w_Shader_sendMatrix(lua_State *L) if (dimension < 2 || dimension > 4) return luaL_error(L, "Invalid matrix size: %dx%d (only 2x2, 3x3 and 4x4 matrices are supported).", - count, count); + dimension, dimension); float *values = new float[dimension * dimension * count]; for (int i = 0; i < count; ++i) @@ -178,64 +232,134 @@ int w_Shader_sendMatrix(lua_State *L) lua_pop(L, 1 + dimension); } + bool should_error = false; + try { shader->sendMatrix(name, dimension, values, count); } catch(love::Exception &e) { - delete[] values; - return luaL_error(L, "%s", e.what()); + should_error = true; + lua_pushstring(L, e.what()); } delete[] values; + + if (should_error) + return luaL_error(L, "%s", lua_tostring(L, -1)); + return 0; } -int w_Shader_sendImage(lua_State *L) +int w_Shader_sendTexture(lua_State *L) { Shader *shader = luax_checkshader(L, 1); const char *name = luaL_checkstring(L, 2); - Image *img = luax_checkimage(L, 3); - - try - { - shader->sendImage(name, *img); - } - catch(love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + Texture *texture = luax_checktexture(L, 3); + EXCEPT_GUARD(shader->sendTexture(name, texture);) return 0; } -int w_Shader_sendCanvas(lua_State *L) +// Convert matrices on the stack for use with sendMatrix. +static void w_convertMatrices(lua_State *L, int idx) { - Shader *shader = luax_checkshader(L, 1); - const char *name = luaL_checkstring(L, 2); - Canvas *canvas = luax_checkcanvas(L, 3); + int matrixcount = lua_gettop(L) - (idx - 1); - try + for (int matrix = idx; matrix < idx + matrixcount; matrix++) { - shader->sendCanvas(name, *canvas); - } - catch(love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + luaL_checktype(L, matrix, LUA_TTABLE); + int dimension = lua_objlen(L, matrix); - return 0; + int newi = 1; + lua_createtable(L, dimension * dimension, 0); + + // Collapse {{a,b,c}, {d,e,f}, ...} to {a,b,c, d,e,f, ...} + for (size_t i = 1; i <= lua_objlen(L, matrix); i++) + { + // Push args[matrix][i] onto the stack. + lua_rawgeti(L, matrix, i); + luaL_checktype(L, -1, LUA_TTABLE); + + for (size_t j = 1; j <= lua_objlen(L, -1); j++) + { + // Push args[matrix[i][j] onto the stack. + lua_rawgeti(L, -1, j); + luaL_checktype(L, -1, LUA_TNUMBER); + + // newtable[newi] = args[matrix][i][j] + lua_rawseti(L, -3, newi++); + } + + lua_pop(L, 1); + } + + // newtable.dimension = #args[matrix] + lua_pushinteger(L, dimension); + lua_setfield(L, -2, "dimension"); + + // Replace args[i] with the new table + lua_replace(L, matrix); + } } +int w_Shader_send(lua_State *L) +{ + int ttype = lua_type(L, 3); + Proxy *p = nullptr; + + switch (ttype) + { + case LUA_TNUMBER: + case LUA_TBOOLEAN: + // Scalar float/boolean. + return w_Shader_sendFloat(L); + break; + case LUA_TUSERDATA: + // Texture (Image or Canvas). + p = (Proxy *) lua_touserdata(L, 3); + + if (p->flags[GRAPHICS_TEXTURE_ID]) + return w_Shader_sendTexture(L); + + break; + case LUA_TTABLE: + // Vector or Matrix. + lua_rawgeti(L, 3, 1); + ttype = lua_type(L, -1); + lua_pop(L, 1); + + if (ttype == LUA_TNUMBER || ttype == LUA_TBOOLEAN) + return w_Shader_sendFloat(L); + else if (ttype == LUA_TTABLE) + { + w_convertMatrices(L, 3); + return w_Shader_sendMatrix(L); + } + + break; + default: + break; + } + + return luaL_argerror(L, 3, "number, boolean, table, image, or canvas expected"); +} static const luaL_Reg functions[] = { { "getWarnings", w_Shader_getWarnings }, + { "sendInt", w_Shader_sendInt }, + { "sendBoolean", w_Shader_sendInt }, { "sendFloat", w_Shader_sendFloat }, { "sendMatrix", w_Shader_sendMatrix }, - { "sendImage", w_Shader_sendImage }, - { "sendCanvas", w_Shader_sendCanvas }, + { "sendTexture", w_Shader_sendTexture }, + { "send", w_Shader_send }, + + // Deprecated since 0.9.1. + { "sendImage", w_Shader_sendTexture }, + { "sendCanvas", w_Shader_sendTexture }, + { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Shader.h b/src/modules/graphics/opengl/wrap_Shader.h index b3a92f887..be7b81db4 100644 --- a/src/modules/graphics/opengl/wrap_Shader.h +++ b/src/modules/graphics/opengl/wrap_Shader.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,9 +33,11 @@ namespace opengl Shader *luax_checkshader(lua_State *L, int idx); int w_Shader_getWarnings(lua_State *L); +int w_Shader_sendInt(lua_State *L); int w_Shader_sendFloat(lua_State *L); int w_Shader_sendMatrix(lua_State *L); -int w_Shader_sendImage(lua_State *L); +int w_Shader_sendTexture(lua_State *L); +int w_Shader_send(lua_State *L); extern "C" int luaopen_shader(lua_State *L); } // opengl diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp index e31c865b9..68cb07853 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,8 +18,14 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "Image.h" +// LOVE #include "wrap_SpriteBatch.h" +#include "Image.h" +#include "Canvas.h" +#include "wrap_Texture.h" + +// C++ +#include namespace love { @@ -36,68 +42,72 @@ SpriteBatch *luax_checkspritebatch(lua_State *L, int idx) int w_SpriteBatch_add(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - float x = (float)luaL_optnumber(L, 2, 0.0f); - float y = (float)luaL_optnumber(L, 3, 0.0f); - float angle = (float)luaL_optnumber(L, 4, 0.0f); - float sx = (float)luaL_optnumber(L, 5, 1.0f); - float sy = (float)luaL_optnumber(L, 6, sx); - float ox = (float)luaL_optnumber(L, 7, 0); - float oy = (float)luaL_optnumber(L, 8, 0); - float kx = (float)luaL_optnumber(L, 9, 0); - float ky = (float)luaL_optnumber(L, 10, 0); - lua_pushnumber(L, t->add(x, y, angle, sx, sy, ox, oy, kx, ky)); - return 1; -} + Quad *quad = nullptr; + int startidx = 2; -int w_SpriteBatch_addq(lua_State *L) -{ - SpriteBatch *t = luax_checkspritebatch(L, 1); - Quad *q = luax_checktype(L, 2, "Quad", GRAPHICS_QUAD_T); - float x = (float)luaL_optnumber(L, 3, 0.0f); - float y = (float)luaL_optnumber(L, 4, 0.0f); - float angle = (float)luaL_optnumber(L, 5, 0.0f); - float sx = (float)luaL_optnumber(L, 6, 1.0f); - float sy = (float)luaL_optnumber(L, 7, sx); - float ox = (float)luaL_optnumber(L, 8, 0); - float oy = (float)luaL_optnumber(L, 9, 0); - float kx = (float)luaL_optnumber(L, 10, 0); - float ky = (float)luaL_optnumber(L, 11, 0); - lua_pushnumber(L, t->addq(q, x, y, angle, sx, sy, ox, oy, kx, ky)); + if (luax_istype(L, 2, GRAPHICS_QUAD_T)) + { + quad = luax_totype(L, 2, "Quad", GRAPHICS_QUAD_T); + startidx = 3; + } + else if (lua_isnil(L, 2) && !lua_isnoneornil(L, 3)) + return luax_typerror(L, 2, "Quad"); + + float x = (float) luaL_optnumber(L, startidx + 0, 0.0); + float y = (float) luaL_optnumber(L, startidx + 1, 0.0); + float a = (float) luaL_optnumber(L, startidx + 2, 0.0); + float sx = (float) luaL_optnumber(L, startidx + 3, 1.0); + float sy = (float) luaL_optnumber(L, startidx + 4, sx); + float ox = (float) luaL_optnumber(L, startidx + 5, 0.0); + float oy = (float) luaL_optnumber(L, startidx + 6, 0.0); + float kx = (float) luaL_optnumber(L, startidx + 7, 0.0); + float ky = (float) luaL_optnumber(L, startidx + 8, 0.0); + + int id = 0; + EXCEPT_GUARD( + if (quad) + id = t->addq(quad, x, y, a, sx, sy, ox, oy, kx, ky); + else + id = t->add(x, y, a, sx, sy, ox, oy, kx, ky); + ) + + lua_pushinteger(L, id); return 1; } int w_SpriteBatch_set(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - int index = luaL_checkinteger(L, 2); - float x = (float)luaL_optnumber(L, 3, 0.0f); - float y = (float)luaL_optnumber(L, 4, 0.0f); - float angle = (float)luaL_optnumber(L, 5, 0.0f); - float sx = (float)luaL_optnumber(L, 6, 1.0f); - float sy = (float)luaL_optnumber(L, 7, sx); - float ox = (float)luaL_optnumber(L, 8, 0); - float oy = (float)luaL_optnumber(L, 9, 0); - float kx = (float)luaL_optnumber(L, 10, 0); - float ky = (float)luaL_optnumber(L, 11, 0); - t->add(x, y, angle, sx, sy, ox, oy, kx, ky, index); - return 0; -} + int id = luaL_checkinteger(L, 2); + + Quad *quad = nullptr; + int startidx = 3; + + if (luax_istype(L, 3, GRAPHICS_QUAD_T)) + { + quad = luax_totype(L, 3, "Quad", GRAPHICS_QUAD_T); + startidx = 4; + } + else if (lua_isnil(L, 3) && !lua_isnoneornil(L, 4)) + return luax_typerror(L, 3, "Quad"); + + float x = (float) luaL_optnumber(L, startidx + 0, 0.0); + float y = (float) luaL_optnumber(L, startidx + 1, 0.0); + float a = (float) luaL_optnumber(L, startidx + 2, 0.0); + float sx = (float) luaL_optnumber(L, startidx + 3, 1.0); + float sy = (float) luaL_optnumber(L, startidx + 4, sx); + float ox = (float) luaL_optnumber(L, startidx + 5, 0.0); + float oy = (float) luaL_optnumber(L, startidx + 6, 0.0); + float kx = (float) luaL_optnumber(L, startidx + 7, 0.0); + float ky = (float) luaL_optnumber(L, startidx + 8, 0.0); + + EXCEPT_GUARD( + if (quad) + t->addq(quad, x, y, a, sx, sy, ox, oy, kx, ky, id); + else + t->add(x, y, a, sx, sy, ox, oy, kx, ky, id); + ) -int w_SpriteBatch_setq(lua_State *L) -{ - SpriteBatch *t = luax_checkspritebatch(L, 1); - int index = luaL_checkinteger(L, 2); - Quad *q = luax_checktype(L, 3, "Quad", GRAPHICS_QUAD_T); - float x = (float)luaL_optnumber(L, 4, 0.0f); - float y = (float)luaL_optnumber(L, 5, 0.0f); - float angle = (float)luaL_optnumber(L, 6, 0.0f); - float sx = (float)luaL_optnumber(L, 7, 1.0f); - float sy = (float)luaL_optnumber(L, 8, sx); - float ox = (float)luaL_optnumber(L, 9, 0); - float oy = (float)luaL_optnumber(L, 10, 0); - float kx = (float)luaL_optnumber(L, 11, 0); - float ky = (float)luaL_optnumber(L, 12, 0); - t->addq(q, x, y, angle, sx, sy, ox, oy, kx, ky, index); return 0; } @@ -111,14 +121,7 @@ int w_SpriteBatch_clear(lua_State *L) int w_SpriteBatch_bind(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - try - { - t->lock(); - } - catch (love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(t->lock();) return 0; } @@ -129,20 +132,31 @@ int w_SpriteBatch_unbind(lua_State *L) return 0; } -int w_SpriteBatch_setImage(lua_State *L) +int w_SpriteBatch_setTexture(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - Image *image = luax_checktype(L, 2, "Image", GRAPHICS_IMAGE_T); - t->setImage(image); + Texture *tex = luax_checktexture(L, 2); + t->setTexture(tex); return 0; } -int w_SpriteBatch_getImage(lua_State *L) +int w_SpriteBatch_getTexture(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - Image *image = t->getImage(); - image->retain(); - luax_newtype(L, "Image", GRAPHICS_IMAGE_T, (void *)image); + Texture *tex = t->getTexture(); + tex->retain(); + + // FIXME: big hack right here. + if (typeid(*tex) == typeid(Image)) + luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, tex); + else if (typeid(*tex) == typeid(Canvas)) + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, tex); + else + { + tex->release(); + return luaL_error(L, "Unable to determine texture type."); + } + return 1; } @@ -158,25 +172,22 @@ int w_SpriteBatch_setColor(lua_State *L) } 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); + for (int i = 1; i <= 4; i++) + lua_rawgeti(L, 2, i); + + c.r = (unsigned char) luaL_checkinteger(L, -4); + c.g = (unsigned char) luaL_checkinteger(L, -3); + c.b = (unsigned char) luaL_checkinteger(L, -2); + c.a = (unsigned char) luaL_optinteger(L, -1, 255); + + lua_pop(L, 4); } else { - c.r = (unsigned char)luaL_checkint(L, 2); - c.g = (unsigned char)luaL_checkint(L, 3); - c.b = (unsigned char)luaL_checkint(L, 4); - c.a = (unsigned char)luaL_optint(L, 5, 255); + c.r = (unsigned char)luaL_checkinteger(L, 2); + c.g = (unsigned char)luaL_checkinteger(L, 3); + c.b = (unsigned char)luaL_checkinteger(L, 4); + c.a = (unsigned char)luaL_optinteger(L, 5, 255); } t->setColor(c); @@ -184,34 +195,63 @@ int w_SpriteBatch_setColor(lua_State *L) return 0; } -int w_SpriteBatch_isEmpty(lua_State *L) +int w_SpriteBatch_getColor(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - luax_pushboolean(L, t->isEmpty()); + const Color *color = t->getColor(); + + // getColor returns NULL if no color is set. + if (!color) + return 0; + + lua_pushinteger(L, (lua_Integer) color->r); + lua_pushinteger(L, (lua_Integer) color->g); + lua_pushinteger(L, (lua_Integer) color->b); + lua_pushinteger(L, (lua_Integer) color->a); + + return 4; +} + +int w_SpriteBatch_getCount(lua_State *L) +{ + SpriteBatch *t = luax_checkspritebatch(L, 1); + lua_pushinteger(L, t->getCount()); return 1; } -int w_SpriteBatch_isFull(lua_State *L) +int w_SpriteBatch_setBufferSize(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - luax_pushboolean(L, t->isFull()); + int size = luaL_checkint(L, 2); + EXCEPT_GUARD(t->setBufferSize(size);) + return 0; +} + +int w_SpriteBatch_getBufferSize(lua_State *L) +{ + SpriteBatch *t = luax_checkspritebatch(L, 1); + lua_pushinteger(L, t->getBufferSize()); return 1; } static const luaL_Reg functions[] = { { "add", w_SpriteBatch_add }, - { "addq", w_SpriteBatch_addq }, { "set", w_SpriteBatch_set }, - { "setq", w_SpriteBatch_setq }, { "clear", w_SpriteBatch_clear }, { "bind", w_SpriteBatch_bind }, { "unbind", w_SpriteBatch_unbind }, - { "setImage", w_SpriteBatch_setImage }, - { "getImage", w_SpriteBatch_getImage }, + { "setTexture", w_SpriteBatch_setTexture }, + { "getTexture", w_SpriteBatch_getTexture }, { "setColor", w_SpriteBatch_setColor }, - { "isEmpty", w_SpriteBatch_isEmpty }, - { "isFull", w_SpriteBatch_isFull }, + { "getColor", w_SpriteBatch_getColor }, + { "getCount", w_SpriteBatch_getCount }, + { "setBufferSize", w_SpriteBatch_setBufferSize }, + { "getBufferSize", w_SpriteBatch_getBufferSize }, + + // Deprecated since 0.9.1. + { "setImage", w_SpriteBatch_setTexture }, + { "getImage", w_SpriteBatch_getTexture }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.h b/src/modules/graphics/opengl/wrap_SpriteBatch.h index 58e5be8f0..76828b8f2 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.h +++ b/src/modules/graphics/opengl/wrap_SpriteBatch.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,17 +33,19 @@ namespace opengl SpriteBatch *luax_checkspritebatch(lua_State *L, int idx); int w_SpriteBatch_add(lua_State *L); -int w_SpriteBatch_addq(lua_State *L); +int w_SpriteBatch_addg(lua_State *L); int w_SpriteBatch_set(lua_State *L); -int w_SpriteBatch_setq(lua_State *L); +int w_SpriteBatch_setg(lua_State *L); int w_SpriteBatch_clear(lua_State *L); int w_SpriteBatch_bind(lua_State *L); int w_SpriteBatch_unbind(lua_State *L); -int w_SpriteBatch_setImage(lua_State *L); -int w_SpriteBatch_getImage(lua_State *L); +int w_SpriteBatch_setTexture(lua_State *L); +int w_SpriteBatch_getTexture(lua_State *L); int w_SpriteBatch_setColor(lua_State *L); -int w_SpriteBatch_isEmpty(lua_State *L); -int w_SpriteBatch_isFull(lua_State *L); +int w_SpriteBatch_getColor(lua_State *L); +int w_SpriteBatch_getCount(lua_State *L); +int w_SpriteBatch_setBufferSize(lua_State *L); +int w_SpriteBatch_getBufferSize(lua_State *L); extern "C" int luaopen_spritebatch(lua_State *L); diff --git a/src/modules/graphics/opengl/wrap_Texture.cpp b/src/modules/graphics/opengl/wrap_Texture.cpp new file mode 100644 index 000000000..3401115a5 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_Texture.cpp @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "wrap_Texture.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Texture *luax_checktexture(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "Texture", GRAPHICS_TEXTURE_T); +} + +int w_Texture_getWidth(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + lua_pushnumber(L, t->getWidth()); + return 1; +} + +int w_Texture_getHeight(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + lua_pushnumber(L, t->getHeight()); + return 1; +} + +int w_Texture_getDimensions(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + lua_pushnumber(L, t->getWidth()); + lua_pushnumber(L, t->getHeight()); + return 2; +} + +int w_Texture_setFilter(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + Texture::Filter f = t->getFilter(); + + const char *minstr = luaL_checkstring(L, 2); + const char *magstr = luaL_optstring(L, 3, minstr); + + if (!Texture::getConstant(minstr, f.min)) + return luaL_error(L, "Invalid filter mode: %s", minstr); + if (!Texture::getConstant(magstr, f.mag)) + return luaL_error(L, "Invalid filter mode: %s", magstr); + + f.anisotropy = (float) luaL_optnumber(L, 4, 1.0); + + EXCEPT_GUARD(t->setFilter(f);) + return 0; +} + +int w_Texture_getFilter(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + const Texture::Filter f = t->getFilter(); + + const char *minstr = nullptr; + const char *magstr = nullptr; + + if (!Texture::getConstant(f.min, minstr)) + return luaL_error(L, "Unknown filter mode."); + if (!Texture::getConstant(f.mag, magstr)) + return luaL_error(L, "Unknown filter mode."); + + lua_pushstring(L, minstr); + lua_pushstring(L, magstr); + lua_pushnumber(L, f.anisotropy); + return 3; +} + +int w_Texture_setWrap(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + Texture::Wrap w; + + const char *sstr = luaL_checkstring(L, 2); + const char *tstr = luaL_optstring(L, 3, sstr); + + if (!Texture::getConstant(sstr, w.s)) + return luaL_error(L, "Invalid wrap mode: %s", sstr); + if (!Texture::getConstant(tstr, w.t)) + return luaL_error(L, "Invalid wrap mode, %s", tstr); + + t->setWrap(w); + return 0; +} + +int w_Texture_getWrap(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + const Texture::Wrap w = t->getWrap(); + + const char *sstr = nullptr; + const char *tstr = nullptr; + + if (!Texture::getConstant(w.s, sstr)) + return luaL_error(L, "Unknown wrap mode."); + if (!Texture::getConstant(w.t, tstr)) + return luaL_error(L, "Unknown wrap mode."); + + lua_pushstring(L, sstr); + lua_pushstring(L, tstr); + return 2; +} + + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/wrap_Texture.h b/src/modules/graphics/opengl/wrap_Texture.h new file mode 100644 index 000000000..0ba502a62 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_Texture.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_GRAPHICS_OPENGL_WRAP_TEXTURE_H +#define LOVE_GRAPHICS_OPENGL_WRAP_TEXTURE_H + +#include "Texture.h" +#include "common/runtime.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Texture *luax_checktexture(lua_State *L, int idx); +int w_Texture_getWidth(lua_State *L); +int w_Texture_getHeight(lua_State *L); +int w_Texture_getDimensions(lua_State *L); +int w_Texture_setFilter(lua_State *L); +int w_Texture_getFilter(lua_State *L); +int w_Texture_setWrap(lua_State *L); +int w_Texture_getWrap(lua_State *L); + +} // opengl +} // graphics +} // love + +#endif // LOVE_GRAPHICS_OPENGL_WRAP_TEXTURE_H diff --git a/src/modules/image/CompressedData.cpp b/src/modules/image/CompressedData.cpp new file mode 100644 index 000000000..fc85e51f0 --- /dev/null +++ b/src/modules/image/CompressedData.cpp @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "CompressedData.h" + +namespace love +{ +namespace image +{ + +CompressedData::CompressedData() + : format(FORMAT_UNKNOWN) + , data(0) + , dataSize(0) +{ +} + +CompressedData::~CompressedData() +{ +} + +int CompressedData::getSize() const +{ + return int(dataSize); +} + +void *CompressedData::getData() const +{ + return data; +} + +int CompressedData::getMipmapCount() const +{ + return dataImages.size(); +} + +int CompressedData::getSize(int miplevel) const +{ + checkMipmapLevelExists(miplevel); + + return int(dataImages[miplevel].size); +} + +void *CompressedData::getData(int miplevel) const +{ + checkMipmapLevelExists(miplevel); + + return (void *) &dataImages[miplevel].data[0]; +} + +int CompressedData::getWidth(int miplevel) const +{ + checkMipmapLevelExists(miplevel); + + return dataImages[miplevel].width; +} + +int CompressedData::getHeight(int miplevel) const +{ + checkMipmapLevelExists(miplevel); + + return dataImages[miplevel].height; +} + +CompressedData::Format CompressedData::getFormat() const +{ + return format; +} + +void CompressedData::checkMipmapLevelExists(int miplevel) const +{ + if (miplevel < 0 || miplevel >= (int) dataImages.size()) + throw love::Exception("Mipmap level %d does not exist", miplevel); +} + +bool CompressedData::getConstant(const char *in, CompressedData::Format &out) +{ + return formats.find(in, out); +} + +bool CompressedData::getConstant(CompressedData::Format in, const char *&out) +{ + return formats.find(in, out); +} + +StringMap::Entry CompressedData::formatEntries[] = +{ + {"unknown", CompressedData::FORMAT_UNKNOWN}, + {"dxt1", CompressedData::FORMAT_DXT1}, + {"dxt3", CompressedData::FORMAT_DXT3}, + {"dxt5", CompressedData::FORMAT_DXT5}, + {"bc4", CompressedData::FORMAT_BC4}, + {"bc4s", CompressedData::FORMAT_BC4s}, + {"bc5", CompressedData::FORMAT_BC5}, + {"bc5s", CompressedData::FORMAT_BC5s}, +}; + +StringMap CompressedData::formats(CompressedData::formatEntries, sizeof(CompressedData::formatEntries)); + +} // image +} // love diff --git a/src/modules/image/CompressedData.h b/src/modules/image/CompressedData.h new file mode 100644 index 000000000..9df985b4f --- /dev/null +++ b/src/modules/image/CompressedData.h @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_IMAGE_COMPRESSED_DATA_H +#define LOVE_IMAGE_COMPRESSED_DATA_H + +// LOVE +#include "common/Data.h" +#include "common/StringMap.h" +#include "common/int.h" + +// STL +#include + +namespace love +{ +namespace image +{ + +/** + * CompressedData represents image data which is designed to be uploaded to the + * GPU and rendered in its compressed form, without being un-compressed. + * http://renderingpipeline.com/2012/07/texture-compression/ + **/ +class CompressedData : public Data +{ +public: + + // Recognized compressed image data formats. + enum Format + { + FORMAT_UNKNOWN, + FORMAT_DXT1, + FORMAT_DXT3, + FORMAT_DXT5, + FORMAT_BC4, + FORMAT_BC4s, + FORMAT_BC5, + FORMAT_BC5s, + FORMAT_MAX_ENUM + }; + + // Compressed image data can have multiple mipmap levels, each represented + // by a sub-image. + struct SubImage + { + int width, height; + size_t size; + uint8 *data; // Should not have ownership of the data. + }; + + CompressedData(); + virtual ~CompressedData(); + + // Implements Data. + virtual void *getData() const; + virtual int getSize() const; + + /** + * Gets the number of mipmaps in this Compressed Image Data. + * Includes the base image level. + **/ + int getMipmapCount() const; + + /** + * Gets the size in bytes of a sub-image at the specified mipmap level. + **/ + int getSize(int miplevel) const; + + /** + * Gets the byte data of a sub-image at the specified mipmap level. + **/ + void *getData(int miplevel) const; + + /** + * Gets the width of a sub-image at the specified mipmap level. + **/ + int getWidth(int miplevel) const; + + /** + * Gets the height of a sub-image at the specified mipmap level. + **/ + int getHeight(int miplevel) const; + + /** + * Gets the format of the compressed data. + **/ + Format getFormat() const; + + static bool getConstant(const char *in, Format &out); + static bool getConstant(Format in, const char *&out); + +protected: + + Format format; + + // Single block of memory containing all of the sub-images. + uint8 *data; + size_t dataSize; + + // Texture info for each mipmap level. + std::vector dataImages; + + void checkMipmapLevelExists(int miplevel) const; + +private: + + static StringMap::Entry formatEntries[]; + static StringMap formats; + +}; // CompressedData + +} // image +} // love + +#endif // LOVE_IMAGE_COMPRESSED_DATA_H diff --git a/src/modules/image/Image.h b/src/modules/image/Image.h index 533798b85..b95024475 100644 --- a/src/modules/image/Image.h +++ b/src/modules/image/Image.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,6 +26,7 @@ #include "common/Module.h" #include "filesystem/File.h" #include "ImageData.h" +#include "CompressedData.h" namespace love { @@ -34,8 +35,10 @@ namespace image /** * This module is responsible for decoding files such as PNG, GIF, JPEG - * into raw pixel data. This module does not know how to draw images on - * screen; only love.graphics knows that. + * into raw pixel data, as well as parsing compressed formats which are designed + * to be uploaded to the GPU and rendered without being un-compressed. + * This module does not know how to draw images on screen; only love.graphics + * knows that. **/ class Image : public Module { @@ -47,35 +50,43 @@ public: virtual ~Image() {}; /** - * Creates new ImageData from a file. - * @param file The file containing the encoded image data. + * Creates new ImageData from FileData. + * @param data The FileData containing the encoded image data. * @return The new ImageData. **/ - virtual ImageData *newImageData(love::filesystem::File *file) = 0; - - /** - * Creates new ImageData from a raw Data. - * @param data The object containing encoded pixel data. - * @return The new ImageData. - **/ - virtual ImageData *newImageData(Data *data) = 0; + virtual ImageData *newImageData(love::filesystem::FileData *data) = 0; /** * Creates empty ImageData with the given size. - * @param The width of the ImageData. - * @param The height of the ImageData. + * @param width The width of the ImageData. + * @param height The height of the ImageData. * @return The new ImageData. **/ virtual ImageData *newImageData(int width, int height) = 0; /** * Creates empty ImageData with the given size. - * @param The width of the ImageData. - * @param The height of the ImageData. - * @param The data to load into the ImageData. + * @param width The width of the ImageData. + * @param height The height of the ImageData. + * @param data The data to load into the ImageData. + * @param own Whether the new ImageData should take ownership of the data or + * copy it. * @return The new ImageData. **/ - virtual ImageData *newImageData(int width, int height, void *data) = 0; + virtual ImageData *newImageData(int width, int height, void *data, bool own = false) = 0; + + /** + * Creates new CompressedData from FileData. + * @param data The FileData containing the compressed image data. + * @return The new CompressedData. + **/ + virtual CompressedData *newCompressedData(love::filesystem::FileData *data) = 0; + + /** + * Determines whether a FileData is Compressed image data or not. + * @param data The FileData to test. + **/ + virtual bool isCompressed(love::filesystem::FileData *data) = 0; }; // Image diff --git a/src/modules/image/ImageData.cpp b/src/modules/image/ImageData.cpp index a5d4fe5c3..e71f7feb3 100644 --- a/src/modules/image/ImageData.cpp +++ b/src/modules/image/ImageData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -20,8 +20,6 @@ #include "ImageData.h" -#include - using love::thread::Lock; namespace love @@ -30,6 +28,7 @@ namespace image { ImageData::ImageData() + : data(0) { mutex = thread::newMutex(); } @@ -39,14 +38,19 @@ ImageData::~ImageData() delete mutex; } +int ImageData::getSize() const +{ + return getWidth()*getHeight()*sizeof(pixel); +} + void *ImageData::getData() const { return data; } -int ImageData::getSize() const +bool ImageData::inside(int x, int y) const { - return getWidth()*getHeight()*sizeof(pixel); + return x >= 0 && x < getWidth() && y >= 0 && y < getHeight(); } int ImageData::getWidth() const @@ -59,11 +63,6 @@ int ImageData::getHeight() const return height; } -bool ImageData::inside(int x, int y) const -{ - return x >= 0 && x < getWidth() && y >= 0 && y < getHeight(); -} - void ImageData::setPixel(int x, int y, pixel c) { if (!inside(x, y)) @@ -71,18 +70,25 @@ void ImageData::setPixel(int x, int y, pixel c) Lock lock(mutex); - pixel *pixels = (pixel *)getData(); + pixel *pixels = (pixel *) getData(); pixels[y*getWidth()+x] = c; } -pixel ImageData::getPixel(int x, int y) +void ImageData::setPixelUnsafe(int x, int y, love::image::pixel c) +{ + if (!inside(x, y)) + throw love::Exception("Attempt to set out-of-range pixel!"); + + pixel *pixels = (pixel *) getData(); + pixels[y*getWidth()+x] = c; +} + +pixel ImageData::getPixel(int x, int y) const { if (!inside(x, y)) throw love::Exception("Attempt to get out-of-range pixel!"); - Lock lock(mutex); - - pixel *pixels = (pixel *)getData(); + const pixel *pixels = (const pixel *) getData(); return pixels[y*getWidth()+x]; } @@ -143,15 +149,21 @@ void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, in // If the dimensions match up, copy the entire memory stream in one go if (sw == getWidth() && getWidth() == src->getWidth() - && sh == getHeight() && getHeight() == src->getHeight()) - memcpy(d, s, sizeof(pixel) * sw * sh); - else if (sw > 0) // Otherwise, copy each row individually + && sh == getHeight() && getHeight() == src->getHeight()) { - for (int i = 0; i < sh; i++) - { - memcpy(d + dx + (i + dy) * getWidth(), s + sx + (i + sy) * src->getWidth(), sizeof(pixel) * sw); - } + memcpy(d, s, sizeof(pixel) * sw * sh); } + else if (sw > 0) + { + // Otherwise, copy each row individually. + for (int i = 0; i < sh; i++) + memcpy(d + dx + (i + dy) * getWidth(), s + sx + (i + sy) * src->getWidth(), sizeof(pixel) * sw); + } +} + +love::thread::Mutex *ImageData::getMutex() const +{ + return mutex; } bool ImageData::getConstant(const char *in, ImageData::Format &out) @@ -168,7 +180,6 @@ StringMap::Entry ImageData::forma { {"tga", ImageData::FORMAT_TGA}, {"bmp", ImageData::FORMAT_BMP}, - {"gif", ImageData::FORMAT_GIF}, {"jpg", ImageData::FORMAT_JPG}, {"png", ImageData::FORMAT_PNG}, }; diff --git a/src/modules/image/ImageData.h b/src/modules/image/ImageData.h index 077b6c1c6..3349722fd 100644 --- a/src/modules/image/ImageData.h +++ b/src/modules/image/ImageData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -45,29 +45,12 @@ struct pixel **/ class ImageData : public Data { -protected: - - // The width of the image data. - int width; - - // The height of the image data. - int height; - - // The actual data. - unsigned char *data; - - // We need to be thread-safe - // so we lock when we're accessing our - // data - Mutex *mutex; - public: enum Format { FORMAT_TGA = 1, FORMAT_BMP, - FORMAT_GIF, FORMAT_JPG, FORMAT_PNG, FORMAT_MAX_ENUM @@ -122,13 +105,19 @@ public: **/ void setPixel(int x, int y, pixel p); + /** + * Sets the pixel at location (x,y). + * Not thread-safe! + **/ + void setPixelUnsafe(int x, int y, pixel p); + /** * Gets the pixel at location (x,y). * @param x The location along the x-axis. * @param y The location along the y-axis. * @return The color for the given location. **/ - pixel getPixel(int x, int y); + pixel getPixel(int x, int y) const; /** * Encodes raw pixel data into a given format. @@ -137,11 +126,30 @@ public: **/ virtual void encode(love::filesystem::File *f, Format format) = 0; + love::thread::Mutex *getMutex() const; + // Implements Data. - void *getData() const; - int getSize() const; + virtual void *getData() const; + virtual int getSize() const; + +protected: + + // The width of the image data. + int width; + + // The height of the image data. + int height; + + // The actual data. + unsigned char *data; + + // We need to be thread-safe + // so we lock when we're accessing our + // data + Mutex *mutex; private: + static StringMap::Entry formatEntries[]; static StringMap formats; diff --git a/src/modules/image/magpie/CompressedData.cpp b/src/modules/image/magpie/CompressedData.cpp new file mode 100644 index 000000000..2a4e46c1d --- /dev/null +++ b/src/modules/image/magpie/CompressedData.cpp @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "CompressedData.h" + +#include "ddsHandler.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +CompressedData::CompressedData(love::filesystem::FileData *filedata) +{ + load(filedata); +} + +CompressedData::~CompressedData() +{ + delete[] data; +} + +void CompressedData::load(love::filesystem::FileData *filedata) +{ + // SubImage vector will be populated by a parser. + std::vector parsedimages; + Format texformat = FORMAT_UNKNOWN; + + uint8 *newdata = 0; + size_t newdata_size = 0; + + if (ddsHandler::canParse(filedata)) + newdata = ddsHandler::parse(filedata, parsedimages, newdata_size, texformat); + + if (newdata == 0) + throw love::Exception("Could not parse compressed data."); + + if (texformat == FORMAT_UNKNOWN) + { + delete[] newdata; + throw love::Exception("Could not parse compressed data: Unknown format."); + } + + if (parsedimages.size() == 0 || newdata_size == 0) + { + delete[] newdata; + throw love::Exception("Could not parse compressed data: No valid data?"); + } + + // Make sure to clean up any previously loaded data. + delete[] data; + + data = newdata; + dataSize = newdata_size; + + dataImages = parsedimages; + format = texformat; +} + +bool CompressedData::isCompressed(love::filesystem::FileData *filedata) +{ + if (ddsHandler::canParse(filedata)) + return true; + + return false; +} + +} // magpie +} // image +} // love diff --git a/src/modules/image/magpie/CompressedData.h b/src/modules/image/magpie/CompressedData.h new file mode 100644 index 000000000..bd1bc98cf --- /dev/null +++ b/src/modules/image/magpie/CompressedData.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_IMAGE_MAGPIE_COMPRESSED_DATA_H +#define LOVE_IMAGE_MAGPIE_COMPRESSED_DATA_H + +// LOVE +#include "filesystem/FileData.h" +#include "image/CompressedData.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +class CompressedData : public love::image::CompressedData +{ +public: + + CompressedData(love::filesystem::FileData *filedata); + virtual ~CompressedData(); + + static bool isCompressed(love::filesystem::FileData *filedata); + +private: + + void load(love::filesystem::FileData *filedata); + +}; // CompressedData + +} // magpie +} // image +} // love + +#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_DATA_H diff --git a/src/modules/image/devil/ImageData.cpp b/src/modules/image/magpie/DevilHandler.cpp similarity index 56% rename from src/modules/image/devil/ImageData.cpp rename to src/modules/image/magpie/DevilHandler.cpp index fbe76dc6d..dede18fdc 100644 --- a/src/modules/image/devil/ImageData.cpp +++ b/src/modules/image/magpie/DevilHandler.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,16 +18,15 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "ImageData.h" - -// STD -#include -#include +#include "DevilHandler.h" // LOVE #include "common/Exception.h" #include "common/math.h" -#include "filesystem/File.h" +#include "thread/threads.h" + +// DevIL +#include using love::thread::Lock; @@ -37,7 +36,7 @@ namespace love { namespace image { -namespace devil +namespace magpie { static inline void ilxClearErrors() @@ -45,74 +44,66 @@ static inline void ilxClearErrors() while (ilGetError() != IL_NO_ERROR); } -ImageData::ImageData(Data *data) +void DevilHandler::init() { - load(data); + ilInit(); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); } -ImageData::ImageData(filesystem::File *file) +void DevilHandler::quit() { - Data *data = file->read(); - load(data); - data->release(); -} - -ImageData::ImageData(int width, int height) -{ - this->width = width; - this->height = height; - create(width, height); - - // Set to black. - memset(data, 0, width*height*4); -} - -ImageData::ImageData(int width, int height, void *data) -{ - this->width = width; - this->height = height; - create(width, height, data); -} - -ImageData::~ImageData() -{ - delete[] data; -} - -void ImageData::create(int width, int height, void *data) -{ - try + ilShutDown(); + if (devilMutex) { - this->data = new unsigned char[width*height*sizeof(pixel)]; + delete devilMutex; + devilMutex = 0; } - catch(std::bad_alloc &) +} + +bool DevilHandler::canDecode(love::filesystem::FileData * /*data*/) +{ + // DevIL can decode a lot of formats... + return true; +} + +bool DevilHandler::canEncode(ImageData::Format format) +{ + switch (format) { - throw love::Exception("Out of memory"); + case ImageData::FORMAT_BMP: + case ImageData::FORMAT_TGA: + case ImageData::FORMAT_JPG: + case ImageData::FORMAT_PNG: + return true; + default: + return false; } - if (data) - memcpy(this->data, data, width*height*sizeof(pixel)); + return false; } -void ImageData::load(Data *data) +DevilHandler::DecodedImage DevilHandler::decode(love::filesystem::FileData *data) { if (!devilMutex) devilMutex = thread::newMutex(); Lock lock(devilMutex); - ILuint image; - ilGenImages(1, &image); + + ILuint image = ilGenImage(); ilBindImage(image); + DecodedImage img; + try { - bool success = IL_TRUE == ilLoadL(IL_TYPE_UNKNOWN, (void *)data->getData(), data->getSize()); + bool success = ilLoadL(IL_TYPE_UNKNOWN, (void *)data->getData(), (ILuint) data->getSize()) == IL_TRUE; if (!success) throw love::Exception("Could not decode image!"); - width = ilGetInteger(IL_IMAGE_WIDTH); - height = ilGetInteger(IL_IMAGE_HEIGHT); + img.width = ilGetInteger(IL_IMAGE_WIDTH); + img.height = ilGetInteger(IL_IMAGE_HEIGHT); // Make sure the image is in RGBA format. ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); @@ -122,35 +113,47 @@ void ImageData::load(Data *data) if (bpp != sizeof(pixel)) throw love::Exception("Could not convert image!"); - create(width, height, ilGetData()); + img.size = (size_t) ilGetInteger(IL_IMAGE_SIZE_OF_DATA); + + try + { + img.data = new ILubyte[img.size]; + } + catch (std::bad_alloc &) + { + throw love::Exception("Out of memory."); + } + + memcpy(img.data, ilGetData(), img.size); } - catch(std::exception &) + catch (std::exception &e) { - ilDeleteImages(1, &image); - throw; + // catches love and std exceptions + ilDeleteImage(image); + throw love::Exception("%s", e.what()); } - ilDeleteImages(1, &image); + ilDeleteImage(image); + + return img; } -void ImageData::encode(love::filesystem::File *f, ImageData::Format format) +DevilHandler::EncodedImage DevilHandler::encode(const DecodedImage &img, ImageData::Format format) { if (!devilMutex) devilMutex = thread::newMutex(); - Lock lock1(devilMutex); - Lock lock2(mutex); + Lock lock(devilMutex); - ILuint tempimage; - ilGenImages(1, &tempimage); + ILuint tempimage = ilGenImage(); ilBindImage(tempimage); ilxClearErrors(); - ILubyte *encoded_data = NULL; + EncodedImage encodedimage; try { - bool success = IL_TRUE == ilTexImage(width, height, 1, sizeof(pixel), IL_RGBA, IL_UNSIGNED_BYTE, this->data); + bool success = ilTexImage(img.width, img.height, 1, sizeof(pixel), IL_RGBA, IL_UNSIGNED_BYTE, img.data) == IL_TRUE; ILenum err = ilGetError(); ilxClearErrors(); @@ -186,9 +189,6 @@ void ImageData::encode(love::filesystem::File *f, ImageData::Format format) case ImageData::FORMAT_TGA: ilFormat = IL_TGA; break; - case ImageData::FORMAT_GIF: - ilFormat = IL_GIF; - break; case ImageData::FORMAT_JPG: ilFormat = IL_JPG; break; @@ -198,36 +198,35 @@ void ImageData::encode(love::filesystem::File *f, ImageData::Format format) break; } - ILuint size = ilSaveL(ilFormat, NULL, 0); - if (!size) + encodedimage.size = ilSaveL(ilFormat, NULL, 0); + if (!encodedimage.size) throw love::Exception("Could not encode image!"); try { - encoded_data = new ILubyte[size]; + encodedimage.data = new ILubyte[encodedimage.size]; } catch(std::bad_alloc &) { throw love::Exception("Out of memory"); } - ilSaveL(ilFormat, encoded_data, size); - - f->open(love::filesystem::File::WRITE); - f->write(encoded_data, size); - f->close(); + ilSaveL(ilFormat, encodedimage.data, encodedimage.size); } - catch(std::exception &) + catch (std::exception &e) { - ilDeleteImages(1, &tempimage); - delete[] encoded_data; - throw; + // Catches love and std exceptions. + ilDeleteImage(tempimage); + delete[] encodedimage.data; + encodedimage.data = 0; + throw love::Exception("%s", e.what()); } - ilDeleteImages(1, &tempimage); - delete[] encoded_data; + ilDeleteImage(tempimage); + + return encodedimage; } -} // devil +} // magpie } // image } // love diff --git a/src/modules/image/magpie/DevilHandler.h b/src/modules/image/magpie/DevilHandler.h new file mode 100644 index 000000000..5d1e85019 --- /dev/null +++ b/src/modules/image/magpie/DevilHandler.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_IMAGE_MAGPIE_DEVIL_HANDLER_H +#define LOVE_IMAGE_MAGPIE_DEVIL_HANDLER_H + +// LOVE +#include "filesystem/FileData.h" +#include "FormatHandler.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +/** + * Interface between ImageData and DevIL. + **/ +class DevilHandler : public FormatHandler +{ +public: + + static void init(); + static void quit(); + + // Implements FormatHandler. + + static bool canDecode(love::filesystem::FileData *data); + static bool canEncode(ImageData::Format format); + + static DecodedImage decode(love::filesystem::FileData *data); + static EncodedImage encode(const DecodedImage &img, ImageData::Format format); + +}; // DevilHandler + +} // magpie +} // image +} // love + +#endif // LOVE_IMAGE_MAGPIE_DEVIL_HANDLER_H diff --git a/src/modules/image/magpie/FormatHandler.h b/src/modules/image/magpie/FormatHandler.h new file mode 100644 index 000000000..f953e97e3 --- /dev/null +++ b/src/modules/image/magpie/FormatHandler.h @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H +#define LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H + +// LOVE +#include "image/ImageData.h" +#include "filesystem/FileData.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +/** + * Base class for all ImageData encoder/decoder library interfaces. + **/ +class FormatHandler +{ +public: + + // Raw RGBA pixel data. + struct DecodedImage + { + int width, height; + size_t size; + unsigned char *data; + DecodedImage() : width(0), height(0), size(0), data(0) {} + }; + + // Pixel data encoded in a particular format. + struct EncodedImage + { + size_t size; + unsigned char *data; + EncodedImage() : size(0), data(0) {} + }; + + // Lets pretend we have virtual static methods... + + /** + * Determines whether a particular FileData can be decoded by this handler. + * @param data The data to decode. + **/ + // virtual static bool canDecode(love::filesystem::FileData *data) = 0; + + /** + * Determines whether this handler can encode to a particular format. + * @param format The format to encode to. + **/ + // virtual static bool canEncode(ImageData::Format format) = 0; + + /** + * Decodes an image from its encoded form into raw pixel data. + * @param data The encoded data to decode. + * @return The decoded pixel data. + **/ + // virtual static DecodedImage decode(love::filesystem::FileData *data) = 0; + + /** + * Encodes an image from raw pixel data into a particular format. + * @param img The raw image data to encode. + * @param format The format to encode to. + * @return The encoded image data. + **/ + // virtual static EncodedImage encode(const DecodedImage &img, ImageData::Format format) = 0; + +}; // FormatHandler + +} // magpie +} // image +} // love + +#endif // LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H diff --git a/src/modules/image/devil/Image.cpp b/src/modules/image/magpie/Image.cpp similarity index 71% rename from src/modules/image/devil/Image.cpp rename to src/modules/image/magpie/Image.cpp index f36945cb2..7eb8d2519 100644 --- a/src/modules/image/devil/Image.cpp +++ b/src/modules/image/magpie/Image.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,40 +21,33 @@ #include "Image.h" #include "ImageData.h" +#include "CompressedData.h" -// DevIL -#include +#include "DevilHandler.h" namespace love { namespace image { -namespace devil +namespace magpie { Image::Image() { - ilInit(); - ilOriginFunc(IL_ORIGIN_UPPER_LEFT); - ilEnable(IL_ORIGIN_SET); + DevilHandler::init(); } Image::~Image() { - ilShutDown(); + DevilHandler::quit(); } const char *Image::getName() const { - return "love.image.devil"; + return "love.image.magpie"; } -love::image::ImageData *Image::newImageData(love::filesystem::File *file) -{ - return new ImageData(file); -} - -love::image::ImageData *Image::newImageData(Data *data) +love::image::ImageData *Image::newImageData(love::filesystem::FileData *data) { return new ImageData(data); } @@ -64,11 +57,21 @@ love::image::ImageData *Image::newImageData(int width, int height) return new ImageData(width, height); } -love::image::ImageData *Image::newImageData(int width, int height, void *data) +love::image::ImageData *Image::newImageData(int width, int height, void *data, bool own) { - return new ImageData(width, height, data); + return new ImageData(width, height, data, own); } -} // devil +love::image::CompressedData *Image::newCompressedData(love::filesystem::FileData *data) +{ + return new CompressedData(data); +} + +bool Image::isCompressed(love::filesystem::FileData *data) +{ + return CompressedData::isCompressed(data); +} + +} // magpie } // image } // love diff --git a/src/modules/image/devil/Image.h b/src/modules/image/magpie/Image.h similarity index 66% rename from src/modules/image/devil/Image.h rename to src/modules/image/magpie/Image.h index 6a03aea99..4385e6635 100644 --- a/src/modules/image/devil/Image.h +++ b/src/modules/image/magpie/Image.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,8 +18,8 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_IMAGE_DEVIL_IMAGE_H -#define LOVE_IMAGE_DEVIL_IMAGE_H +#ifndef LOVE_IMAGE_MAGPIE_IMAGE_H +#define LOVE_IMAGE_MAGPIE_IMAGE_H // LOVE #include "image/Image.h" @@ -28,9 +28,14 @@ namespace love { namespace image { -namespace devil +namespace magpie { +/** + * Similar to love.sound's Lullaby module, love.image.magpie interfaces with + * multiple image libraries and determines the correct one to use on a + * per-image basis at runtime. + **/ class Image : public love::image::Image { public: @@ -41,15 +46,18 @@ public: // Implements Module. const char *getName() const; - love::image::ImageData *newImageData(love::filesystem::File *file); - love::image::ImageData *newImageData(Data *data); + love::image::ImageData *newImageData(love::filesystem::FileData *data); love::image::ImageData *newImageData(int width, int height); - love::image::ImageData *newImageData(int width, int height, void *data); + love::image::ImageData *newImageData(int width, int height, void *data, bool own = false); + + love::image::CompressedData *newCompressedData(love::filesystem::FileData *data); + + bool isCompressed(love::filesystem::FileData *data); }; // Image -} // devil +} // magpie } // image } // love -#endif // LOVE_IMAGE_DEVIL_IMAGE_H \ No newline at end of file +#endif // LOVE_IMAGE_MAGPIE_IMAGE_H diff --git a/src/modules/image/magpie/ImageData.cpp b/src/modules/image/magpie/ImageData.cpp new file mode 100644 index 000000000..db614abbb --- /dev/null +++ b/src/modules/image/magpie/ImageData.cpp @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "ImageData.h" + +#include "FormatHandler.h" +#include "DevilHandler.h" + +namespace love +{ +namespace image +{ +namespace magpie +{ + +ImageData::ImageData(love::filesystem::FileData *data) +{ + decode(data); +} + +ImageData::ImageData(int width, int height) +{ + this->width = width; + this->height = height; + create(width, height); + + // Set to black/transparency. + memset(data, 0, width*height*sizeof(pixel)); +} + +ImageData::ImageData(int width, int height, void *data, bool own) +{ + this->width = width; + this->height = height; + + if (own) + this->data = (unsigned char *) data; + else + create(width, height, data); +} + +ImageData::~ImageData() +{ + delete[] data; +} + +void ImageData::create(int width, int height, void *data) +{ + try + { + this->data = new unsigned char[width*height*sizeof(pixel)]; + } + catch(std::bad_alloc &) + { + throw love::Exception("Out of memory"); + } + + if (data) + memcpy(this->data, data, width*height*sizeof(pixel)); +} + +void ImageData::decode(love::filesystem::FileData *data) +{ + FormatHandler::DecodedImage decodedimage; + + if (DevilHandler::canDecode(data)) + decodedimage = DevilHandler::decode(data); + else + throw love::Exception("Could not decode image: unrecognized format."); + + // The decoder *must* output a 32 bits-per-pixel image. + if (decodedimage.size != decodedimage.width*decodedimage.height*sizeof(pixel)) + { + delete[] decodedimage.data; + throw love::Exception("Coult not convert image!"); + } + + if (this->data) + delete[] this->data; + + this->width = decodedimage.width; + this->height = decodedimage.height; + this->data = decodedimage.data; +} + +void ImageData::encode(love::filesystem::File *f, ImageData::Format format) +{ + FormatHandler::EncodedImage encodedimage; + + { + // We only need to lock this mutex when actually encoding the ImageData. + thread::Lock lock(mutex); + + FormatHandler::DecodedImage rawimage; + rawimage.width = width; + rawimage.height = height; + rawimage.size = width*height*sizeof(pixel); + rawimage.data = data; + + if (DevilHandler::canEncode(format)) + encodedimage = DevilHandler::encode(rawimage, format); + else + throw love::Exception("Image format has no suitable encoder."); + } + + try + { + + f->open(love::filesystem::File::WRITE); + f->write(encodedimage.data, encodedimage.size); + f->close(); + } + catch (love::Exception &) + { + delete[] encodedimage.data; + throw; + } + + delete[] encodedimage.data; +} + +} // magpie +} // image +} // love diff --git a/src/modules/image/devil/ImageData.h b/src/modules/image/magpie/ImageData.h similarity index 69% rename from src/modules/image/devil/ImageData.h rename to src/modules/image/magpie/ImageData.h index 3791b7c51..b7ccbf346 100644 --- a/src/modules/image/devil/ImageData.h +++ b/src/modules/image/magpie/ImageData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,54 +18,44 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_DEVIL_IMAGE_DATA_H -#define LOVE_DEVIL_IMAGE_DATA_H +#ifndef LOVE_IMAGE_MAGPIE_IMAGE_DATA_H +#define LOVE_IMAGE_MAGPIE_IMAGE_DATA_H // LOVE #include "filesystem/File.h" #include "image/ImageData.h" -// DevIL -#include - - namespace love { namespace image { -namespace devil +namespace magpie { class ImageData : public love::image::ImageData { +public: + + ImageData(love::filesystem::FileData *data); + ImageData(int width, int height); + ImageData(int width, int height, void *data, bool own); + virtual ~ImageData(); + + // Implements image::ImageData. + virtual void encode(love::filesystem::File *f, ImageData::Format format); + private: // Create imagedata. Initialize with data if not null. void create(int width, int height, void *data = 0); - // Load an encoded format. - void load(Data *data); - -public: - - ImageData(Data *data); - ImageData(love::filesystem::File *file); - ImageData(int width, int height); - ImageData(int width, int height, void *data); - virtual ~ImageData(); - - // Implements ImageData. - void encode(love::filesystem::File *f, Format format); - - // We need to be thread-safe - // so we lock when we're accessing our - // data - Mutex *mutex; + // Decode and load an encoded format. + void decode(love::filesystem::FileData *data); }; // ImageData -} // devil +} // magpie } // image } // love -#endif // LOVE_DEVIL_IMAGE_DATA_H +#endif // LOVE_IMAGE_MAGPIE_IMAGE_DATA_H diff --git a/src/modules/image/magpie/ddsHandler.cpp b/src/modules/image/magpie/ddsHandler.cpp new file mode 100644 index 000000000..865f35239 --- /dev/null +++ b/src/modules/image/magpie/ddsHandler.cpp @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "ddsHandler.h" + +#include + +namespace love +{ +namespace image +{ +namespace magpie +{ + +bool ddsHandler::canParse(const filesystem::FileData *data) +{ + std::string ext = data->getExtension(); + std::transform(ext.begin(), ext.end(), ext.begin(), tolower); + + if (ext.compare("dds") != 0) + return false; + + return dds::isCompressedDDS(data->getData(), data->getSize()); +} + +uint8 *ddsHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedData::Format &format) +{ + if (!dds::isDDS(filedata->getData(), filedata->getSize())) + throw love::Exception("Could not decode compressed data (not a DDS file?)"); + + CompressedData::Format texformat = CompressedData::FORMAT_UNKNOWN; + + uint8 *data = 0; + dataSize = 0; + images.clear(); + + try + { + // Attempt to parse the dds file. + dds::Parser parser(filedata->getData(), filedata->getSize()); + + texformat = convertFormat(parser.getFormat()); + + if (texformat == CompressedData::FORMAT_UNKNOWN) + throw love::Exception("Could not parse compressed data: Unsupported format."); + + if (parser.getMipmapCount() == 0) + throw love::Exception("Could not parse compressed data: No readable texture data."); + + // Calculate the size of the block of memory we're returning. + for (size_t i = 0; i < parser.getMipmapCount(); i++) + { + const dds::Image *img = parser.getImageData(i); + dataSize += img->dataSize; + } + + data = new uint8[dataSize]; + + size_t dataOffset = 0; + + // Copy the parsed mipmap levels from the FileData to our CompressedData. + for (size_t i = 0; i < parser.getMipmapCount(); i++) + { + // Fetch the data for this mipmap level. + const dds::Image *img = parser.getImageData(i); + + CompressedData::SubImage mip; + + mip.width = img->width; + mip.height = img->height; + mip.size = img->dataSize; + + // Copy the mipmap image from the FileData to our block of memory. + memcpy(data + dataOffset, img->data, mip.size); + mip.data = data + dataOffset; + + dataOffset += mip.size; + + images.push_back(mip); + } + } + catch (std::exception &e) + { + delete[] data; + images.clear(); + throw love::Exception("%s", e.what()); + } + + format = texformat; + return data; +} + +CompressedData::Format ddsHandler::convertFormat(dds::Format ddsformat) +{ + switch (ddsformat) + { + case dds::FORMAT_DXT1: + return CompressedData::FORMAT_DXT1; + case dds::FORMAT_DXT3: + return CompressedData::FORMAT_DXT3; + case dds::FORMAT_DXT5: + return CompressedData::FORMAT_DXT5; + case dds::FORMAT_BC4: + return CompressedData::FORMAT_BC4; + case dds::FORMAT_BC4s: + return CompressedData::FORMAT_BC4s; + case dds::FORMAT_BC5: + return CompressedData::FORMAT_BC5; + case dds::FORMAT_BC5s: + return CompressedData::FORMAT_BC5s; + default: + return CompressedData::FORMAT_UNKNOWN; + } + + return CompressedData::FORMAT_UNKNOWN; +} + +} // magpie +} // image +} // love diff --git a/src/modules/image/magpie/ddsHandler.h b/src/modules/image/magpie/ddsHandler.h new file mode 100644 index 000000000..f8d711801 --- /dev/null +++ b/src/modules/image/magpie/ddsHandler.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_IMAGE_MAGPIE_DDS_HANDLER_H +#define LOVE_IMAGE_MAGPIE_DDS_HANDLER_H + +// LOVE +#include "common/EnumMap.h" +#include "filesystem/FileData.h" +#include "image/CompressedData.h" + +// dds parser +#include "ddsparse/ddsparse.h" + +// STL +#include + +namespace love +{ +namespace image +{ +namespace magpie +{ + +/** + * Interface between CompressedData and the ddsparse library. + **/ +class ddsHandler +{ +public: + + /** + * Determines whether a particular FileData can be parsed as CompressedData + * by this handler. + * @param data The data to parse. + **/ + static bool canParse(const filesystem::FileData *data); + + /** + * Parses compressed image filedata into a list of sub-images and returns + * a single block of memory containing all the images. + * + * @param[in] filedata The data to parse. + * @param[out] image The list of sub-images generated. Byte data is a pointer + * to the returned data. + * @param[out] dataSize The total size in bytes of the returned data. + * @param[out] format The format of the Compressed Data. + * + * @return The single block of memory containing the parsed images. + **/ + static uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedData::Format &format); + +private: + + static CompressedData::Format convertFormat(dds::Format ddsformat); + +}; // ddsHandler + +} // magpie +} // image +} // love + +#endif // LOVE_IMAGE_MAGPIE_DDS_HANDLER_H diff --git a/src/modules/image/wrap_CompressedData.cpp b/src/modules/image/wrap_CompressedData.cpp new file mode 100644 index 000000000..f4b0c5752 --- /dev/null +++ b/src/modules/image/wrap_CompressedData.cpp @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "wrap_CompressedData.h" +#include "common/wrap_Data.h" + +namespace love +{ +namespace image +{ + +CompressedData *luax_checkcompresseddata(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "CompressedData", IMAGE_COMPRESSED_DATA_T); +} + +int w_CompressedData_getWidth(lua_State *L) +{ + CompressedData *t = luax_checkcompresseddata(L, 1); + int miplevel = luaL_optinteger(L, 2, 1); + int width = 0; + + EXCEPT_GUARD(width = t->getWidth(miplevel >= 1 ? miplevel - 1 : 0);) + + lua_pushinteger(L, width); + return 1; +} + +int w_CompressedData_getHeight(lua_State *L) +{ + CompressedData *t = luax_checkcompresseddata(L, 1); + int miplevel = luaL_optinteger(L, 2, 1); + int height = 0; + + EXCEPT_GUARD(height = t->getHeight(miplevel >= 1 ? miplevel - 1 : 0);) + + lua_pushinteger(L, height); + return 1; +} + +int w_CompressedData_getDimensions(lua_State *L) +{ + CompressedData *t = luax_checkcompresseddata(L, 1); + int miplevel = luaL_optinteger(L, 2, 1); + int width = 0, height = 0; + + EXCEPT_GUARD( + width = t->getWidth(miplevel >= 1 ? miplevel - 1 : 0); + height = t->getHeight(miplevel >= 1 ? miplevel - 1 : 0); + ) + + lua_pushinteger(L, width); + lua_pushinteger(L, height); + return 2; +} + +int w_CompressedData_getMipmapCount(lua_State *L) +{ + CompressedData *t = luax_checkcompresseddata(L, 1); + lua_pushinteger(L, t->getMipmapCount()); + return 1; +} + +int w_CompressedData_getFormat(lua_State *L) +{ + CompressedData *t = luax_checkcompresseddata(L, 1); + + image::CompressedData::Format format = t->getFormat(); + const char *str; + + if (image::CompressedData::getConstant(format, str)) + lua_pushstring(L, str); + else + lua_pushstring(L, "unknown"); + + return 1; +} + +static const luaL_Reg functions[] = +{ + // Data + { "getString", w_Data_getString }, + { "getPointer", w_Data_getPointer }, + { "getSize", w_Data_getSize }, + + { "getWidth", w_CompressedData_getWidth }, + { "getHeight", w_CompressedData_getHeight }, + { "getDimensions", w_CompressedData_getDimensions }, + { "getMipmapCount", w_CompressedData_getMipmapCount }, + { "getFormat", w_CompressedData_getFormat }, + { 0, 0 }, +}; + +extern "C" int luaopen_compresseddata(lua_State *L) +{ + return luax_register_type(L, "CompressedData", functions); +} + +} // image +} // love diff --git a/src/modules/image/wrap_CompressedData.h b/src/modules/image/wrap_CompressedData.h new file mode 100644 index 000000000..d55ec6da0 --- /dev/null +++ b/src/modules/image/wrap_CompressedData.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_IMAGE_WRAP_COMRESSED_DATA_H +#define LOVE_IMAGE_WRAP_COMRESSED_DATA_H + +// LOVE +#include "common/runtime.h" +#include "CompressedData.h" + +namespace love +{ +namespace image +{ + +CompressedData *luax_checkcompresseddata(lua_State *L, int idx); +int w_CompressedData_getWidth(lua_State *L); +int w_CompressedData_getHeight(lua_State *L); +int w_CompressedData_getDimensions(lua_State *L); +int w_CompressedData_getMipmapCount(lua_State *L); +int w_CompressedData_getFormat(lua_State *L); +extern "C" int luaopen_compresseddata(lua_State *L); + +} // image +} // love + +#endif // LOVE_IMAGE_WRAP_COMRESSED_DATA_H diff --git a/src/modules/image/wrap_Image.cpp b/src/modules/image/wrap_Image.cpp index a730fe9f4..93896f852 100644 --- a/src/modules/image/wrap_Image.cpp +++ b/src/modules/image/wrap_Image.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,7 +23,7 @@ #include "common/Data.h" #include "common/StringMap.h" -#include "devil/Image.h" +#include "magpie/Image.h" namespace love { @@ -43,53 +43,54 @@ int w_newImageData(lua_State *L) return luaL_error(L, "Invalid image size."); ImageData *t = 0; - try - { - t = instance->newImageData(w, h); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)t); + EXCEPT_GUARD(t = instance->newImageData(w, h);) + + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, t); return 1; } - // Case 2: Data - if (luax_istype(L, 1, DATA_T)) - { - Data *d = luax_checktype(L, 1, "Data", DATA_T); - ImageData *t = 0; - try - { - t = instance->newImageData(d); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)t); - return 1; - } + // Case 2: File(Data). - // Case 3: String/File. + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); - // Convert to File, if necessary. - if (lua_isstring(L, 1)) - luax_convobj(L, 1, "filesystem", "newFile"); - - love::filesystem::File *file = luax_checktype(L, 1, "File", FILESYSTEM_FILE_T); + love::filesystem::FileData *data = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); ImageData *t = 0; - try - { - t = instance->newImageData(file); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)t); + EXCEPT_GUARD(t = instance->newImageData(data);) + + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, t); + return 1; +} + +int w_newCompressedData(lua_State *L) +{ + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); + + love::filesystem::FileData *data = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); + + CompressedData *t = 0; + EXCEPT_GUARD(t = instance->newCompressedData(data);) + + luax_pushtype(L, "CompressedData", IMAGE_COMPRESSED_DATA_T, t); + return 1; +} + +int w_isCompressed(lua_State *L) +{ + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); + + love::filesystem::FileData *data = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); + + bool compressed = false; + EXCEPT_GUARD(compressed = instance->isCompressed(data);) + + luax_pushboolean(L, compressed); return 1; } @@ -97,12 +98,15 @@ int w_newImageData(lua_State *L) static const luaL_Reg functions[] = { { "newImageData", w_newImageData }, + { "newCompressedData", w_newCompressedData }, + { "isCompressed", w_isCompressed }, { 0, 0 } }; static const lua_CFunction types[] = { luaopen_imagedata, + luaopen_compresseddata, 0 }; @@ -110,14 +114,7 @@ extern "C" int luaopen_love_image(lua_State *L) { if (instance == 0) { - try - { - instance = new love::image::devil::Image(); - } - catch(Exception &e) - { - return luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(instance = new love::image::magpie::Image();) } else instance->retain(); diff --git a/src/modules/image/wrap_Image.h b/src/modules/image/wrap_Image.h index b58d551ae..d1d201995 100644 --- a/src/modules/image/wrap_Image.h +++ b/src/modules/image/wrap_Image.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,14 +24,16 @@ // LOVE #include "Image.h" #include "wrap_ImageData.h" +#include "wrap_CompressedData.h" namespace love { namespace image { -int w_getFormats(lua_State *L); int w_newImageData(lua_State *L); +int w_newCompressedData(lua_State *L); +int w_isCompressed(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_image(lua_State *L); } // image diff --git a/src/modules/image/wrap_ImageData.cpp b/src/modules/image/wrap_ImageData.cpp index 8bbd996e2..401e4b718 100644 --- a/src/modules/image/wrap_ImageData.cpp +++ b/src/modules/image/wrap_ImageData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -47,20 +47,23 @@ int w_ImageData_getHeight(lua_State *L) return 1; } +int w_ImageData_getDimensions(lua_State *L) +{ + ImageData *t = luax_checkimagedata(L, 1); + lua_pushinteger(L, t->getWidth()); + lua_pushinteger(L, t->getHeight()); + return 2; +} + int w_ImageData_getPixel(lua_State *L) { ImageData *t = luax_checkimagedata(L, 1); int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); pixel c; - try - { - c = t->getPixel(x, y); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } + + EXCEPT_GUARD(c = t->getPixel(x, y);) + lua_pushnumber(L, c.r); lua_pushnumber(L, c.g); lua_pushnumber(L, c.b); @@ -74,60 +77,149 @@ int w_ImageData_setPixel(lua_State *L) int x = luaL_checkint(L, 2); int y = luaL_checkint(L, 3); pixel c; - c.r = luaL_checkint(L, 4); - c.g = luaL_checkint(L, 5); - c.b = luaL_checkint(L, 6); - c.a = luaL_checkint(L, 7); - try + + if (lua_istable(L, 4)) { - t->setPixel(x, y, c); + for (int i = 1; i <= 4; i++) + lua_rawgeti(L, 4, i); + + c.r = (unsigned char)luaL_checkinteger(L, -4); + c.g = (unsigned char)luaL_checkinteger(L, -3); + c.b = (unsigned char)luaL_checkinteger(L, -2); + c.a = (unsigned char)luaL_optinteger(L, -1, 255); + + lua_pop(L, 4); } - catch(love::Exception &e) + else { - return luaL_error(L, "%s", e.what()); + c.r = (unsigned char)luaL_checkinteger(L, 4); + c.g = (unsigned char)luaL_checkinteger(L, 5); + c.b = (unsigned char)luaL_checkinteger(L, 6); + c.a = (unsigned char)luaL_optinteger(L, 7, 255); } + + EXCEPT_GUARD(t->setPixel(x, y, c);) return 0; } -int w_ImageData_mapPixel(lua_State *L) +// Gets the result of luaL_where as a string. +static std::string luax_getwhere(lua_State *L, int level) +{ + luaL_where(L, level); + + const char *str = lua_tostring(L, -1); + std::string where; + if (str) + where = str; + + lua_pop(L, 1); + return where; +} + +// Generates a Lua error with a nice error string when a return value of a +// called function is not a number. +static int luax_retnumbererror(lua_State *L, int level, int retnum, int ttype) +{ + if (ttype == LUA_TNUMBER) + return 0; + + const char *where = luax_getwhere(L, level).c_str(); + const char *ttypename = lua_typename(L, ttype); + + return luaL_error(L, "%sbad return value #%d (number expected, got %s)", + where, retnum, ttypename); +} + +// ImageData:mapPixel. Not thread-safe! See the wrapper function below. +static int w_ImageData_mapPixelUnsafe(lua_State *L) { ImageData *t = luax_checkimagedata(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); - if (!lua_isfunction(L, 2)) - return luaL_error(L, "Function expected"); + // No optints because we assume they're done in the wrapper function. + int sx = (int) lua_tonumber(L, 3); + int sy = (int) lua_tonumber(L, 4); + int w = (int) lua_tonumber(L, 5); + int h = (int) lua_tonumber(L, 6); - int w = t->getWidth(); - int h = t->getHeight(); + if (!(t->inside(sx, sy) && t->inside(sx+w-1, sy+h-1))) + return luaL_error(L, "Invalid rectangle dimensions."); - for (int i = 0; i < w; i++) + // Cache-friendlier loop. :) + for (int y = sy; y < sy+h; y++) { - for (int j = 0; j < h; j++) + for (int x = sx; x < sx+w; x++) { lua_pushvalue(L, 2); - lua_pushnumber(L, i); - lua_pushnumber(L, j); - pixel c = t->getPixel(i, j); + lua_pushnumber(L, x); + lua_pushnumber(L, y); + pixel c = t->getPixel(x, y); lua_pushnumber(L, c.r); lua_pushnumber(L, c.g); lua_pushnumber(L, c.b); lua_pushnumber(L, c.a); lua_call(L, 6, 4); - c.r = luaL_optint(L, -4, 0); - c.g = luaL_optint(L, -3, 0); - c.b = luaL_optint(L, -2, 0); - c.a = luaL_optint(L, -1, 0); - t->setPixel(i, j, c); + + // If we used luaL_checkX / luaL_optX then we would get messy error + // messages (e.g. Error: bad argument #-1 to '?'), so while this is + // messier code, at least the errors are a bit more descriptive. + + // Treat the pixel as an array for less code duplication. :( + unsigned char *parray = (unsigned char *) &c; + for (int i = 0; i < 4; i++) + { + int ttype = lua_type(L, -4 + i); + + if (ttype == LUA_TNUMBER) + parray[i] = (unsigned char) lua_tonumber(L, -4 + i); + else if (i == 3 && (ttype == LUA_TNONE || ttype == LUA_TNIL)) + parray[i] = 255; // Alpha component defaults to 255. + else + // Error (level 2 because this is function will be wrapped.) + return luax_retnumbererror(L, 2, i + 1, ttype); + } + + // Pop return values. lua_pop(L, 4); + + // We're locking the entire function, instead of each setPixel call. + t->setPixelUnsafe(x, y, c); } } return 0; } -int w_ImageData_getString(lua_State *L) +// Thread-safe wrapper for the above function. +int w_ImageData_mapPixel(lua_State *L) { ImageData *t = luax_checkimagedata(L, 1); - lua_pushlstring(L, (const char *)t->getData(), t->getSize()); - return 1; + luaL_checktype(L, 2, LUA_TFUNCTION); + int sx = luaL_optint(L, 3, 0); + int sy = luaL_optint(L, 4, 0); + int w = luaL_optint(L, 5, t->getWidth()); + int h = luaL_optint(L, 6, t->getHeight()); + + lua_pushcfunction(L, w_ImageData_mapPixelUnsafe); + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); + lua_pushinteger(L, sx); + lua_pushinteger(L, sy); + lua_pushinteger(L, w); + lua_pushinteger(L, h); + + int ret = 0; + + // Lock this ImageData's mutex during the entire mapPixel. We pcall instead + // of call because lua_error longjmp's without calling object destructors. + { + love::thread::Lock lock(t->getMutex()); + ret = lua_pcall(L, 6, 0, 0); + } + + if (ret != 0) + return lua_error(L); + + return 0; } int w_ImageData_paste(lua_State *L) @@ -159,39 +251,33 @@ int w_ImageData_encode(lua_State *L) { ext = file->getExtension(); fmt = ext.c_str(); - ImageData::getConstant(fmt, format); + if (!ImageData::getConstant(fmt, format)) + return luaL_error(L, "Invalid image format '%s'.", fmt); } else { fmt = luaL_checkstring(L, 3); if (!ImageData::getConstant(fmt, format)) - luaL_error(L, "Invalid image format."); + return luaL_error(L, "Invalid image format '%s'.", fmt); } - try - { - t->encode(file, format); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(t->encode(file, format);) return 0; } static const luaL_Reg functions[] = { - // Data + { "getString", w_Data_getString }, { "getPointer", w_Data_getPointer }, { "getSize", w_Data_getSize }, { "getWidth", w_ImageData_getWidth }, { "getHeight", w_ImageData_getHeight }, + { "getDimensions", w_ImageData_getDimensions }, { "getPixel", w_ImageData_getPixel }, { "setPixel", w_ImageData_setPixel }, { "mapPixel", w_ImageData_mapPixel }, - { "getString", w_ImageData_getString }, { "paste", w_ImageData_paste }, { "encode", w_ImageData_encode }, { 0, 0 } diff --git a/src/modules/image/wrap_ImageData.h b/src/modules/image/wrap_ImageData.h index 142439d4a..a8bbd51bd 100644 --- a/src/modules/image/wrap_ImageData.h +++ b/src/modules/image/wrap_ImageData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,10 +33,10 @@ namespace image ImageData *luax_checkimagedata(lua_State *L, int idx); int w_ImageData_getWidth(lua_State *L); int w_ImageData_getHeight(lua_State *L); +int w_ImageData_getDimensions(lua_State *L); int w_ImageData_getPixel(lua_State *L); int w_ImageData_setPixel(lua_State *L); int w_ImageData_mapPixel(lua_State *L); -int w_ImageData_getString(lua_State *L); int w_ImageData_paste(lua_State *L); int w_ImageData_encode(lua_State *L); extern "C" int luaopen_imagedata(lua_State *L); diff --git a/src/modules/joystick/Joystick.cpp b/src/modules/joystick/Joystick.cpp index fe9a04a62..03946abc0 100644 --- a/src/modules/joystick/Joystick.cpp +++ b/src/modules/joystick/Joystick.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,15 +18,26 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "Joystick.h" +// STL +#include + namespace love { namespace joystick { -Joystick::~Joystick() +float Joystick::clampval(float x) const { + if (fabsf(x) < 0.01) + return 0.0f; + + if (x < -0.99f) return -1.0f; + if (x > 0.99f) return 1.0f; + + return x; } bool Joystick::getConstant(const char *in, Joystick::Hat &out) @@ -34,11 +45,41 @@ bool Joystick::getConstant(const char *in, Joystick::Hat &out) return hats.find(in, out); } -bool Joystick::getConstant(Joystick::Hat in, const char *&out) +bool Joystick::getConstant(Joystick::Hat in, const char *&out) { return hats.find(in, out); } +bool Joystick::getConstant(const char *in, Joystick::GamepadAxis &out) +{ + return gpAxes.find(in, out); +} + +bool Joystick::getConstant(Joystick::GamepadAxis in, const char *&out) +{ + return gpAxes.find(in, out); +} + +bool Joystick::getConstant(const char *in, Joystick::GamepadButton &out) +{ + return gpButtons.find(in, out); +} + +bool Joystick::getConstant(Joystick::GamepadButton in, const char *&out) +{ + return gpButtons.find(in, out); +} + +bool Joystick::getConstant(const char *in, Joystick::InputType &out) +{ + return inputTypes.find(in, out); +} + +bool Joystick::getConstant(Joystick::InputType in, const char *&out) +{ + return inputTypes.find(in, out); +} + StringMap::Entry Joystick::hatEntries[] = { {"c", Joystick::HAT_CENTERED}, @@ -54,5 +95,47 @@ StringMap::Entry Joystick::hatEntries[] = StringMap Joystick::hats(Joystick::hatEntries, sizeof(Joystick::hatEntries)); +StringMap::Entry Joystick::gpAxisEntries[] = +{ + {"leftx", GAMEPAD_AXIS_LEFTX}, + {"lefty", GAMEPAD_AXIS_LEFTY}, + {"rightx", GAMEPAD_AXIS_RIGHTX}, + {"righty", GAMEPAD_AXIS_RIGHTY}, + {"triggerleft", GAMEPAD_AXIS_TRIGGERLEFT}, + {"triggerright", GAMEPAD_AXIS_TRIGGERRIGHT}, +}; + +StringMap Joystick::gpAxes(Joystick::gpAxisEntries, sizeof(Joystick::gpAxisEntries)); + +StringMap::Entry Joystick::gpButtonEntries[] = +{ + {"a", GAMEPAD_BUTTON_A}, + {"b", GAMEPAD_BUTTON_B}, + {"x", GAMEPAD_BUTTON_X}, + {"y", GAMEPAD_BUTTON_Y}, + {"back", GAMEPAD_BUTTON_BACK}, + {"guide", GAMEPAD_BUTTON_GUIDE}, + {"start", GAMEPAD_BUTTON_START}, + {"leftstick", GAMEPAD_BUTTON_LEFTSTICK}, + {"rightstick", GAMEPAD_BUTTON_RIGHTSTICK}, + {"leftshoulder", GAMEPAD_BUTTON_LEFTSHOULDER}, + {"rightshoulder", GAMEPAD_BUTTON_RIGHTSHOULDER}, + {"dpup", GAMEPAD_BUTTON_DPAD_UP}, + {"dpdown", GAMEPAD_BUTTON_DPAD_DOWN}, + {"dpleft", GAMEPAD_BUTTON_DPAD_LEFT}, + {"dpright", GAMEPAD_BUTTON_DPAD_RIGHT}, +}; + +StringMap Joystick::gpButtons(Joystick::gpButtonEntries, sizeof(Joystick::gpButtonEntries)); + +StringMap::Entry Joystick::inputTypeEntries[] = +{ + {"axis", Joystick::INPUT_TYPE_AXIS}, + {"button", Joystick::INPUT_TYPE_BUTTON}, + {"hat", Joystick::INPUT_TYPE_HAT}, +}; + +StringMap Joystick::inputTypes(Joystick::inputTypeEntries, sizeof(Joystick::inputTypeEntries)); + } // joystick } // love diff --git a/src/modules/joystick/Joystick.h b/src/modules/joystick/Joystick.h index c0dd71727..d2d57fa21 100644 --- a/src/modules/joystick/Joystick.h +++ b/src/modules/joystick/Joystick.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,18 +22,23 @@ #define LOVE_JOYSTICK_JOYSTICK_H // LOVE -#include "common/Module.h" +#include "common/Object.h" #include "common/StringMap.h" +// stdlib +#include +#include + namespace love { namespace joystick { -class Joystick : public Module +class Joystick : public Object { public: + // Joystick hat values. enum Hat { HAT_INVALID, @@ -49,19 +54,147 @@ public: HAT_MAX_ENUM = 16 }; - virtual ~Joystick(); + // Valid Gamepad axes. + enum GamepadAxis + { + GAMEPAD_AXIS_INVALID, + GAMEPAD_AXIS_LEFTX, + GAMEPAD_AXIS_LEFTY, + GAMEPAD_AXIS_RIGHTX, + GAMEPAD_AXIS_RIGHTY, + GAMEPAD_AXIS_TRIGGERLEFT, + GAMEPAD_AXIS_TRIGGERRIGHT, + GAMEPAD_AXIS_MAX_ENUM + }; + + // Valid Gamepad buttons. + enum GamepadButton + { + GAMEPAD_BUTTON_INVALID, + GAMEPAD_BUTTON_A, + GAMEPAD_BUTTON_B, + GAMEPAD_BUTTON_X, + GAMEPAD_BUTTON_Y, + GAMEPAD_BUTTON_BACK, + GAMEPAD_BUTTON_GUIDE, + GAMEPAD_BUTTON_START, + GAMEPAD_BUTTON_LEFTSTICK, + GAMEPAD_BUTTON_RIGHTSTICK, + GAMEPAD_BUTTON_LEFTSHOULDER, + GAMEPAD_BUTTON_RIGHTSHOULDER, + GAMEPAD_BUTTON_DPAD_UP, + GAMEPAD_BUTTON_DPAD_DOWN, + GAMEPAD_BUTTON_DPAD_LEFT, + GAMEPAD_BUTTON_DPAD_RIGHT, + GAMEPAD_BUTTON_MAX_ENUM + }; + + // Different types of inputs for a joystick. + enum InputType + { + INPUT_TYPE_AXIS, + INPUT_TYPE_BUTTON, + INPUT_TYPE_HAT, + INPUT_TYPE_MAX_ENUM + }; + + // Represents a gamepad input value, e.g. the "x" button or the left trigger. + struct GamepadInput + { + InputType type; + union + { + GamepadAxis axis; + GamepadButton button; + }; + }; + + // Represents a joystick input value, e.g. button 6 or axis 1. + struct JoystickInput + { + InputType type; + union + { + int axis; + int button; + struct + { + int index; + Hat value; + } hat; + }; + }; + + virtual ~Joystick() {} + + virtual bool open(int deviceindex) = 0; + virtual void close() = 0; + + virtual bool isConnected() const = 0; + + virtual const char *getName() const = 0; + + virtual int getAxisCount() const = 0; + virtual int getButtonCount() const = 0; + virtual int getHatCount() const = 0; + + virtual float getAxis(int axisindex) const = 0; + virtual std::vector getAxes() const = 0; + virtual Hat getHat(int hatindex) const = 0; + + virtual bool isDown(const std::vector &buttonlist) const = 0; + + virtual bool openGamepad(int deviceindex) = 0; + virtual bool isGamepad() const = 0; + + virtual float getGamepadAxis(GamepadAxis axis) const = 0; + virtual bool isGamepadDown(const std::vector &blist) const = 0; + + virtual void *getHandle() const = 0; + + virtual std::string getGUID() const = 0; + virtual int getInstanceID() const = 0; + virtual int getID() const = 0; + + virtual bool isVibrationSupported() = 0; + virtual bool setVibration(float left, float right) = 0; + virtual bool setVibration() = 0; + virtual void getVibration(float &left, float &right) const = 0; static bool getConstant(const char *in, Hat &out); - static bool getConstant(Hat in, const char *&out); + static bool getConstant(Hat in, const char *&out); + + static bool getConstant(const char *in, GamepadAxis &out); + static bool getConstant(GamepadAxis in, const char *&out); + + static bool getConstant(const char *in, GamepadButton &out); + static bool getConstant(GamepadButton in, const char *&out); + + static bool getConstant(const char *in, InputType &out); + static bool getConstant(InputType in, const char *&out); + +protected: + + float clampval(float x) const; private: static StringMap::Entry hatEntries[]; static StringMap hats; + static StringMap::Entry gpAxisEntries[]; + static StringMap gpAxes; + + static StringMap::Entry gpButtonEntries[]; + static StringMap gpButtons; + + static StringMap::Entry inputTypeEntries[]; + static StringMap inputTypes; + }; // Joystick } // joystick } // love -#endif // LOVE_JOYSTICK_JOYSTICK_H \ No newline at end of file + +#endif // LOVE_JOYSTICK_JOYSTICK_H diff --git a/src/modules/joystick/JoystickModule.h b/src/modules/joystick/JoystickModule.h new file mode 100644 index 000000000..d1a488c3d --- /dev/null +++ b/src/modules/joystick/JoystickModule.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_JOYSTICK_JOYSTICK_MODULE_H +#define LOVE_JOYSTICK_JOYSTICK_MODULE_H + +// LOVE +#include "common/Module.h" +#include "Joystick.h" + +namespace love +{ +namespace joystick +{ + +class JoystickModule : public Module +{ +public: + + virtual ~JoystickModule() {} + + /** + * Adds a connected Joystick device and opens it for use. + * Returns NULL if the Joystick could not be added. + **/ + virtual Joystick *addJoystick(int deviceindex) = 0; + + /** + * Removes a disconnected Joystick device. + **/ + virtual void removeJoystick(Joystick *joystick) = 0; + + /** + * Gets a connected Joystick from its unique Instance ID. + * Returns NULL if the instance ID does not correspond to a connected stick. + **/ + virtual Joystick *getJoystickFromID(int instanceid) = 0; + + /** + * Gets a connected Joystick. + * Returns NULL if joyindex is not in the range of [0, getJoystickCount()). + **/ + virtual Joystick *getJoystick(int joyindex) = 0; + + /** + * Gets the index of a connected joystick. + * Returns -1 if the joystick is not connected. + **/ + virtual int getIndex(const Joystick *joystick) = 0; + + /** + * Gets the number of currently connected Joysticks. + **/ + virtual int getJoystickCount() const = 0; + + /** + * Sets the virtual Gamepad mapping for a joystick input value for all + * joystick devices with the specified joystick product GUID. + * If any joysticks with the specified GUID are connected, they will be + * added as Gamepads if they aren't already, otherwise their Gamepad mapping + * will be updated. + **/ + virtual bool setGamepadMapping(const std::string &pguid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput) = 0; + + /** + * Gets the joystick input value the gamepad input value is bound to for the + * specified joystick product GUID. + **/ + virtual Joystick::JoystickInput getGamepadMapping(const std::string &pguid, Joystick::GamepadInput gpinput) = 0; + +}; // JoystickModule + +} // joystick +} // love + +#endif // LOVE_JOYSTICK_JOYSTICK_MODULE_H diff --git a/src/modules/joystick/sdl/Joystick.cpp b/src/modules/joystick/sdl/Joystick.cpp index deeca8d4c..ed370a270 100644 --- a/src/modules/joystick/sdl/Joystick.cpp +++ b/src/modules/joystick/sdl/Joystick.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,10 +18,13 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE +#include "common/config.h" #include "Joystick.h" +#include "common/int.h" -// STD -#include +// C++ +#include namespace love { @@ -30,230 +33,437 @@ namespace joystick namespace sdl { -Joystick::Joystick() - : joysticks(0) +Joystick::Joystick(int id) + : joyhandle(0) + , controller(0) + , haptic(0) + , instanceid(-1) + , id(id) + , vibration() { - // Init the SDL joystick system. - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) - throw love::Exception("%s", SDL_GetError()); +} - // Start joystick event watching. - SDL_JoystickEventState(SDL_ENABLE); - - // Open all connected joysticks. - int numjoysticks = this->getNumJoysticks(); - this->joysticks = (SDL_Joystick **)calloc(numjoysticks, sizeof(SDL_Joystick *)); - - for (int i = 0; iopen(i); +Joystick::Joystick(int id, int joyindex) + : joyhandle(0) + , controller(0) + , haptic(0) + , instanceid(-1) + , id(id) + , vibration() +{ + open(joyindex); } Joystick::~Joystick() { - // Closes any open joysticks. - for (int i = 0; i != getNumJoysticks(); i++) - { - if (isOpen(i)) - close(i); - } - - free(joysticks); - - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + close(); } -void Joystick::reload() +bool Joystick::open(int deviceindex) { - // Closes any open joysticks. - for (int i = 0; i != getNumJoysticks(); i++) + close(); + + joyhandle = SDL_JoystickOpen(deviceindex); + + if (joyhandle) { - if (isOpen(i)) - close(i); + instanceid = SDL_JoystickInstanceID(joyhandle); + + // SDL_JoystickGetGUIDString uses 32 bytes plus the null terminator. + char cstr[33]; + + SDL_JoystickGUID sdlguid = SDL_JoystickGetGUID(joyhandle); + SDL_JoystickGetGUIDString(sdlguid, cstr, (int) sizeof(cstr)); + + pguid = std::string(cstr); + + // See if SDL thinks this is a Game Controller. + openGamepad(deviceindex); + + // Prefer the Joystick name for consistency. + const char *joyname = SDL_JoystickName(joyhandle); + if (!joyname && controller) + joyname = SDL_GameControllerName(controller); + + if (joyname) + name = joyname; } - free(joysticks); + return isConnected(); +} - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +void Joystick::close() +{ + if (haptic) + { + SDL_HapticRumbleStop(haptic); + SDL_HapticClose(haptic); + } - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) - throw love::Exception("%s", SDL_GetError()); + if (controller) + SDL_GameControllerClose(controller); - int numjoysticks = this->getNumJoysticks(); - this->joysticks = (SDL_Joystick **)calloc(numjoysticks, sizeof(SDL_Joystick *)); + if (joyhandle) + SDL_JoystickClose(joyhandle); - for (int i = 0; iopen(i); + joyhandle = 0; + controller = 0; + haptic = 0; + instanceid = -1; + vibration = Vibration(); +} + +bool Joystick::isConnected() const +{ + return joyhandle != 0 && SDL_JoystickGetAttached(joyhandle); } const char *Joystick::getName() const { - return "love.joystick.sdl"; + // Use the saved name if this Joystick isn't connected anymore. + if (!isConnected()) + return name.c_str(); + + // Prefer the Joystick name for consistency. + const char *joyname = SDL_JoystickName(joyhandle); + + if (!joyname && isGamepad()) + joyname = SDL_GameControllerName(controller); + + return joyname; } -bool Joystick::checkIndex(int index) +int Joystick::getAxisCount() const { - return index >= 0 && index < getNumJoysticks(); + return isConnected() ? SDL_JoystickNumAxes(joyhandle) : 0; } -int Joystick::getNumJoysticks() +int Joystick::getButtonCount() const { - int num = SDL_NumJoysticks(); - return num < 0 ? 0 : num; + return isConnected() ? SDL_JoystickNumButtons(joyhandle) : 0; } -const char *Joystick::getName(int index) +int Joystick::getHatCount() const { - return SDL_JoystickName(index); + return isConnected() ? SDL_JoystickNumHats(joyhandle) : 0; } -bool Joystick::open(int index) +float Joystick::getAxis(int axisindex) const { - if (isOpen(index)) - return true; - - if (!checkIndex(index)) - return false; - - if (!(joysticks[index] = SDL_JoystickOpen(index))) - return false; - - return true; -} - -bool Joystick::isOpen(int index) -{ - if (!checkIndex(index)) - return false; - - return joysticks[index] != 0 ? true : false; -} - -bool Joystick::verifyJoystick(int index) -{ - if (!checkIndex(index)) - return false; - - if (!isOpen(index)) - return false; - - return true; -} - -int Joystick::getNumAxes(int index) -{ - return verifyJoystick(index) ? SDL_JoystickNumAxes(joysticks[index]) : 0; -} - -int Joystick::getNumBalls(int index) -{ - return verifyJoystick(index) ? SDL_JoystickNumBalls(joysticks[index]) : 0; -} - -int Joystick::getNumButtons(int index) -{ - return verifyJoystick(index) ? SDL_JoystickNumButtons(joysticks[index]) : 0; -} - -int Joystick::getNumHats(int index) -{ - return verifyJoystick(index) ? SDL_JoystickNumHats(joysticks[index]) : 0; -} - -float Joystick::clampval(float x) -{ - if (fabs((double)x) < 0.01) return 0.0f; - if (x < -0.99f) return -1.0f; - if (x > 0.99f) return 1.0f; - return x; -} - -float Joystick::getAxis(int index, int axis) -{ - if (!verifyJoystick(index)) + if (!isConnected() || axisindex < 0 || axisindex >= getAxisCount()) return 0; - if (axis >= getNumAxes(index)) - return 0; - - return clampval(((float)SDL_JoystickGetAxis(joysticks[index], axis))/32768.0f); + return clampval(((float) SDL_JoystickGetAxis(joyhandle, axisindex))/32768.0f); } -int Joystick::getAxes(lua_State *L) +std::vector Joystick::getAxes() const { - love::luax_assert_argc(L, 1, 1); - int index = (int)lua_tointeger(L, 1) - 1; + std::vector axes; + int count = getAxisCount(); - if (!verifyJoystick(index)) - return 0; + if (!isConnected() || count <= 0) + return axes; - int num = getNumAxes(index); + axes.reserve(count); - for (int i = 0; i= getHatCount()) + return h; - if (ball >= getNumBalls(index)) - return 0; + getConstant(SDL_JoystickGetHat(joyhandle, hatindex), h); - int dx, dy; - SDL_JoystickGetBall(joysticks[index], ball, &dx, &dy); - - lua_pushnumber(L, dx); - lua_pushnumber(L, dy); - return 2; + return h; } -bool Joystick::isDown(int index, int *buttonlist) +bool Joystick::isDown(const std::vector &buttonlist) const { - if (!verifyJoystick(index)) + if (!isConnected()) return false; - int num = getNumButtons(index); + int num = getButtonCount(); - for (int button = *buttonlist; button != -1; button = *(++buttonlist)) + for (size_t i = 0; i < buttonlist.size(); i++) { - if (button >= 0 && button < num && SDL_JoystickGetButton(joysticks[index], button) == 1) + int button = buttonlist[i]; + if (button >= 0 && button < num && SDL_JoystickGetButton(joyhandle, button) == 1) return true; } return false; } -Joystick::Hat Joystick::getHat(int index, int hat) +bool Joystick::openGamepad(int deviceindex) { - Hat h = HAT_INVALID; + if (!SDL_IsGameController(deviceindex)) + return false; - if (!verifyJoystick(index)) - return h; + if (isGamepad()) + { + SDL_GameControllerClose(controller); + controller = 0; + } - if (hat >= getNumHats(index)) - return h; - - hats.find(SDL_JoystickGetHat(joysticks[index], hat), h); - - return h; + controller = SDL_GameControllerOpen(deviceindex); + return isGamepad(); } -void Joystick::close(int index) +bool Joystick::isGamepad() const { - if (!checkIndex(index)) - return; + return controller != 0; +} - if (joysticks[index]!=0) +float Joystick::getGamepadAxis(love::joystick::Joystick::GamepadAxis axis) const +{ + if (!isConnected() || !isGamepad()) + return 0.f; + + SDL_GameControllerAxis sdlaxis; + if (!getConstant(axis, sdlaxis)) + return 0.f; + + Sint16 value = SDL_GameControllerGetAxis(controller, sdlaxis); + + return clampval((float) value / 32768.0f); +} + +bool Joystick::isGamepadDown(const std::vector &blist) const +{ + if (!isConnected() || !isGamepad()) + return false; + + SDL_GameControllerButton sdlbutton; + + for (size_t i = 0; i < blist.size(); i++) { - SDL_JoystickClose(joysticks[index]); - joysticks[index] = 0; + if (!getConstant(blist[i], sdlbutton)) + continue; + + if (SDL_GameControllerGetButton(controller, sdlbutton) == 1) + return true; } + + return false; +} + +void *Joystick::getHandle() const +{ + return joyhandle; +} + +std::string Joystick::getGUID() const +{ + // SDL2's GUIDs identify *classes* of devices, instead of unique devices. + return pguid; +} + +int Joystick::getInstanceID() const +{ + return instanceid; +} + +int Joystick::getID() const +{ + return id; +} + +bool Joystick::checkCreateHaptic() +{ + if (!isConnected()) + return false; + + if (!SDL_WasInit(SDL_INIT_HAPTIC) && SDL_InitSubSystem(SDL_INIT_HAPTIC) < 0) + return false; + + if (haptic && SDL_HapticIndex(haptic) != -1) + return true; + + if (haptic) + { + SDL_HapticClose(haptic); + haptic = 0; + } + + haptic = SDL_HapticOpenFromJoystick(joyhandle); + vibration = Vibration(); + + return haptic != 0; +} + +bool Joystick::isVibrationSupported() +{ + if (!checkCreateHaptic()) + return false; + + unsigned int features = SDL_HapticQuery(haptic); + + if ((features & SDL_HAPTIC_LEFTRIGHT) != 0) + return true; + + // Some gamepad drivers only support left/right motors via a custom effect. + if (isGamepad() && (features & SDL_HAPTIC_CUSTOM) != 0) + return true; + + // Check SDL's simple rumble as a last resort. + if (SDL_HapticRumbleSupported(haptic) == 1) + return true; + + return false; +} + +bool Joystick::runVibrationEffect() +{ + if (vibration.id != -1) + { + if (SDL_HapticUpdateEffect(haptic, vibration.id, &vibration.effect) == 0) + { + if (SDL_HapticRunEffect(haptic, vibration.id, 1) != -1) + return true; + } + + // If the effect fails to update, we should destroy and re-create it. + SDL_HapticDestroyEffect(haptic, vibration.id); + vibration.id = -1; + } + + vibration.id = SDL_HapticNewEffect(haptic, &vibration.effect); + + if (vibration.id != -1 && SDL_HapticRunEffect(haptic, vibration.id, 1) != -1) + return true; + + return false; +} + +bool Joystick::setVibration(float left, float right) +{ + // TODO: support non-infinite durations? The working Tattiebogle Xbox + // controller driver in OS X seems to ignore durations under 1 second. + + left = std::min(std::max(left, 0.0f), 1.0f); + right = std::min(std::max(right, 0.0f), 1.0f); + + if (left == 0.0f && right == 0.0f) + return setVibration(); + + if (!checkCreateHaptic()) + return false; + + bool success = false; + unsigned int features = SDL_HapticQuery(haptic); + + if ((features & SDL_HAPTIC_LEFTRIGHT) != 0) + { + memset(&vibration.effect, 0, sizeof(SDL_HapticEffect)); + vibration.effect.type = SDL_HAPTIC_LEFTRIGHT; + + vibration.effect.leftright.length = SDL_HAPTIC_INFINITY; + vibration.effect.leftright.large_magnitude = Uint16(left * LOVE_UINT16_MAX); + vibration.effect.leftright.small_magnitude = Uint16(right * LOVE_UINT16_MAX); + + success = runVibrationEffect(); + } + + // Some gamepad drivers only give support for controlling the motors via + // a custom FF effect. + if (!success && isGamepad() && (features & SDL_HAPTIC_CUSTOM) != 0) + { + // NOTE: this may cause issues with drivers which support custom effects + // but aren't similar to https://github.com/d235j/360Controller . + + // Custom effect data is clamped to 0x7FFF in SDL. + vibration.data[0] = vibration.data[2] = Uint16(left * 0x7FFF); + vibration.data[1] = vibration.data[3] = Uint16(right * 0x7FFF); + + memset(&vibration.effect, 0, sizeof(SDL_HapticEffect)); + vibration.effect.type = SDL_HAPTIC_CUSTOM; + + vibration.effect.custom.length = SDL_HAPTIC_INFINITY; + vibration.effect.custom.channels = 2; + vibration.effect.custom.period = 10; + vibration.effect.custom.samples = 2; + vibration.effect.custom.data = vibration.data; + + success = runVibrationEffect(); + } + + // Fall back to a simple rumble if all else fails. SDL's simple rumble API + // only supports a single strength value. + if (!success && SDL_HapticRumbleInit(haptic) == 0) + { + float strength = std::max(left, right); + int played = SDL_HapticRumblePlay(haptic, strength, SDL_HAPTIC_INFINITY); + success = (played == 0); + } + + if (success) + { + vibration.left = left; + vibration.right = right; + } + + return success; +} + +bool Joystick::setVibration() +{ + bool success = true; + + if (SDL_WasInit(SDL_INIT_HAPTIC) && haptic && SDL_HapticIndex(haptic) != -1) + { + // Stop all playing effects on the haptic device. + // FIXME: We should only stop the vibration effect, in case we use the + // Haptic API for other things in the future. + success = (SDL_HapticStopAll(haptic) == 0); + } + + if (success) + vibration.left = vibration.right = 0.0f; + + return success; +} + +void Joystick::getVibration(float &left, float &right) const +{ + left = vibration.left; + right = vibration.right; +} + +bool Joystick::getConstant(Uint8 in, Joystick::Hat &out) +{ + return hats.find(in, out); +} + +bool Joystick::getConstant(Joystick::Hat in, Uint8 &out) +{ + return hats.find(in, out); +} + +bool Joystick::getConstant(SDL_GameControllerAxis in, Joystick::GamepadAxis &out) +{ + return gpAxes.find(in, out); +} + +bool Joystick::getConstant(Joystick::GamepadAxis in, SDL_GameControllerAxis &out) +{ + return gpAxes.find(in, out); +} + +bool Joystick::getConstant(SDL_GameControllerButton in, Joystick::GamepadButton &out) +{ + return gpButtons.find(in, out); +} + +bool Joystick::getConstant(Joystick::GamepadButton in, SDL_GameControllerButton &out) +{ + return gpButtons.find(in, out); } EnumMap::Entry Joystick::hatEntries[] = @@ -271,6 +481,39 @@ EnumMap::Entry Joystick::hatEntrie EnumMap Joystick::hats(Joystick::hatEntries, sizeof(Joystick::hatEntries)); +EnumMap::Entry Joystick::gpAxisEntries[] = +{ + {Joystick::GAMEPAD_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTX}, + {Joystick::GAMEPAD_AXIS_LEFTY, SDL_CONTROLLER_AXIS_LEFTY}, + {Joystick::GAMEPAD_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_RIGHTX}, + {Joystick::GAMEPAD_AXIS_RIGHTY, SDL_CONTROLLER_AXIS_RIGHTY}, + {Joystick::GAMEPAD_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, + {Joystick::GAMEPAD_AXIS_TRIGGERRIGHT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, +}; + +EnumMap Joystick::gpAxes(Joystick::gpAxisEntries, sizeof(Joystick::gpAxisEntries)); + +EnumMap::Entry Joystick::gpButtonEntries[] = +{ + {Joystick::GAMEPAD_BUTTON_A, SDL_CONTROLLER_BUTTON_A}, + {Joystick::GAMEPAD_BUTTON_B, SDL_CONTROLLER_BUTTON_B}, + {Joystick::GAMEPAD_BUTTON_X, SDL_CONTROLLER_BUTTON_X}, + {Joystick::GAMEPAD_BUTTON_Y, SDL_CONTROLLER_BUTTON_Y}, + {Joystick::GAMEPAD_BUTTON_BACK, SDL_CONTROLLER_BUTTON_BACK}, + {Joystick::GAMEPAD_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_GUIDE}, + {Joystick::GAMEPAD_BUTTON_START, SDL_CONTROLLER_BUTTON_START}, + {Joystick::GAMEPAD_BUTTON_LEFTSTICK, SDL_CONTROLLER_BUTTON_LEFTSTICK}, + {Joystick::GAMEPAD_BUTTON_RIGHTSTICK, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, + {Joystick::GAMEPAD_BUTTON_LEFTSHOULDER, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, + {Joystick::GAMEPAD_BUTTON_RIGHTSHOULDER, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, + {Joystick::GAMEPAD_BUTTON_DPAD_UP, SDL_CONTROLLER_BUTTON_DPAD_UP}, + {Joystick::GAMEPAD_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, + {Joystick::GAMEPAD_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, + {Joystick::GAMEPAD_BUTTON_DPAD_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, +}; + +EnumMap Joystick::gpButtons(Joystick::gpButtonEntries, sizeof(Joystick::gpButtonEntries)); + } // sdl } // joystick } // love diff --git a/src/modules/joystick/sdl/Joystick.h b/src/modules/joystick/sdl/Joystick.h index 1604c5129..929cb5454 100644 --- a/src/modules/joystick/sdl/Joystick.h +++ b/src/modules/joystick/sdl/Joystick.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -37,40 +37,96 @@ namespace sdl class Joystick : public love::joystick::Joystick { -private: - SDL_Joystick **joysticks; public: - Joystick(); + + Joystick(int id); + Joystick(int id, int joyindex); + virtual ~Joystick(); - // Implements Module. + bool open(int deviceindex); + void close(); + + bool isConnected() const; + const char *getName() const; - void reload(); - bool checkIndex(int index); - int getNumJoysticks(); - const char *getName(int index); - bool open(int index); - bool isOpen(int index); - bool verifyJoystick(int index); - int getNumAxes(int index); - int getNumBalls(int index); - int getNumButtons(int index); - int getNumHats(int index); - float clampval(float x); - float getAxis(int index, int axis); - int getAxes(lua_State *L); - int getBall(lua_State *L); - bool isDown(int index, int *buttonlist); - Hat getHat(int index, int hat); - void close(int index); + int getAxisCount() const; + int getButtonCount() const; + int getHatCount() const; + + float getAxis(int axisindex) const; + std::vector getAxes() const; + Hat getHat(int hatindex) const; + + bool isDown(const std::vector &buttonlist) const; + + bool openGamepad(int deviceindex); + bool isGamepad() const; + + float getGamepadAxis(GamepadAxis axis) const; + bool isGamepadDown(const std::vector &blist) const; + + void *getHandle() const; + + std::string getGUID() const; + int getInstanceID() const; + int getID() const; + + bool isVibrationSupported(); + bool setVibration(float left, float right); + bool setVibration(); + void getVibration(float &left, float &right) const; + + static bool getConstant(Hat in, Uint8 &out); + static bool getConstant(Uint8 in, Hat &out); + + static bool getConstant(SDL_GameControllerAxis in, GamepadAxis &out); + static bool getConstant(GamepadAxis in, SDL_GameControllerAxis &out); + + static bool getConstant(SDL_GameControllerButton in, GamepadButton &out); + static bool getConstant(GamepadButton in, SDL_GameControllerButton &out); private: + Joystick() {} + + bool checkCreateHaptic(); + bool runVibrationEffect(); + + SDL_Joystick *joyhandle; + SDL_GameController *controller; + SDL_Haptic *haptic; + + SDL_JoystickID instanceid; + std::string pguid; + int id; + + std::string name; + + struct Vibration + { + float left, right; + SDL_HapticEffect effect; + Uint16 data[4]; + int id; + + Vibration() + : left(0.0f), right(0.0f), effect(), data(), id(-1) + {} + + } vibration; + static EnumMap::Entry hatEntries[]; static EnumMap hats; -}; // Joystick + static EnumMap::Entry gpAxisEntries[]; + static EnumMap gpAxes; + + static EnumMap::Entry gpButtonEntries[]; + static EnumMap gpButtons; + +}; } // sdl } // joystick diff --git a/src/modules/joystick/sdl/JoystickModule.cpp b/src/modules/joystick/sdl/JoystickModule.cpp new file mode 100644 index 000000000..f037927b1 --- /dev/null +++ b/src/modules/joystick/sdl/JoystickModule.cpp @@ -0,0 +1,467 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "common/config.h" +#include "JoystickModule.h" +#include "Joystick.h" + +// SDL +#include + +// C++ +#include +#include + +// C +#include + +namespace love +{ +namespace joystick +{ +namespace sdl +{ + +JoystickModule::JoystickModule() +{ + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) + throw love::Exception("%s", SDL_GetError()); + + // Initialize any joysticks which are already connected. + for (int i = 0; i < SDL_NumJoysticks(); i++) + addJoystick(i); + + // Start joystick event watching. Joysticks are automatically added and + // removed via love.event. + SDL_JoystickEventState(SDL_ENABLE); + SDL_GameControllerEventState(SDL_ENABLE); +} + +JoystickModule::~JoystickModule() +{ + // Close any open Joysticks. + for (auto it = joysticks.begin(); it != joysticks.end(); ++it) + { + (*it)->close(); + (*it)->release(); + } + + if (SDL_WasInit(SDL_INIT_HAPTIC) != 0) + SDL_QuitSubSystem(SDL_INIT_HAPTIC); + + SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); +} + +const char *JoystickModule::getName() const +{ + return "love.joystick.sdl"; +} + +love::joystick::Joystick *JoystickModule::getJoystick(int joyindex) +{ + if (joyindex < 0 || (size_t) joyindex >= activeSticks.size()) + return 0; + + return activeSticks[joyindex]; +} + +int JoystickModule::getIndex(const love::joystick::Joystick *joystick) +{ + for (size_t i = 0; i < activeSticks.size(); i++) + { + if (activeSticks[i] == joystick) + return i; + } + + // Joystick is not connected. + return -1; +} + +int JoystickModule::getJoystickCount() const +{ + return (int) activeSticks.size(); +} + +love::joystick::Joystick *JoystickModule::getJoystickFromID(int instanceid) +{ + for (size_t i = 0; i < activeSticks.size(); i++) + { + if (instanceid == activeSticks[i]->getInstanceID()) + return activeSticks[i]; + } + + return 0; +} + +love::joystick::Joystick *JoystickModule::addJoystick(int deviceindex) +{ + if (deviceindex < 0 || deviceindex >= SDL_NumJoysticks()) + return 0; + + std::string guidstr = getDeviceGUID(deviceindex); + joystick::Joystick *joystick = 0; + bool reused = false; + + for (auto it = joysticks.begin(); it != joysticks.end(); ++it) + { + // Try to re-use a disconnected Joystick with the same GUID. + if (!(*it)->isConnected() && (*it)->getGUID() == guidstr) + { + joystick = *it; + reused = true; + break; + } + } + + if (!joystick) + { + joystick = new Joystick(joysticks.size()); + joysticks.push_back(joystick); + } + + // Make sure the Joystick object isn't in the active list already. + removeJoystick(joystick); + + if (!joystick->open(deviceindex)) + return 0; + + // Make sure multiple instances of the same physical joystick aren't added + // to the active list. + for (auto it = activeSticks.begin(); it != activeSticks.end(); ++it) + { + if (joystick->getHandle() == (*it)->getHandle()) + { + joystick->close(); + + // If we just created the stick, remove it since it's a duplicate. + if (!reused) + { + joysticks.remove(joystick); + joystick->release(); + } + + return *it; + } + } + + activeSticks.push_back(joystick); + return joystick; +} + +void JoystickModule::removeJoystick(love::joystick::Joystick *joystick) +{ + if (!joystick) + return; + + // Close the Joystick and remove it from the active joystick list. + auto it = std::find(activeSticks.begin(), activeSticks.end(), joystick); + if (it != activeSticks.end()) + { + (*it)->close(); + activeSticks.erase(it); + } +} + +bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput) +{ + // All SDL joystick GUID strings are 32 characters. + if (guid.length() != 32) + throw love::Exception("Invalid joystick GUID: %s", guid.c_str()); + + SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(guid.c_str()); + std::string mapstr; + + char *sdlmapstr = SDL_GameControllerMappingForGUID(sdlguid); + if (sdlmapstr) + { + mapstr = sdlmapstr; + SDL_free(sdlmapstr); + } + else + { + // Use a generic name if we have to create a new mapping string. + mapstr = guid + ",Controller,"; + } + + std::stringstream joyinputstream; + Uint8 sdlhat; + + // We can't have negative int values in the bind string. + switch (joyinput.type) + { + case Joystick::INPUT_TYPE_AXIS: + if (joyinput.axis >= 0) + joyinputstream << "a" << joyinput.axis; + break; + case Joystick::INPUT_TYPE_BUTTON: + if (joyinput.button >= 0) + joyinputstream << "b" << joyinput.button; + break; + case Joystick::INPUT_TYPE_HAT: + if (joyinput.hat.value >= 0 && Joystick::getConstant(joyinput.hat.value, sdlhat)) + joyinputstream << "h" << joyinput.hat.value << "." << int(sdlhat); + break; + default: + break; + } + + std::string joyinputstr = joyinputstream.str(); + + if (joyinputstr.length() == 0) + throw love::Exception("Invalid joystick input value."); + + // SDL's name for the gamepad input value, e.g. "guide". + std::string gpinputname = stringFromGamepadInput(gpinput); + + // We should remove any existing joystick bind for this gamepad buttton/axis + // so SDL's parser doesn't get mixed up. + removeBindFromMapString(mapstr, joyinputstr); + + // The string we'll be adding to the mapping string, e.g. "guide:b10," + std::string insertstr = gpinputname + ":" + joyinputstr + ","; + + // We should replace any existing gamepad bind. + size_t findpos = mapstr.find(gpinputname + ":"); + if (findpos != std::string::npos) + { + // The bind string ends at the next comma, or the end of the string. + size_t endpos = mapstr.find_first_of(',', findpos); + if (endpos == std::string::npos) + endpos = mapstr.length() - 1; + + mapstr.replace(findpos, endpos - findpos + 1, insertstr); + } + else + { + // Just append to the end if we don't need to replace anything. + mapstr += insertstr; + } + + // 1 == added, 0 == updated, -1 == error. + int status = SDL_GameControllerAddMapping(mapstr.c_str()); + + // FIXME: massive hack until missing APIs are added to SDL 2: + // https://bugzilla.libsdl.org/show_bug.cgi?id=1975 + if (status == 1) + checkGamepads(guid); + + return status >= 0; +} + +Joystick::JoystickInput JoystickModule::getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput) +{ + // All SDL joystick GUID strings are 32 characters. + if (guid.length() != 32) + throw love::Exception("Invalid joystick GUID: %s", guid.c_str()); + + Joystick::JoystickInput jinput; + jinput.type = Joystick::INPUT_TYPE_MAX_ENUM; + + SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(guid.c_str()); + + std::string mapstr; + + char *sdlmapstr = SDL_GameControllerMappingForGUID(sdlguid); + if (!sdlmapstr) + return jinput; + + mapstr = sdlmapstr; + SDL_free(sdlmapstr); + + std::string gpbindname = stringFromGamepadInput(gpinput); + + size_t findpos = mapstr.find(std::string(",") + gpbindname + ":"); + if (findpos == std::string::npos) + return jinput; + + size_t endpos = mapstr.find_first_of(',', findpos); + if (endpos == std::string::npos) + { + // Assume end-of-string if we can't find the next comma. + endpos = mapstr.length() - 1; + } + + if (endpos >= mapstr.length()) + return jinput; // Something went wrong. + + // Strip out the trailing comma from our search position, if it exists. + if (mapstr[endpos] == ',') + endpos--; + + // New start position: comma + gamepadinputlength + ":". + findpos += 1 + gpbindname.length() + 1; + std::string jbindstr = mapstr.substr(findpos, endpos - findpos + 1); + + jinput = JoystickInputFromString(jbindstr); + return jinput; +} + +std::string JoystickModule::stringFromGamepadInput(Joystick::GamepadInput gpinput) const +{ + SDL_GameControllerAxis sdlaxis; + SDL_GameControllerButton sdlbutton; + + const char *gpinputname = 0; + + switch (gpinput.type) + { + case Joystick::INPUT_TYPE_AXIS: + if (Joystick::getConstant(gpinput.axis, sdlaxis)) + gpinputname = SDL_GameControllerGetStringForAxis(sdlaxis); + break; + case Joystick::INPUT_TYPE_BUTTON: + if (Joystick::getConstant(gpinput.button, sdlbutton)) + gpinputname = SDL_GameControllerGetStringForButton(sdlbutton); + break; + default: + break; + } + + if (!gpinputname) + throw love::Exception("Invalid gamepad axis/button."); + + return std::string(gpinputname); +} + +Joystick::JoystickInput JoystickModule::JoystickInputFromString(const std::string &str) const +{ + Joystick::JoystickInput jinput; + jinput.type = Joystick::INPUT_TYPE_MAX_ENUM; + + // Return an invalid value rather than throwing an exception. + if (str.length() < 2) + return jinput; + + // The input type will always be the first character in the string. + char inputtype = str[0]; + std::string bindvalues = str.substr(1); + + Uint8 sdlhat; + switch (inputtype) + { + case 'a': + jinput.type = Joystick::INPUT_TYPE_AXIS; + jinput.axis = atoi(bindvalues.c_str()); + break; + case 'b': + jinput.type = Joystick::INPUT_TYPE_BUTTON; + jinput.button = atoi(bindvalues.c_str()); + break; + case 'h': + // Hat string syntax is "index.value". + if (bindvalues.length() < 3) + break; + jinput.type = Joystick::INPUT_TYPE_HAT; + jinput.hat.index = atoi(bindvalues.substr(0, 1).c_str()); + sdlhat = (Uint8) atoi(bindvalues.substr(2, 1).c_str()); + if (!Joystick::getConstant(sdlhat, jinput.hat.value)) + { + // Return an invalid value if we can't find the hat constant. + jinput.type = Joystick::INPUT_TYPE_MAX_ENUM; + return jinput; + } + break; + default: + break; + } + + return jinput; +} + +void JoystickModule::removeBindFromMapString(std::string &mapstr, const std::string &joybindstr) const +{ + // Find the joystick part of the bind in the string. + size_t joybindpos = mapstr.find(joybindstr + ","); + if (joybindpos == std::string::npos) + { + joybindpos = mapstr.rfind(joybindstr); + if (joybindpos != mapstr.length() - joybindstr.length()) + return; + } + + if (joybindpos == std::string::npos) + return; + + // Find the start of the entire bind. + size_t bindstart = mapstr.rfind(',', joybindpos); + if (bindstart != std::string::npos && bindstart < mapstr.length() - 1) + { + size_t bindend = mapstr.find(',', bindstart + 1); + if (bindend == std::string::npos) + bindend = mapstr.length() - 1; + + // Replace it with an empty string (remove it.) + mapstr.replace(bindstart, bindend - bindstart + 1, ""); + } +} + +void JoystickModule::checkGamepads(const std::string &guid) const +{ + // FIXME: massive hack until missing APIs are added to SDL 2: + // https://bugzilla.libsdl.org/show_bug.cgi?id=1975 + + // Make sure all connected joysticks of a certain guid that are + // gamepad-capable are opened as such. + for (int d_index = 0; d_index < SDL_NumJoysticks(); d_index++) + { + if (!SDL_IsGameController(d_index)) + continue; + + if (guid.compare(getDeviceGUID(d_index)) != 0) + continue; + + for (auto it = activeSticks.begin(); it != activeSticks.end(); ++it) + { + if ((*it)->isGamepad() || guid.compare((*it)->getGUID()) != 0) + continue; + + // Big hack time: open the index as a game controller and compare + // the underlying joystick handle to the active stick's. + SDL_GameController *ctrl = SDL_GameControllerOpen(d_index); + if (ctrl == NULL) + continue; + + SDL_Joystick *stick = SDL_GameControllerGetJoystick(ctrl); + if (stick == (SDL_Joystick *) (*it)->getHandle()) + (*it)->openGamepad(d_index); + + SDL_GameControllerClose(ctrl); + } + } +} + +std::string JoystickModule::getDeviceGUID(int deviceindex) const +{ + if (deviceindex < 0 || deviceindex >= SDL_NumJoysticks()) + return std::string(""); + + // SDL_JoystickGetGUIDString uses 32 bytes plus the null terminator. + char guidstr[33] = {'\0'}; + + // SDL2's GUIDs identify *classes* of devices, instead of unique devices. + SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(deviceindex); + SDL_JoystickGetGUIDString(guid, guidstr, sizeof(guidstr)); + + return std::string(guidstr); +} + +} // sdl +} // joystick +} // love diff --git a/src/modules/joystick/sdl/JoystickModule.h b/src/modules/joystick/sdl/JoystickModule.h new file mode 100644 index 000000000..ba7c8feb1 --- /dev/null +++ b/src/modules/joystick/sdl/JoystickModule.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_JOYSTICK_SDL_JOYSTICK_MODULE_H +#define LOVE_JOYSTICK_SDL_JOYSTICK_MODULE_H + +// LOVE +#include "joystick/JoystickModule.h" + +// C++ +#include +#include +#include + +namespace love +{ +namespace joystick +{ +namespace sdl +{ + +class JoystickModule : public love::joystick::JoystickModule +{ +public: + + JoystickModule(); + virtual ~JoystickModule(); + + // Implements Module. + const char *getName() const; + + // Implements JoystickModule. + love::joystick::Joystick *addJoystick(int deviceindex); + void removeJoystick(love::joystick::Joystick *joystick); + love::joystick::Joystick *getJoystickFromID(int instanceid); + love::joystick::Joystick *getJoystick(int joyindex); + int getIndex(const love::joystick::Joystick *joystick); + int getJoystickCount() const; + + bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput); + Joystick::JoystickInput getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput); + +private: + + std::string stringFromGamepadInput(Joystick::GamepadInput gpinput) const; + Joystick::JoystickInput JoystickInputFromString(const std::string &str) const; + void removeBindFromMapString(std::string &mapstr, const std::string &joybindstr) const; + + void checkGamepads(const std::string &guid) const; + + // SDL2's GUIDs identify *classes* of devices, instead of unique devices. + std::string getDeviceGUID(int deviceindex) const; + + // Lists of currently connected Joysticks. + std::vector activeSticks; + + // Persistent list of all Joysticks which have been connected at some point. + std::list joysticks; + +}; // JoystickModule + +} // sdl +} // joystick +} // love + +#endif // LOVE_JOYSTICK_SDL_JOYSTICK_MODULE_H diff --git a/src/modules/joystick/sdl/wrap_Joystick.cpp b/src/modules/joystick/sdl/wrap_Joystick.cpp index 646709e83..a0eb45694 100644 --- a/src/modules/joystick/sdl/wrap_Joystick.cpp +++ b/src/modules/joystick/sdl/wrap_Joystick.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,7 +18,11 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "wrap_Joystick.h" +#include "wrap_JoystickModule.h" + +#include namespace love { @@ -27,157 +31,231 @@ namespace joystick namespace sdl { -static Joystick *instance = 0; - -int w_reload(lua_State *L) +Joystick *luax_checkjoystick(lua_State *L, int idx) { - try - { - instance->reload(); - } - catch(love::Exception &e) - { - return luaL_error(L, "%s", e.what()); - } - return 0; + return luax_checktype(L, idx, "Joystick", JOYSTICK_JOYSTICK_T); } -int w_getNumJoysticks(lua_State *L) +int w_Joystick_isConnected(lua_State *L) { - lua_pushinteger(L, instance->getNumJoysticks()); + Joystick *j = luax_checkjoystick(L, 1); + luax_pushboolean(L, j->isConnected()); return 1; } -int w_getName(lua_State *L) +int w_Joystick_getName(lua_State *L) { - int index = luaL_checkint(L, 1)-1; - lua_pushstring(L, instance->getName(index)); + Joystick *j = luax_checkjoystick(L, 1); + lua_pushstring(L, j->getName()); return 1; } -int w_getNumAxes(lua_State *L) +int w_Joystick_getID(lua_State *L) { - int index = luaL_checkint(L, 1)-1; - lua_pushinteger(L, instance->getNumAxes(index)); + Joystick *j = luax_checkjoystick(L, 1); + + // IDs are 1-based in Lua. + lua_pushinteger(L, j->getID() + 1); + + int instanceid = j->getInstanceID(); + if (instanceid >= 0) + lua_pushinteger(L, instanceid + 1); + else + lua_pushnil(L); + + return 2; +} + +int w_Joystick_getGUID(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + luax_pushstring(L, j->getGUID()); return 1; } -int w_getNumBalls(lua_State *L) +int w_Joystick_getAxisCount(lua_State *L) { - int index = luaL_checkint(L, 1)-1; - lua_pushinteger(L, instance->getNumBalls(index)); + Joystick *j = luax_checkjoystick(L, 1); + lua_pushinteger(L, j->getAxisCount()); return 1; } -int w_getNumButtons(lua_State *L) +int w_Joystick_getButtonCount(lua_State *L) { - int index = luaL_checkint(L, 1)-1; - lua_pushinteger(L, instance->getNumButtons(index)); + Joystick *j = luax_checkjoystick(L, 1); + lua_pushinteger(L, j->getButtonCount()); return 1; } -int w_getNumHats(lua_State *L) +int w_Joystick_getHatCount(lua_State *L) { - int index = luaL_checkint(L, 1)-1; - lua_pushinteger(L, instance->getNumHats(index)); + Joystick *j = luax_checkjoystick(L, 1); + lua_pushinteger(L, j->getHatCount()); return 1; } -int w_getAxis(lua_State *L) +int w_Joystick_getAxis(lua_State *L) { - int index = luaL_checkint(L, 1)-1; - int axis = luaL_checkint(L, 2)-1; - lua_pushnumber(L, instance->getAxis(index, axis)); + Joystick *j = luax_checkjoystick(L, 1); + int axisindex = luaL_checkint(L, 2) - 1; + lua_pushnumber(L, j->getAxis(axisindex)); return 1; } -int w_getAxes(lua_State *L) +int w_Joystick_getAxes(lua_State *L) { - return instance->getAxes(L); + Joystick *j = luax_checkjoystick(L, 1); + std::vector axes = j->getAxes(); + + for (size_t i = 0; i < axes.size(); i++) + lua_pushnumber(L, axes[i]); + + return (int) axes.size(); } -int w_getBall(lua_State *L) +int w_Joystick_getHat(lua_State *L) { - return instance->getBall(L); -} + Joystick *j = luax_checkjoystick(L, 1); + int hatindex = luaL_checkint(L, 2) - 1; -int w_isDown(lua_State *L) -{ - int index = luaL_checkint(L, 1)-1; - unsigned int num = lua_gettop(L); - int *buttonlist = new int[num]; - unsigned int counter = 0; - - for (unsigned int i = 1; i < num; i++) - { - buttonlist[counter++] = (int) luaL_checknumber(L, i+1)-1; - } - buttonlist[counter] = -1; - - luax_pushboolean(L, instance->isDown(index, buttonlist)); - delete[] buttonlist; - return 1; -} - -int w_getHat(lua_State *L) -{ - int index = luaL_checkint(L, 1)-1; - int hat = luaL_checkint(L, 2)-1; - - Joystick::Hat h = instance->getHat(index, hat); + Joystick::Hat h = j->getHat(hatindex); const char *direction = ""; - Joystick::getConstant(h, direction); - lua_pushstring(L, direction); + love::joystick::Joystick::getConstant(h, direction); + lua_pushstring(L, direction); return 1; } +int w_Joystick_isDown(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + + luaL_checkinteger(L, 2); + + std::vector buttons; + for (int i = 2; i <= lua_gettop(L); i++) + buttons.push_back(luaL_checkint(L, i) - 1); + + luax_pushboolean(L, j->isDown(buttons)); + return 1; +} + +int w_Joystick_isGamepad(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + luax_pushboolean(L, j->isGamepad()); + return 1; +} + +int w_Joystick_getGamepadAxis(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + + const char *str = luaL_checkstring(L, 2); + Joystick::GamepadAxis axis; + + if (!joystick::Joystick::getConstant(str, axis)) + return luaL_error(L, "Invalid gamepad axis: %s", str); + + lua_pushnumber(L, j->getGamepadAxis(axis)); + return 1; +} + +int w_Joystick_isGamepadDown(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + + std::vector buttons; + buttons.reserve(lua_gettop(L) - 1); + + luaL_checkstring(L, 2); + + for (int i = 2; i <= lua_gettop(L); i++) + { + const char *str = luaL_checkstring(L, i); + Joystick::GamepadButton button; + + if (!joystick::Joystick::getConstant(str, button)) + return luaL_error(L, "Invalid gamepad button: %s", str); + + buttons.push_back(button); + } + + luax_pushboolean(L, j->isGamepadDown(buttons)); + return 1; +} + +int w_Joystick_isVibrationSupported(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + luax_pushboolean(L, j->isVibrationSupported()); + return 1; +} + +int w_Joystick_setVibration(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + bool success = false; + + if (lua_isnoneornil(L, 2)) + { + // Disable joystick vibration if no argument is given. + success = j->setVibration(); + } + else + { + float left = (float) luaL_checknumber(L, 2); + float right = (float) luaL_optnumber(L, 3, left); + success = j->setVibration(left, right); + } + + luax_pushboolean(L, success); + return 1; +} + +int w_Joystick_getVibration(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + float left, right; + j->getVibration(left, right); + lua_pushnumber(L, left); + lua_pushnumber(L, right); + return 2; +} + // List of functions to wrap. static const luaL_Reg functions[] = { - { "reload", w_reload }, - { "getNumJoysticks", w_getNumJoysticks }, - { "getName", w_getName }, - { "getNumAxes", w_getNumAxes }, - { "getNumBalls", w_getNumBalls }, - { "getNumButtons", w_getNumButtons }, - { "getNumHats", w_getNumHats }, - { "getAxis", w_getAxis }, + { "isConnected", w_Joystick_isConnected }, + { "getName", w_Joystick_getName }, + { "getID", w_Joystick_getID }, + { "getGUID", w_Joystick_getGUID }, + { "getAxisCount", w_Joystick_getAxisCount }, + { "getButtonCount", w_Joystick_getButtonCount }, + { "getHatCount", w_Joystick_getHatCount }, + { "getAxis", w_Joystick_getAxis }, + { "getAxes", w_Joystick_getAxes }, + { "getHat", w_Joystick_getHat }, + { "isDown", w_Joystick_isDown }, - { "getAxes", w_getAxes }, - { "getBall", w_getBall }, + { "isGamepad", w_Joystick_isGamepad }, + { "getGamepadAxis", w_Joystick_getGamepadAxis }, + { "isGamepadDown", w_Joystick_isGamepadDown }, - { "isDown", w_isDown }, - { "getHat", w_getHat }, - { 0, 0 } + { "isVibrationSupported", w_Joystick_isVibrationSupported }, + { "setVibration", w_Joystick_setVibration }, + { "getVibration", w_Joystick_getVibration }, + + // From wrap_JoystickModule. + { "getConnectedIndex", w_getIndex }, + { "getGamepadMapping", w_getGamepadMapping }, + { 0, 0 }, }; -extern "C" int luaopen_love_joystick(lua_State *L) +extern "C" int luaopen_joystick(lua_State *L) { - if (instance == 0) - { - try - { - instance = new Joystick(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } - } - else - instance->retain(); - - - WrappedModule w; - w.module = instance; - w.name = "joystick"; - w.flags = MODULE_T; - w.functions = functions; - w.types = 0; - - return luax_register_module(L, w); + return luax_register_type(L, "Joystick", functions); } } // sdl diff --git a/src/modules/joystick/sdl/wrap_Joystick.h b/src/modules/joystick/sdl/wrap_Joystick.h index f49c11fe9..42f446d87 100644 --- a/src/modules/joystick/sdl/wrap_Joystick.h +++ b/src/modules/joystick/sdl/wrap_Joystick.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -24,6 +24,7 @@ // LOVE #include "common/config.h" #include "Joystick.h" +#include "common/runtime.h" namespace love { @@ -32,19 +33,25 @@ namespace joystick namespace sdl { -int w_reload(lua_State *L); -int w_getNumJoysticks(lua_State *L); -int w_getName(lua_State *L); -int w_getNumAxes(lua_State *L); -int w_getNumBalls(lua_State *L); -int w_getNumButtons(lua_State *L); -int w_getNumHats(lua_State *L); -int w_getAxis(lua_State *L); -int w_getAxes(lua_State *L); -int w_getBall(lua_State *L); -int w_isDown(lua_State *L); -int w_getHat(lua_State *L); -extern "C" LOVE_EXPORT int luaopen_love_joystick(lua_State *L); +Joystick *luax_checkjoystick(lua_State *L, int idx); +int w_Joystick_isConnected(lua_State *L); +int w_Joystick_getName(lua_State *L); +int w_Joystick_getID(lua_State *L); +int w_Joystick_getGUID(lua_State *L); +int w_Joystick_getAxisCount(lua_State *L); +int w_Joystick_getButtonCount(lua_State *L); +int w_Joystick_getHatCount(lua_State *L); +int w_Joystick_getAxis(lua_State *L); +int w_Joystick_getAxes(lua_State *L); +int w_Joystick_getHat(lua_State *L); +int w_Joystick_isDown(lua_State *L); +int w_Joystick_isGamepad(lua_State *L); +int w_Joystick_getGamepadAxis(lua_State *L); +int w_Joystick_isGamepadDown(lua_State *L); +int w_Joystick_isVibrationSupported(lua_State *L); +int w_Joystick_setVibration(lua_State *L); +int w_Joystick_getVibration(lua_State *L); +extern "C" int luaopen_joystick(lua_State *L); } // sdl } // joystick diff --git a/src/modules/joystick/sdl/wrap_JoystickModule.cpp b/src/modules/joystick/sdl/wrap_JoystickModule.cpp new file mode 100644 index 000000000..a069e0156 --- /dev/null +++ b/src/modules/joystick/sdl/wrap_JoystickModule.cpp @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "wrap_JoystickModule.h" +#include "wrap_Joystick.h" + +namespace love +{ +namespace joystick +{ +namespace sdl +{ + +static JoystickModule *instance = 0; + +int w_getJoysticks(lua_State *L) +{ + int stickcount = instance->getJoystickCount(); + lua_createtable(L, stickcount, 0); + + for (int i = 0; i < stickcount; i++) + { + love::joystick::Joystick *stick = instance->getJoystick(i); + stick->retain(); + luax_pushtype(L, "Joystick", JOYSTICK_JOYSTICK_T, stick); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int w_getIndex(lua_State *L) +{ + love::joystick::Joystick *j = luax_checkjoystick(L, 1); + int index = instance->getIndex(j); + if (index >= 0) + lua_pushinteger(L, index + 1); + else + lua_pushnil(L); + return 1; +} + +int w_getJoystickCount(lua_State *L) +{ + lua_pushinteger(L, instance->getJoystickCount()); + return 1; +} + +int w_setGamepadMapping(lua_State *L) +{ + // Only accept a GUID string. We don't accept a Joystick object because + // the gamepad mapping applies to all joysticks with the same GUID (e.g. all + // Xbox 360 controllers on the system), rather than individual objects. + const char *guid = luaL_checkstring(L, 1); + + const char *gpbindstr = luaL_checkstring(L, 2); + Joystick::GamepadInput gpinput; + + if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis)) + gpinput.type = Joystick::INPUT_TYPE_AXIS; + else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button)) + gpinput.type = Joystick::INPUT_TYPE_BUTTON; + else + return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr); + + const char *jinputtypestr = luaL_checkstring(L, 3); + Joystick::JoystickInput jinput; + + if (!love::joystick::Joystick::getConstant(jinputtypestr, jinput.type)) + return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr); + + const char *hatstr; + switch (jinput.type) + { + case Joystick::INPUT_TYPE_AXIS: + jinput.axis = luaL_checkint(L, 4) - 1; + break; + case Joystick::INPUT_TYPE_BUTTON: + jinput.button = luaL_checkint(L, 4) - 1; + break; + case Joystick::INPUT_TYPE_HAT: + // Hats need both a hat index and a hat value. + jinput.hat.index = luaL_checkint(L, 4) - 1; + hatstr = luaL_checkstring(L, 5); + if (!love::joystick::Joystick::getConstant(hatstr, jinput.hat.value)) + return luaL_error(L, "Invalid joystick hat: %s", hatstr); + break; + default: + return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr); + } + + bool success = false; + EXCEPT_GUARD(success = instance->setGamepadMapping(guid, gpinput, jinput);) + + luax_pushboolean(L, success); + return 1; +} + +int w_getGamepadMapping(lua_State *L) +{ + std::string guid; + + // Accept either a GUID string or a Joystick object. This way we can re-use + // the function for Joystick:getGamepadMapping. + if (lua_type(L, 1) == LUA_TSTRING) + guid = luax_checkstring(L, 1); + else + { + love::joystick::Joystick *stick = luax_checkjoystick(L, 1); + guid = stick->getGUID(); + } + + const char *gpbindstr = luaL_checkstring(L, 2); + Joystick::GamepadInput gpinput; + + if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis)) + gpinput.type = Joystick::INPUT_TYPE_AXIS; + else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button)) + gpinput.type = Joystick::INPUT_TYPE_BUTTON; + else + return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr); + + Joystick::JoystickInput jinput; + jinput.type = Joystick::INPUT_TYPE_MAX_ENUM; + + EXCEPT_GUARD(jinput = instance->getGamepadMapping(guid, gpinput);) + + if (jinput.type == Joystick::INPUT_TYPE_MAX_ENUM) + return 0; + + const char *inputtypestr; + if (!love::joystick::Joystick::getConstant(jinput.type, inputtypestr)) + return luaL_error(L, "Unknown joystick input type."); + + lua_pushstring(L, inputtypestr); + + const char *hatstr; + switch (jinput.type) + { + case Joystick::INPUT_TYPE_AXIS: + lua_pushinteger(L, jinput.axis + 1); + return 2; + case Joystick::INPUT_TYPE_BUTTON: + lua_pushinteger(L, jinput.button + 1); + return 2; + case Joystick::INPUT_TYPE_HAT: + lua_pushinteger(L, jinput.hat.index + 1); + if (love::joystick::Joystick::getConstant(jinput.hat.value, hatstr)) + { + lua_pushstring(L, hatstr); + return 3; + } + else + return luaL_error(L, "Unknown joystick hat."); + default: + break; // ? + } + + return 1; +} + +// List of functions to wrap. +static const luaL_Reg functions[] = +{ + { "getJoysticks", w_getJoysticks }, + { "getJoystickCount", w_getJoystickCount }, + { "setGamepadMapping", w_setGamepadMapping }, + { "getGamepadMapping", w_getGamepadMapping }, + { 0, 0 } +}; + +static const lua_CFunction types[] = +{ + luaopen_joystick, + 0, +}; + +extern "C" int luaopen_love_joystick(lua_State *L) +{ + if (instance == 0) + { + EXCEPT_GUARD(instance = new JoystickModule();) + } + else + instance->retain(); + + WrappedModule w; + w.module = instance; + w.name = "joystick"; + w.flags = MODULE_T; + w.functions = functions; + w.types = types; + + return luax_register_module(L, w); +} + +} // sdl +} // joystick +} // love diff --git a/src/modules/joystick/sdl/wrap_JoystickModule.h b/src/modules/joystick/sdl/wrap_JoystickModule.h new file mode 100644 index 000000000..24de3264c --- /dev/null +++ b/src/modules/joystick/sdl/wrap_JoystickModule.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_JOYSTICK_SDL_WRAP_JOYSTICK_MODULE_H +#define LOVE_JOYSTICK_SDL_WRAP_JOYSTICK_MODULE_H + +// LOVE +#include "common/config.h" +#include "common/runtime.h" +#include "JoystickModule.h" + +namespace love +{ +namespace joystick +{ +namespace sdl +{ + +int w_getJoysticks(lua_State *L); +int w_getIndex(lua_State *L); +int w_getJoystickCount(lua_State *L); +int w_setGamepadMapping(lua_State *L); +int w_getGamepadMapping(lua_State *L); +extern "C" LOVE_EXPORT int luaopen_love_joystick(lua_State *L); + +} // sdl +} // joystick +} // love + +#endif // LOVE_JOYSTICK_SDL_WRAP_JOYSTICK_MODULE_H diff --git a/src/modules/keyboard/Keyboard.cpp b/src/modules/keyboard/Keyboard.cpp index f3c8aa4ac..6270c108f 100644 --- a/src/modules/keyboard/Keyboard.cpp +++ b/src/modules/keyboard/Keyboard.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,12 +39,10 @@ bool Keyboard::getConstant(Keyboard::Key in, const char *&out) StringMap::Entry Keyboard::keyEntries[] = { + {"return", Keyboard::KEY_RETURN}, + {"escape", Keyboard::KEY_ESCAPE}, {"backspace", Keyboard::KEY_BACKSPACE}, {"tab", Keyboard::KEY_TAB}, - {"clear", Keyboard::KEY_CLEAR}, - {"return", Keyboard::KEY_RETURN}, - {"pause", Keyboard::KEY_PAUSE}, - {"escape", Keyboard::KEY_ESCAPE}, {" ", Keyboard::KEY_SPACE}, {"!", Keyboard::KEY_EXCLAIM}, {"\"", Keyboard::KEY_QUOTEDBL}, @@ -110,35 +108,8 @@ StringMap::Entry Keyboard::keyEntries[] = {"x", Keyboard::KEY_X}, {"y", Keyboard::KEY_Y}, {"z", Keyboard::KEY_Z}, - {"delete", Keyboard::KEY_DELETE}, - {"kp0", Keyboard::KEY_KP0}, - {"kp1", Keyboard::KEY_KP1}, - {"kp2", Keyboard::KEY_KP2}, - {"kp3", Keyboard::KEY_KP3}, - {"kp4", Keyboard::KEY_KP4}, - {"kp5", Keyboard::KEY_KP5}, - {"kp6", Keyboard::KEY_KP6}, - {"kp7", Keyboard::KEY_KP7}, - {"kp8", Keyboard::KEY_KP8}, - {"kp9", Keyboard::KEY_KP9}, - {"kp.", Keyboard::KEY_KP_PERIOD}, - {"kp/", Keyboard::KEY_KP_DIVIDE}, - {"kp*", Keyboard::KEY_KP_MULTIPLY}, - {"kp-", Keyboard::KEY_KP_MINUS}, - {"kp+", Keyboard::KEY_KP_PLUS}, - {"kpenter", Keyboard::KEY_KP_ENTER}, - {"kp=", Keyboard::KEY_KP_EQUALS}, - - {"up", Keyboard::KEY_UP}, - {"down", Keyboard::KEY_DOWN}, - {"right", Keyboard::KEY_RIGHT}, - {"left", Keyboard::KEY_LEFT}, - {"insert", Keyboard::KEY_INSERT}, - {"home", Keyboard::KEY_HOME}, - {"end", Keyboard::KEY_END}, - {"pageup", Keyboard::KEY_PAGEUP}, - {"pagedown", Keyboard::KEY_PAGEDOWN}, + {"capslock", Keyboard::KEY_CAPSLOCK}, {"f1", Keyboard::KEY_F1}, {"f2", Keyboard::KEY_F2}, @@ -152,34 +123,112 @@ StringMap::Entry Keyboard::keyEntries[] = {"f10", Keyboard::KEY_F10}, {"f11", Keyboard::KEY_F11}, {"f12", Keyboard::KEY_F12}, + + {"printscreen", Keyboard::KEY_PRINTSCREEN}, + {"scrolllock", Keyboard::KEY_SCROLLLOCK}, + {"pause", Keyboard::KEY_PAUSE}, + {"insert", Keyboard::KEY_INSERT}, + {"home", Keyboard::KEY_HOME}, + {"pageup", Keyboard::KEY_PAGEUP}, + {"delete", Keyboard::KEY_DELETE}, + {"end", Keyboard::KEY_END}, + {"pagedown", Keyboard::KEY_PAGEDOWN}, + {"right", Keyboard::KEY_RIGHT}, + {"left", Keyboard::KEY_LEFT}, + {"down", Keyboard::KEY_DOWN}, + {"up", Keyboard::KEY_UP}, + + {"numlock", Keyboard::KEY_NUMLOCKCLEAR}, + {"kp/", Keyboard::KEY_KP_DIVIDE}, + {"kp*", Keyboard::KEY_KP_MULTIPLY}, + {"kp-", Keyboard::KEY_KP_MINUS}, + {"kp+", Keyboard::KEY_KP_PLUS}, + {"kpenter", Keyboard::KEY_KP_ENTER}, + {"kp0", Keyboard::KEY_KP_0}, + {"kp1", Keyboard::KEY_KP_1}, + {"kp2", Keyboard::KEY_KP_2}, + {"kp3", Keyboard::KEY_KP_3}, + {"kp4", Keyboard::KEY_KP_4}, + {"kp5", Keyboard::KEY_KP_5}, + {"kp6", Keyboard::KEY_KP_6}, + {"kp7", Keyboard::KEY_KP_7}, + {"kp8", Keyboard::KEY_KP_8}, + {"kp9", Keyboard::KEY_KP_9}, + {"kp.", Keyboard::KEY_KP_PERIOD}, + {"kp,", Keyboard::KEY_KP_COMMA}, + {"kp=", Keyboard::KEY_KP_EQUALS}, + + {"application", Keyboard::KEY_APPLICATION}, + {"power", Keyboard::KEY_POWER}, {"f13", Keyboard::KEY_F13}, {"f14", Keyboard::KEY_F14}, {"f15", Keyboard::KEY_F15}, - - {"numlock", Keyboard::KEY_NUMLOCK}, - {"capslock", Keyboard::KEY_CAPSLOCK}, - {"scrollock", Keyboard::KEY_SCROLLOCK}, - {"rshift", Keyboard::KEY_RSHIFT}, - {"lshift", Keyboard::KEY_LSHIFT}, - {"rctrl", Keyboard::KEY_RCTRL}, - {"lctrl", Keyboard::KEY_LCTRL}, - {"ralt", Keyboard::KEY_RALT}, - {"lalt", Keyboard::KEY_LALT}, - {"rmeta", Keyboard::KEY_RMETA}, - {"lmeta", Keyboard::KEY_LMETA}, - {"lsuper", Keyboard::KEY_LSUPER}, - {"rsuper", Keyboard::KEY_RSUPER}, - {"mode", Keyboard::KEY_MODE}, - {"compose", Keyboard::KEY_COMPOSE}, - + {"f16", Keyboard::KEY_F16}, + {"f17", Keyboard::KEY_F17}, + {"f18", Keyboard::KEY_F18}, + {"f19", Keyboard::KEY_F19}, + {"f20", Keyboard::KEY_F20}, + {"f21", Keyboard::KEY_F21}, + {"f22", Keyboard::KEY_F22}, + {"f23", Keyboard::KEY_F23}, + {"f24", Keyboard::KEY_F24}, + {"execute", Keyboard::KEY_EXECUTE}, {"help", Keyboard::KEY_HELP}, - {"print", Keyboard::KEY_PRINT}, - {"sysreq", Keyboard::KEY_SYSREQ}, - {"break", Keyboard::KEY_BREAK}, {"menu", Keyboard::KEY_MENU}, - {"power", Keyboard::KEY_POWER}, - {"euro", Keyboard::KEY_EURO}, + {"select", Keyboard::KEY_SELECT}, + {"stop", Keyboard::KEY_STOP}, + {"again", Keyboard::KEY_AGAIN}, {"undo", Keyboard::KEY_UNDO}, + {"cut", Keyboard::KEY_CUT}, + {"copy", Keyboard::KEY_COPY}, + {"paste", Keyboard::KEY_PASTE}, + {"find", Keyboard::KEY_FIND}, + {"mute", Keyboard::KEY_MUTE}, + {"volumeup", Keyboard::KEY_VOLUMEUP}, + {"volumedown", Keyboard::KEY_VOLUMEDOWN}, + + {"alterase", Keyboard::KEY_ALTERASE}, + {"sysreq", Keyboard::KEY_SYSREQ}, + {"cancel", Keyboard::KEY_CANCEL}, + {"clear", Keyboard::KEY_CLEAR}, + {"prior", Keyboard::KEY_PRIOR}, + {"return2", Keyboard::KEY_RETURN2}, + {"separator", Keyboard::KEY_SEPARATOR}, + {"out", Keyboard::KEY_OUT}, + {"oper", Keyboard::KEY_OPER}, + {"clearagain", Keyboard::KEY_CLEARAGAIN}, + + {"thsousandsseparator", Keyboard::KEY_THOUSANDSSEPARATOR}, + {"decimalseparator", Keyboard::KEY_DECIMALSEPARATOR}, + {"currencyunit", Keyboard::KEY_CURRENCYUNIT}, + {"currencysubunit", Keyboard::KEY_CURRENCYSUBUNIT}, + + {"lctrl", Keyboard::KEY_LCTRL}, + {"lshift", Keyboard::KEY_LSHIFT}, + {"lalt", Keyboard::KEY_LALT}, + {"lgui", Keyboard::KEY_LGUI}, + {"rctrl", Keyboard::KEY_RCTRL}, + {"rshift", Keyboard::KEY_RSHIFT}, + {"ralt", Keyboard::KEY_RALT}, + {"rgui", Keyboard::KEY_RGUI}, + + {"mode", Keyboard::KEY_MODE}, + + {"audionext", Keyboard::KEY_AUDIONEXT}, + {"audioprev", Keyboard::KEY_AUDIOPREV}, + {"audiostop", Keyboard::KEY_AUDIOSTOP}, + {"audioplay", Keyboard::KEY_AUDIOPLAY}, + {"audiomute", Keyboard::KEY_AUDIOMUTE}, + {"mediaselect", Keyboard::KEY_MEDIASELECT}, + + {"brightnessdown", Keyboard::KEY_BRIGHTNESSDOWN}, + {"brightnessup", Keyboard::KEY_BRIGHTNESSUP}, + {"displayswitch", Keyboard::KEY_DISPLAYSWITCH}, + {"kbdillumtoggle", Keyboard::KEY_KBDILLUMTOGGLE}, + {"kbdillumdown", Keyboard::KEY_KBDILLUMDOWN}, + {"kbdillumup", Keyboard::KEY_KBDILLUMUP}, + {"eject", Keyboard::KEY_EJECT}, + {"sleep", Keyboard::KEY_SLEEP}, }; StringMap Keyboard::keys(Keyboard::keyEntries, sizeof(Keyboard::keyEntries)); diff --git a/src/modules/keyboard/Keyboard.h b/src/modules/keyboard/Keyboard.h index a4e53def2..5e2e325a0 100644 --- a/src/modules/keyboard/Keyboard.h +++ b/src/modules/keyboard/Keyboard.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -37,16 +37,16 @@ public: enum Key { KEY_UNKNOWN, + + KEY_RETURN, + KEY_ESCAPE, KEY_BACKSPACE, KEY_TAB, - KEY_CLEAR, - KEY_RETURN, - KEY_PAUSE, - KEY_ESCAPE, KEY_SPACE, KEY_EXCLAIM, KEY_QUOTEDBL, KEY_HASH, + KEY_PERCENT, KEY_DOLLAR, KEY_AMPERSAND, KEY_QUOTE, @@ -108,35 +108,8 @@ public: KEY_X, KEY_Y, KEY_Z, - KEY_DELETE, - KEY_KP0, - KEY_KP1, - KEY_KP2, - KEY_KP3, - KEY_KP4, - KEY_KP5, - KEY_KP6, - KEY_KP7, - KEY_KP8, - KEY_KP9, - KEY_KP_PERIOD, - KEY_KP_DIVIDE, - KEY_KP_MULTIPLY, - KEY_KP_MINUS, - KEY_KP_PLUS, - KEY_KP_ENTER, - KEY_KP_EQUALS, - - KEY_UP, - KEY_DOWN, - KEY_RIGHT, - KEY_LEFT, - KEY_INSERT, - KEY_HOME, - KEY_END, - KEY_PAGEUP, - KEY_PAGEDOWN, + KEY_CAPSLOCK, KEY_F1, KEY_F2, @@ -150,66 +123,147 @@ public: KEY_F10, KEY_F11, KEY_F12, + + KEY_PRINTSCREEN, + KEY_SCROLLLOCK, + KEY_PAUSE, + KEY_INSERT, + KEY_HOME, + KEY_PAGEUP, + KEY_DELETE, + KEY_END, + KEY_PAGEDOWN, + KEY_RIGHT, + KEY_LEFT, + KEY_DOWN, + KEY_UP, + + KEY_NUMLOCKCLEAR, + KEY_KP_DIVIDE, + KEY_KP_MULTIPLY, + KEY_KP_MINUS, + KEY_KP_PLUS, + KEY_KP_ENTER, + KEY_KP_1, + KEY_KP_2, + KEY_KP_3, + KEY_KP_4, + KEY_KP_5, + KEY_KP_6, + KEY_KP_7, + KEY_KP_8, + KEY_KP_9, + KEY_KP_0, + KEY_KP_PERIOD, + KEY_KP_COMMA, + KEY_KP_EQUALS, + + KEY_APPLICATION, + KEY_POWER, KEY_F13, KEY_F14, KEY_F15, - - KEY_NUMLOCK, - KEY_CAPSLOCK, - KEY_SCROLLOCK, - KEY_RSHIFT, - KEY_LSHIFT, - KEY_RCTRL, - KEY_LCTRL, - KEY_RALT, - KEY_LALT, - KEY_RMETA, - KEY_LMETA, - KEY_LSUPER, - KEY_RSUPER, - KEY_MODE, - KEY_COMPOSE, - + KEY_F16, + KEY_F17, + KEY_F18, + KEY_F19, + KEY_F20, + KEY_F21, + KEY_F22, + KEY_F23, + KEY_F24, + KEY_EXECUTE, KEY_HELP, - KEY_PRINT, - KEY_SYSREQ, - KEY_BREAK, KEY_MENU, - KEY_POWER, - KEY_EURO, + KEY_SELECT, + KEY_STOP, + KEY_AGAIN, KEY_UNDO, + KEY_CUT, + KEY_COPY, + KEY_PASTE, + KEY_FIND, + KEY_MUTE, + KEY_VOLUMEUP, + KEY_VOLUMEDOWN, + + KEY_ALTERASE, + KEY_SYSREQ, + KEY_CANCEL, + KEY_CLEAR, + KEY_PRIOR, + KEY_RETURN2, + KEY_SEPARATOR, + KEY_OUT, + KEY_OPER, + KEY_CLEARAGAIN, + + KEY_THOUSANDSSEPARATOR, + KEY_DECIMALSEPARATOR, + KEY_CURRENCYUNIT, + KEY_CURRENCYSUBUNIT, + + KEY_LCTRL, + KEY_LSHIFT, + KEY_LALT, + KEY_LGUI, + KEY_RCTRL, + KEY_RSHIFT, + KEY_RALT, + KEY_RGUI, + + KEY_MODE, + + KEY_AUDIONEXT, + KEY_AUDIOPREV, + KEY_AUDIOSTOP, + KEY_AUDIOPLAY, + KEY_AUDIOMUTE, + KEY_MEDIASELECT, + + KEY_BRIGHTNESSDOWN, + KEY_BRIGHTNESSUP, + KEY_DISPLAYSWITCH, + KEY_KBDILLUMTOGGLE, + KEY_KBDILLUMDOWN, + KEY_KBDILLUMUP, + KEY_EJECT, + KEY_SLEEP, + KEY_MAX_ENUM = 512 }; - static const int DEFAULT = -1; - virtual ~Keyboard() {} /** - * Checks whether a certain key is down or not. - * @param key A key identifier. + * Sets whether repeat keypress events should be sent if a key is held down. + * Does not affect text input events. + * @param enable Whether to send repeat key press events. + **/ + virtual void setKeyRepeat(bool enable) = 0; + + /** + * Gets whether repeat keypress events will be sent if a key is held down. + **/ + virtual bool hasKeyRepeat() const = 0; + + /** + * Checks whether certain keys are down or not. + * @param keylist An array of key identifiers, terminated by KEY_MAX_ENUM. * @return boolean **/ virtual bool isDown(Key *keylist) const = 0; /** - * Enables key repeating. - * @param delay The amount of delay before repeating the key (in milliseconds) - * @param interval Specifies the amount of time between repeats (in milliseconds) + * Sets whether text input events should be sent + * @param enable Whether to send text input events. **/ - virtual void setKeyRepeat(int delay, int interval) const = 0; + virtual void setTextInput(bool enable) = 0; /** - * Gets the specified delay for the key repeat. - * @return int + * Gets whether text input events are enabled. **/ - virtual int getKeyRepeatDelay() const = 0; - - /** - * Gets the specified interval for the key repeat. - * @return int - **/ - virtual int getKeyRepeatInterval() const = 0; + virtual bool hasTextInput() const = 0; static bool getConstant(const char *in, Key &out); static bool getConstant(Key in, const char *&out); diff --git a/src/modules/keyboard/sdl/Keyboard.cpp b/src/modules/keyboard/sdl/Keyboard.cpp index 551df5247..4c70ea94a 100644 --- a/src/modules/keyboard/sdl/Keyboard.cpp +++ b/src/modules/keyboard/sdl/Keyboard.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,194 +29,255 @@ namespace keyboard namespace sdl { +Keyboard::Keyboard() + : key_repeat(false) +{ +} + const char *Keyboard::getName() const { return "love.keyboard.sdl"; } +void Keyboard::setKeyRepeat(bool enable) +{ + key_repeat = enable; +} + +bool Keyboard::hasKeyRepeat() const +{ + return key_repeat; +} + bool Keyboard::isDown(Key *keylist) const { - SDLKey k; - Uint8 *keystate = SDL_GetKeyState(0); + const Uint8 *keystate = SDL_GetKeyboardState(0); + std::map::const_iterator it; for (Key key = *keylist; key != KEY_MAX_ENUM; key = *(++keylist)) { - if (keys.find(key, k) && keystate[(unsigned)k] == 1) + it = keys.find(key); + if (it != keys.end() && keystate[SDL_GetScancodeFromKey(it->second)]) return true; } return false; } -void Keyboard::setKeyRepeat(int delay, int interval) const +void Keyboard::setTextInput(bool enable) { - delay = (delay == DEFAULT) ? SDL_DEFAULT_REPEAT_DELAY : delay; - interval = (interval == DEFAULT) ? SDL_DEFAULT_REPEAT_INTERVAL : interval; - - SDL_EnableKeyRepeat(delay, interval); + if (enable) + SDL_StartTextInput(); + else + SDL_StopTextInput(); } -int Keyboard::getKeyRepeatDelay() const +bool Keyboard::hasTextInput() const { - int delay, interval; - SDL_GetKeyRepeat(&delay, &interval); - return delay; + return SDL_IsTextInputActive(); } -int Keyboard::getKeyRepeatInterval() const +std::map Keyboard::createKeyMap() { - int delay, interval; - SDL_GetKeyRepeat(&delay, &interval); - return interval; + std::map k; + + k[Keyboard::KEY_UNKNOWN] = SDLK_UNKNOWN; + + k[Keyboard::KEY_RETURN] = SDLK_RETURN; + k[Keyboard::KEY_ESCAPE] = SDLK_ESCAPE; + k[Keyboard::KEY_BACKSPACE] = SDLK_BACKSPACE; + k[Keyboard::KEY_TAB] = SDLK_TAB; + k[Keyboard::KEY_SPACE] = SDLK_SPACE; + k[Keyboard::KEY_EXCLAIM] = SDLK_EXCLAIM; + k[Keyboard::KEY_QUOTEDBL] = SDLK_QUOTEDBL; + k[Keyboard::KEY_HASH] = SDLK_HASH; + k[Keyboard::KEY_DOLLAR] = SDLK_DOLLAR; + k[Keyboard::KEY_AMPERSAND] = SDLK_AMPERSAND; + k[Keyboard::KEY_QUOTE] = SDLK_QUOTE; + k[Keyboard::KEY_LEFTPAREN] = SDLK_LEFTPAREN; + k[Keyboard::KEY_RIGHTPAREN] = SDLK_RIGHTPAREN; + k[Keyboard::KEY_ASTERISK] = SDLK_ASTERISK; + k[Keyboard::KEY_PLUS] = SDLK_PLUS; + k[Keyboard::KEY_COMMA] = SDLK_COMMA; + k[Keyboard::KEY_MINUS] = SDLK_MINUS; + k[Keyboard::KEY_PERIOD] = SDLK_PERIOD; + k[Keyboard::KEY_SLASH] = SDLK_SLASH; + k[Keyboard::KEY_0] = SDLK_0; + k[Keyboard::KEY_1] = SDLK_1; + k[Keyboard::KEY_2] = SDLK_2; + k[Keyboard::KEY_3] = SDLK_3; + k[Keyboard::KEY_4] = SDLK_4; + k[Keyboard::KEY_5] = SDLK_5; + k[Keyboard::KEY_6] = SDLK_6; + k[Keyboard::KEY_7] = SDLK_7; + k[Keyboard::KEY_8] = SDLK_8; + k[Keyboard::KEY_9] = SDLK_9; + k[Keyboard::KEY_COLON] = SDLK_COLON; + k[Keyboard::KEY_SEMICOLON] = SDLK_SEMICOLON; + k[Keyboard::KEY_LESS] = SDLK_LESS; + k[Keyboard::KEY_EQUALS] = SDLK_EQUALS; + k[Keyboard::KEY_GREATER] = SDLK_GREATER; + k[Keyboard::KEY_QUESTION] = SDLK_QUESTION; + k[Keyboard::KEY_AT] = SDLK_AT; + + k[Keyboard::KEY_LEFTBRACKET] = SDLK_LEFTBRACKET; + k[Keyboard::KEY_BACKSLASH] = SDLK_BACKSLASH; + k[Keyboard::KEY_RIGHTBRACKET] = SDLK_RIGHTBRACKET; + k[Keyboard::KEY_CARET] = SDLK_CARET; + k[Keyboard::KEY_UNDERSCORE] = SDLK_UNDERSCORE; + k[Keyboard::KEY_BACKQUOTE] = SDLK_BACKQUOTE; + k[Keyboard::KEY_A] = SDLK_a; + k[Keyboard::KEY_B] = SDLK_b; + k[Keyboard::KEY_C] = SDLK_c; + k[Keyboard::KEY_D] = SDLK_d; + k[Keyboard::KEY_E] = SDLK_e; + k[Keyboard::KEY_F] = SDLK_f; + k[Keyboard::KEY_G] = SDLK_g; + k[Keyboard::KEY_H] = SDLK_h; + k[Keyboard::KEY_I] = SDLK_i; + k[Keyboard::KEY_J] = SDLK_j; + k[Keyboard::KEY_K] = SDLK_k; + k[Keyboard::KEY_L] = SDLK_l; + k[Keyboard::KEY_M] = SDLK_m; + k[Keyboard::KEY_N] = SDLK_n; + k[Keyboard::KEY_O] = SDLK_o; + k[Keyboard::KEY_P] = SDLK_p; + k[Keyboard::KEY_Q] = SDLK_q; + k[Keyboard::KEY_R] = SDLK_r; + k[Keyboard::KEY_S] = SDLK_s; + k[Keyboard::KEY_T] = SDLK_t; + k[Keyboard::KEY_U] = SDLK_u; + k[Keyboard::KEY_V] = SDLK_v; + k[Keyboard::KEY_W] = SDLK_w; + k[Keyboard::KEY_X] = SDLK_x; + k[Keyboard::KEY_Y] = SDLK_y; + k[Keyboard::KEY_Z] = SDLK_z; + + k[Keyboard::KEY_CAPSLOCK] = SDLK_CAPSLOCK; + + k[Keyboard::KEY_F1] = SDLK_F1; + k[Keyboard::KEY_F2] = SDLK_F2; + k[Keyboard::KEY_F3] = SDLK_F3; + k[Keyboard::KEY_F4] = SDLK_F4; + k[Keyboard::KEY_F5] = SDLK_F5; + k[Keyboard::KEY_F6] = SDLK_F6; + k[Keyboard::KEY_F7] = SDLK_F7; + k[Keyboard::KEY_F8] = SDLK_F8; + k[Keyboard::KEY_F9] = SDLK_F9; + k[Keyboard::KEY_F10] = SDLK_F10; + k[Keyboard::KEY_F11] = SDLK_F11; + k[Keyboard::KEY_F12] = SDLK_F12; + + k[Keyboard::KEY_PRINTSCREEN] = SDLK_PRINTSCREEN; + k[Keyboard::KEY_SCROLLLOCK] = SDLK_SCROLLLOCK; + k[Keyboard::KEY_PAUSE] = SDLK_PAUSE; + k[Keyboard::KEY_INSERT] = SDLK_INSERT; + k[Keyboard::KEY_HOME] = SDLK_HOME; + k[Keyboard::KEY_PAGEUP] = SDLK_PAGEUP; + k[Keyboard::KEY_DELETE] = SDLK_DELETE; + k[Keyboard::KEY_END] = SDLK_END; + k[Keyboard::KEY_PAGEDOWN] = SDLK_PAGEDOWN; + k[Keyboard::KEY_RIGHT] = SDLK_RIGHT; + k[Keyboard::KEY_LEFT] = SDLK_LEFT; + k[Keyboard::KEY_DOWN] = SDLK_DOWN; + k[Keyboard::KEY_UP] = SDLK_UP; + + k[Keyboard::KEY_NUMLOCKCLEAR] = SDLK_NUMLOCKCLEAR; + k[Keyboard::KEY_KP_DIVIDE] = SDLK_KP_DIVIDE; + k[Keyboard::KEY_KP_MULTIPLY] = SDLK_KP_MULTIPLY; + k[Keyboard::KEY_KP_MINUS] = SDLK_KP_MINUS; + k[Keyboard::KEY_KP_PLUS] = SDLK_KP_PLUS; + k[Keyboard::KEY_KP_ENTER] = SDLK_KP_ENTER; + k[Keyboard::KEY_KP_0] = SDLK_KP_0; + k[Keyboard::KEY_KP_1] = SDLK_KP_1; + k[Keyboard::KEY_KP_2] = SDLK_KP_2; + k[Keyboard::KEY_KP_3] = SDLK_KP_3; + k[Keyboard::KEY_KP_4] = SDLK_KP_4; + k[Keyboard::KEY_KP_5] = SDLK_KP_5; + k[Keyboard::KEY_KP_6] = SDLK_KP_6; + k[Keyboard::KEY_KP_7] = SDLK_KP_7; + k[Keyboard::KEY_KP_8] = SDLK_KP_8; + k[Keyboard::KEY_KP_9] = SDLK_KP_9; + k[Keyboard::KEY_KP_PERIOD] = SDLK_KP_PERIOD; + k[Keyboard::KEY_KP_COMMA] = SDLK_KP_COMMA; + k[Keyboard::KEY_KP_EQUALS] = SDLK_KP_EQUALS; + + k[Keyboard::KEY_APPLICATION] = SDLK_APPLICATION; + k[Keyboard::KEY_POWER] = SDLK_POWER; + k[Keyboard::KEY_F13] = SDLK_F13; + k[Keyboard::KEY_F14] = SDLK_F14; + k[Keyboard::KEY_F15] = SDLK_F15; + k[Keyboard::KEY_F16] = SDLK_F16; + k[Keyboard::KEY_F17] = SDLK_F17; + k[Keyboard::KEY_F18] = SDLK_F18; + k[Keyboard::KEY_F19] = SDLK_F19; + k[Keyboard::KEY_F20] = SDLK_F20; + k[Keyboard::KEY_F21] = SDLK_F21; + k[Keyboard::KEY_F22] = SDLK_F22; + k[Keyboard::KEY_F23] = SDLK_F23; + k[Keyboard::KEY_F24] = SDLK_F24; + k[Keyboard::KEY_EXECUTE] = SDLK_EXECUTE; + k[Keyboard::KEY_HELP] = SDLK_HELP; + k[Keyboard::KEY_MENU] = SDLK_MENU; + k[Keyboard::KEY_SELECT] = SDLK_SELECT; + k[Keyboard::KEY_STOP] = SDLK_STOP; + k[Keyboard::KEY_AGAIN] = SDLK_AGAIN; + k[Keyboard::KEY_UNDO] = SDLK_UNDO; + k[Keyboard::KEY_CUT] = SDLK_CUT; + k[Keyboard::KEY_COPY] = SDLK_COPY; + k[Keyboard::KEY_PASTE] = SDLK_PASTE; + k[Keyboard::KEY_FIND] = SDLK_FIND; + k[Keyboard::KEY_MUTE] = SDLK_MUTE; + k[Keyboard::KEY_VOLUMEUP] = SDLK_VOLUMEUP; + k[Keyboard::KEY_VOLUMEDOWN] = SDLK_VOLUMEDOWN; + + k[Keyboard::KEY_ALTERASE] = SDLK_ALTERASE; + k[Keyboard::KEY_SYSREQ] = SDLK_SYSREQ; + k[Keyboard::KEY_CANCEL] = SDLK_CANCEL; + k[Keyboard::KEY_CLEAR] = SDLK_CLEAR; + k[Keyboard::KEY_PRIOR] = SDLK_PRIOR; + k[Keyboard::KEY_RETURN2] = SDLK_RETURN2; + k[Keyboard::KEY_SEPARATOR] = SDLK_SEPARATOR; + k[Keyboard::KEY_OUT] = SDLK_OUT; + k[Keyboard::KEY_OPER] = SDLK_OPER; + k[Keyboard::KEY_CLEARAGAIN] = SDLK_CLEARAGAIN; + + k[Keyboard::KEY_THOUSANDSSEPARATOR] = SDLK_THOUSANDSSEPARATOR; + k[Keyboard::KEY_DECIMALSEPARATOR] = SDLK_DECIMALSEPARATOR; + k[Keyboard::KEY_CURRENCYUNIT] = SDLK_CURRENCYUNIT; + k[Keyboard::KEY_CURRENCYSUBUNIT] = SDLK_CURRENCYSUBUNIT; + + k[Keyboard::KEY_LCTRL] = SDLK_LCTRL; + k[Keyboard::KEY_LSHIFT] = SDLK_LSHIFT; + k[Keyboard::KEY_LALT] = SDLK_LALT; + k[Keyboard::KEY_LGUI] = SDLK_LGUI; + k[Keyboard::KEY_RCTRL] = SDLK_RCTRL; + k[Keyboard::KEY_RSHIFT] = SDLK_RSHIFT; + k[Keyboard::KEY_RALT] = SDLK_RALT; + k[Keyboard::KEY_RGUI] = SDLK_RGUI; + + k[Keyboard::KEY_MODE] = SDLK_MODE; + + k[Keyboard::KEY_AUDIONEXT] = SDLK_AUDIONEXT; + k[Keyboard::KEY_AUDIOPREV] = SDLK_AUDIOPREV; + k[Keyboard::KEY_AUDIOSTOP] = SDLK_AUDIOSTOP; + k[Keyboard::KEY_AUDIOPLAY] = SDLK_AUDIOPLAY; + k[Keyboard::KEY_AUDIOMUTE] = SDLK_AUDIOMUTE; + k[Keyboard::KEY_MEDIASELECT] = SDLK_MEDIASELECT; + + k[Keyboard::KEY_BRIGHTNESSDOWN] = SDLK_BRIGHTNESSDOWN; + k[Keyboard::KEY_BRIGHTNESSUP] = SDLK_BRIGHTNESSUP; + k[Keyboard::KEY_DISPLAYSWITCH] = SDLK_DISPLAYSWITCH; + k[Keyboard::KEY_KBDILLUMTOGGLE] = SDLK_KBDILLUMTOGGLE; + k[Keyboard::KEY_KBDILLUMDOWN] = SDLK_KBDILLUMDOWN; + k[Keyboard::KEY_KBDILLUMUP] = SDLK_KBDILLUMUP; + k[Keyboard::KEY_EJECT] = SDLK_EJECT; + k[Keyboard::KEY_SLEEP] = SDLK_SLEEP; + + return k; } -EnumMap::Entry Keyboard::keyEntries[] = -{ - { Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE}, - { Keyboard::KEY_TAB, SDLK_TAB}, - { Keyboard::KEY_CLEAR, SDLK_CLEAR}, - { Keyboard::KEY_RETURN, SDLK_RETURN}, - { Keyboard::KEY_PAUSE, SDLK_PAUSE}, - { Keyboard::KEY_ESCAPE, SDLK_ESCAPE }, - { Keyboard::KEY_SPACE, SDLK_SPACE }, - { Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM }, - { Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL }, - { Keyboard::KEY_HASH, SDLK_HASH }, - { Keyboard::KEY_DOLLAR, SDLK_DOLLAR }, - { Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND }, - { Keyboard::KEY_QUOTE, SDLK_QUOTE }, - { Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN }, - { Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN }, - { Keyboard::KEY_ASTERISK, SDLK_ASTERISK }, - { Keyboard::KEY_PLUS, SDLK_PLUS }, - { Keyboard::KEY_COMMA, SDLK_COMMA }, - { Keyboard::KEY_MINUS, SDLK_MINUS }, - { Keyboard::KEY_PERIOD, SDLK_PERIOD }, - { Keyboard::KEY_SLASH, SDLK_SLASH }, - { Keyboard::KEY_0, SDLK_0 }, - { Keyboard::KEY_1, SDLK_1 }, - { Keyboard::KEY_2, SDLK_2 }, - { Keyboard::KEY_3, SDLK_3 }, - { Keyboard::KEY_4, SDLK_4 }, - { Keyboard::KEY_5, SDLK_5 }, - { Keyboard::KEY_6, SDLK_6 }, - { Keyboard::KEY_7, SDLK_7 }, - { Keyboard::KEY_8, SDLK_8 }, - { Keyboard::KEY_9, SDLK_9 }, - { Keyboard::KEY_COLON, SDLK_COLON }, - { Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON }, - { Keyboard::KEY_LESS, SDLK_LESS }, - { Keyboard::KEY_EQUALS, SDLK_EQUALS }, - { Keyboard::KEY_GREATER, SDLK_GREATER }, - { Keyboard::KEY_QUESTION, SDLK_QUESTION }, - { Keyboard::KEY_AT, SDLK_AT }, - - { Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET }, - { Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH }, - { Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET }, - { Keyboard::KEY_CARET, SDLK_CARET }, - { Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE }, - { Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE }, - { Keyboard::KEY_A, SDLK_a }, - { Keyboard::KEY_B, SDLK_b }, - { Keyboard::KEY_C, SDLK_c }, - { Keyboard::KEY_D, SDLK_d }, - { Keyboard::KEY_E, SDLK_e }, - { Keyboard::KEY_F, SDLK_f }, - { Keyboard::KEY_G, SDLK_g }, - { Keyboard::KEY_H, SDLK_h }, - { Keyboard::KEY_I, SDLK_i }, - { Keyboard::KEY_J, SDLK_j }, - { Keyboard::KEY_K, SDLK_k }, - { Keyboard::KEY_L, SDLK_l }, - { Keyboard::KEY_M, SDLK_m }, - { Keyboard::KEY_N, SDLK_n }, - { Keyboard::KEY_O, SDLK_o }, - { Keyboard::KEY_P, SDLK_p }, - { Keyboard::KEY_Q, SDLK_q }, - { Keyboard::KEY_R, SDLK_r }, - { Keyboard::KEY_S, SDLK_s }, - { Keyboard::KEY_T, SDLK_t }, - { Keyboard::KEY_U, SDLK_u }, - { Keyboard::KEY_V, SDLK_v }, - { Keyboard::KEY_W, SDLK_w }, - { Keyboard::KEY_X, SDLK_x }, - { Keyboard::KEY_Y, SDLK_y }, - { Keyboard::KEY_Z, SDLK_z }, - { Keyboard::KEY_DELETE, SDLK_DELETE }, - - { Keyboard::KEY_KP0, SDLK_KP0 }, - { Keyboard::KEY_KP1, SDLK_KP1 }, - { Keyboard::KEY_KP2, SDLK_KP2 }, - { Keyboard::KEY_KP3, SDLK_KP3 }, - { Keyboard::KEY_KP4, SDLK_KP4 }, - { Keyboard::KEY_KP5, SDLK_KP5 }, - { Keyboard::KEY_KP6, SDLK_KP6 }, - { Keyboard::KEY_KP7, SDLK_KP7 }, - { Keyboard::KEY_KP8, SDLK_KP8 }, - { Keyboard::KEY_KP9, SDLK_KP9 }, - { Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD }, - { Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE }, - { Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY}, - { Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS }, - { Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS }, - { Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER }, - { Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS }, - - { Keyboard::KEY_UP, SDLK_UP }, - { Keyboard::KEY_DOWN, SDLK_DOWN }, - { Keyboard::KEY_RIGHT, SDLK_RIGHT }, - { Keyboard::KEY_LEFT, SDLK_LEFT }, - { Keyboard::KEY_INSERT, SDLK_INSERT }, - { Keyboard::KEY_HOME, SDLK_HOME }, - { Keyboard::KEY_END, SDLK_END }, - { Keyboard::KEY_PAGEUP, SDLK_PAGEUP }, - { Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN }, - - { Keyboard::KEY_F1, SDLK_F1 }, - { Keyboard::KEY_F2, SDLK_F2 }, - { Keyboard::KEY_F3, SDLK_F3 }, - { Keyboard::KEY_F4, SDLK_F4 }, - { Keyboard::KEY_F5, SDLK_F5 }, - { Keyboard::KEY_F6, SDLK_F6 }, - { Keyboard::KEY_F7, SDLK_F7 }, - { Keyboard::KEY_F8, SDLK_F8 }, - { Keyboard::KEY_F9, SDLK_F9 }, - { Keyboard::KEY_F10, SDLK_F10 }, - { Keyboard::KEY_F11, SDLK_F11 }, - { Keyboard::KEY_F12, SDLK_F12 }, - { Keyboard::KEY_F13, SDLK_F13 }, - { Keyboard::KEY_F14, SDLK_F14 }, - { Keyboard::KEY_F15, SDLK_F15 }, - - { Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK }, - { Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK }, - { Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK }, - { Keyboard::KEY_RSHIFT, SDLK_RSHIFT }, - { Keyboard::KEY_LSHIFT, SDLK_LSHIFT }, - { Keyboard::KEY_RCTRL, SDLK_RCTRL }, - { Keyboard::KEY_LCTRL, SDLK_LCTRL }, - { Keyboard::KEY_RALT, SDLK_RALT }, - { Keyboard::KEY_LALT, SDLK_LALT }, - { Keyboard::KEY_RMETA, SDLK_RMETA }, - { Keyboard::KEY_LMETA, SDLK_LMETA }, - { Keyboard::KEY_LSUPER, SDLK_LSUPER }, - { Keyboard::KEY_RSUPER, SDLK_RSUPER }, - { Keyboard::KEY_MODE, SDLK_MODE }, - { Keyboard::KEY_COMPOSE, SDLK_COMPOSE }, - - { Keyboard::KEY_HELP, SDLK_HELP }, - { Keyboard::KEY_PRINT, SDLK_PRINT }, - { Keyboard::KEY_SYSREQ, SDLK_SYSREQ }, - { Keyboard::KEY_BREAK, SDLK_BREAK }, - { Keyboard::KEY_MENU, SDLK_MENU }, - { Keyboard::KEY_POWER, SDLK_POWER }, - { Keyboard::KEY_EURO, SDLK_EURO }, - { Keyboard::KEY_UNDO, SDLK_UNDO }, -}; - -EnumMap Keyboard::keys(Keyboard::keyEntries, sizeof(Keyboard::keyEntries)); - +std::map Keyboard::keys = Keyboard::createKeyMap(); } // sdl } // keyboard diff --git a/src/modules/keyboard/sdl/Keyboard.h b/src/modules/keyboard/sdl/Keyboard.h index 4033e23dc..56271b801 100644 --- a/src/modules/keyboard/sdl/Keyboard.h +++ b/src/modules/keyboard/sdl/Keyboard.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -28,6 +28,9 @@ // SDL #include +// STL +#include + namespace love { namespace keyboard @@ -39,17 +42,24 @@ class Keyboard : public love::keyboard::Keyboard { public: + Keyboard(); + // Implements Module. const char *getName() const; + + void setKeyRepeat(bool enable); + bool hasKeyRepeat() const; bool isDown(Key *keylist) const; - void setKeyRepeat(int delay, int interval) const; - int getKeyRepeatDelay() const; - int getKeyRepeatInterval() const; + + void setTextInput(bool enable); + bool hasTextInput() const; private: - static EnumMap::Entry keyEntries[]; - static EnumMap keys; + bool key_repeat; + + static std::map createKeyMap(); + static std::map keys; }; // Keyboard diff --git a/src/modules/keyboard/wrap_Keyboard.cpp b/src/modules/keyboard/wrap_Keyboard.cpp index 5c378337a..fc986b940 100644 --- a/src/modules/keyboard/wrap_Keyboard.cpp +++ b/src/modules/keyboard/wrap_Keyboard.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -29,7 +29,19 @@ namespace love namespace keyboard { -static Keyboard *instance; +static Keyboard *instance = 0; + +int w_setKeyRepeat(lua_State *L) +{ + instance->setKeyRepeat(luax_toboolean(L, 1)); + return 0; +} + +int w_hasKeyRepeat(lua_State *L) +{ + luax_pushboolean(L, instance->hasKeyRepeat()); + return 1; +} int w_isDown(lua_State *L) { @@ -50,34 +62,26 @@ int w_isDown(lua_State *L) return 1; } -int w_setKeyRepeat(lua_State *L) +int w_setTextInput(lua_State *L) { - if (lua_gettop(L) == 0) - { - // Disables key repeat. - instance->setKeyRepeat(0, 0); - return 0; - } - - int delay = lua_isnumber(L, 1) ? (int)(lua_tonumber(L, 1) * 1000 + 0.5) : Keyboard::DEFAULT; - int interval = lua_isnumber(L, 2) ? (int)(lua_tonumber(L, 2) * 1000 + 0.5) : Keyboard::DEFAULT; - instance->setKeyRepeat(delay, interval); + instance->setTextInput(luax_toboolean(L, 1)); return 0; } -int w_getKeyRepeat(lua_State *L) +int w_hasTextInput(lua_State *L) { - lua_pushnumber(L, (lua_Number) instance->getKeyRepeatDelay() * 0.001); - lua_pushnumber(L, (lua_Number) instance->getKeyRepeatInterval() * 0.001); - return 2; + luax_pushboolean(L, instance->hasTextInput()); + return 1; } // List of functions to wrap. static const luaL_Reg functions[] = { - { "isDown", w_isDown }, { "setKeyRepeat", w_setKeyRepeat }, - { "getKeyRepeat", w_getKeyRepeat }, + { "hasKeyRepeat", w_hasKeyRepeat }, + { "setTextInput", w_setTextInput }, + { "hasTextInput", w_hasTextInput }, + { "isDown", w_isDown }, { 0, 0 } }; @@ -85,14 +89,7 @@ extern "C" int luaopen_love_keyboard(lua_State *L) { if (instance == 0) { - try - { - instance = new love::keyboard::sdl::Keyboard(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new love::keyboard::sdl::Keyboard();) } else instance->retain(); diff --git a/src/modules/keyboard/wrap_Keyboard.h b/src/modules/keyboard/wrap_Keyboard.h index 6fa841b9d..717f241c3 100644 --- a/src/modules/keyboard/wrap_Keyboard.h +++ b/src/modules/keyboard/wrap_Keyboard.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,6 +22,7 @@ #define LOVE_KEYBOARD_WRAP_KEYBOARD_H // LOVE +#include "common/runtime.h" #include "Keyboard.h" namespace love @@ -29,9 +30,11 @@ namespace love namespace keyboard { -int w_isDown(lua_State *L); int w_setKeyRepeat(lua_State *L); -int w_getKeyRepeat(lua_State *L); +int w_hasKeyRepeat(lua_State *L); +int w_isDown(lua_State *L); +int w_setTextInput(lua_State *L); +int w_hasTextInput(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_keyboard(lua_State *L); } // keyboard diff --git a/src/modules/love/love.cpp b/src/modules/love/love.cpp index 657d7b8b7..77fe5b208 100644 --- a/src/modules/love/love.cpp +++ b/src/modules/love/love.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,51 +36,13 @@ #include #endif // LOVE_LEGENDARY_CONSOLE_IO_HACK -#ifdef LOVE_LEGENDARY_LIBSTDCXX_HACK - -#include - -// Workarounds for symbols that are missing from Leopard stdlibc++.dylib. -// http://stackoverflow.com/questions/3484043/os-x-program-runs-on-dev-machine-crashing-horribly-on-others -_GLIBCXX_BEGIN_NAMESPACE(std) -// From ostream_insert.h -template ostream& __ostream_insert(ostream&, const char*, streamsize); - -#ifdef _GLIBCXX_USE_WCHAR_T -template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize); -#endif - -// From ostream.tcc -template ostream& ostream::_M_insert(long); -template ostream& ostream::_M_insert(unsigned long); -template ostream& ostream::_M_insert(bool); -#ifdef _GLIBCXX_USE_LONG_LONG -template ostream& ostream::_M_insert(long long); -template ostream& ostream::_M_insert(unsigned long long); -#endif -template ostream& ostream::_M_insert(double); -template ostream& ostream::_M_insert(long double); -template ostream& ostream::_M_insert(const void*); - -#ifdef _GLIBCXX_USE_WCHAR_T -template wostream& wostream::_M_insert(long); -template wostream& wostream::_M_insert(unsigned long); -template wostream& wostream::_M_insert(bool); -#ifdef _GLIBCXX_USE_LONG_LONG -template wostream& wostream::_M_insert(long long); -template wostream& wostream::_M_insert(unsigned long long); -#endif -template wostream& wostream::_M_insert(double); -template wostream& wostream::_M_insert(long double); -template wostream& wostream::_M_insert(const void*); -#endif - -_GLIBCXX_END_NAMESPACE - -#endif // LOVE_LEGENDARY_LIBSTDCXX_HACK - // Libraries. -#include "libraries/luasocket/luasocket.h" +#ifdef LOVE_ENABLE_LUASOCKET +# include "libraries/luasocket/luasocket.h" +#endif +#ifdef LOVE_ENABLE_ENET +# include "libraries/enet/lua-enet.h" +#endif // Scripts #include "scripts/boot.lua.h" @@ -90,44 +52,112 @@ _GLIBCXX_END_NAMESPACE // of addressing implementations directly. extern "C" { +#if defined(LOVE_ENABLE_AUDIO) extern int luaopen_love_audio(lua_State*); +#endif +#if defined(LOVE_ENABLE_EVENT) extern int luaopen_love_event(lua_State*); +#endif +#if defined(LOVE_ENABLE_FILESYSTEM) extern int luaopen_love_filesystem(lua_State*); +#endif +#if defined(LOVE_ENABLE_FONT) extern int luaopen_love_font(lua_State*); +#endif +#if defined(LOVE_ENABLE_GRAPHICS) extern int luaopen_love_graphics(lua_State*); +#endif +#if defined(LOVE_ENABLE_IMAGE) extern int luaopen_love_image(lua_State*); +#endif +#if defined(LOVE_ENABLE_JOYSTICK) extern int luaopen_love_joystick(lua_State*); +#endif +#if defined(LOVE_ENABLE_KEYBOARD) extern int luaopen_love_keyboard(lua_State*); - extern int luaopen_love_mouse(lua_State*); - extern int luaopen_love_physics(lua_State*); - extern int luaopen_love_sound(lua_State*); - extern int luaopen_love_timer(lua_State*); - extern int luaopen_love_thread(lua_State*); +#endif +#if defined(LOVE_ENABLE_MATH) extern int luaopen_love_math(lua_State*); +#endif +#if defined(LOVE_ENABLE_MOUSE) + extern int luaopen_love_mouse(lua_State*); +#endif +#if defined(LOVE_ENABLE_PHYSICS) + extern int luaopen_love_physics(lua_State*); +#endif +#if defined(LOVE_ENABLE_SOUND) + extern int luaopen_love_sound(lua_State*); +#endif +#if defined(LOVE_ENABLE_SYSTEM) + extern int luaopen_love_system(lua_State*); +#endif +#if defined(LOVE_ENABLE_TIMER) + extern int luaopen_love_timer(lua_State*); +#endif +#if defined(LOVE_ENABLE_THREAD) + extern int luaopen_love_thread(lua_State*); +#endif +#if defined(LOVE_ENABLE_WINDOW) + extern int luaopen_love_window(lua_State*); +#endif extern int luaopen_love_boot(lua_State*); } static const luaL_Reg modules[] = { +#if defined(LOVE_ENABLE_AUDIO) { "love.audio", luaopen_love_audio }, +#endif +#if defined(LOVE_ENABLE_EVENT) { "love.event", luaopen_love_event }, +#endif +#if defined(LOVE_ENABLE_FILESYSTEM) { "love.filesystem", luaopen_love_filesystem }, +#endif +#if defined(LOVE_ENABLE_FONT) { "love.font", luaopen_love_font }, +#endif +#if defined(LOVE_ENABLE_GRAPHICS) { "love.graphics", luaopen_love_graphics }, +#endif +#if defined(LOVE_ENABLE_IMAGE) { "love.image", luaopen_love_image }, +#endif +#if defined(LOVE_ENABLE_JOYSTICK) { "love.joystick", luaopen_love_joystick }, +#endif +#if defined(LOVE_ENABLE_KEYBOARD) { "love.keyboard", luaopen_love_keyboard }, - { "love.mouse", luaopen_love_mouse }, - { "love.physics", luaopen_love_physics }, - { "love.sound", luaopen_love_sound }, - { "love.timer", luaopen_love_timer }, - { "love.thread", luaopen_love_thread }, +#endif +#if defined(LOVE_ENABLE_MATH) { "love.math", luaopen_love_math }, +#endif +#if defined(LOVE_ENABLE_MOUSE) + { "love.mouse", luaopen_love_mouse }, +#endif +#if defined(LOVE_ENABLE_PHYSICS) + { "love.physics", luaopen_love_physics }, +#endif +#if defined(LOVE_ENABLE_SOUND) + { "love.sound", luaopen_love_sound }, +#endif +#if defined(LOVE_ENABLE_SYSTEM) + { "love.system", luaopen_love_system }, +#endif +#if defined(LOVE_ENABLE_TIMER) + { "love.timer", luaopen_love_timer }, +#endif +#if defined(LOVE_ENABLE_THREAD) + { "love.thread", luaopen_love_thread }, +#endif +#if defined(LOVE_ENABLE_WINDOW) + { "love.window", luaopen_love_window }, +#endif { "love.boot", luaopen_love_boot }, { 0, 0 } }; #ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK -int w__openConsole(lua_State * L); +int w__openConsole(lua_State *L); #endif // LOVE_LEGENDARY_CONSOLE_IO_HACK const char *love_version() @@ -190,14 +220,19 @@ int luaopen_love(lua_State * L) love::luax_preload(L, modules[i].func, modules[i].name); } +#ifdef LOVE_ENABLE_LUASOCKET love::luasocket::__open(L); +#endif +#ifdef LOVE_ENABLE_ENET + love::luax_preload(L, luaopen_enet, "enet"); +#endif return 1; } #ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK -int w__openConsole(lua_State * L) +int w__openConsole(lua_State *L) { static bool is_open = false; if (is_open) @@ -242,7 +277,8 @@ int w__openConsole(lua_State * L) int luaopen_love_boot(lua_State *L) { if (luaL_loadbuffer(L, (const char *)love::boot_lua, sizeof(love::boot_lua), "boot.lua") == 0) - lua_call(L, 0, 1); + lua_call(L, 0, 1); + return 1; } diff --git a/src/modules/love/love.h b/src/modules/love/love.h index 4a50c8062..c6ab3975c 100644 --- a/src/modules/love/love.h +++ b/src/modules/love/love.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,16 +18,27 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +#ifndef LOVE_LOVE_H +#define LOVE_LOVE_H + // LOVE #include "common/config.h" // Forward declare lua_State. struct lua_State; +#ifdef __cplusplus extern "C" { - LOVE_EXPORT const char *love_version(); - LOVE_EXPORT const char *love_codename(); - LOVE_EXPORT int luaopen_love(lua_State *L); - LOVE_EXPORT int luaopen_love_boot(lua_State *L); +#endif + +LOVE_EXPORT const char *love_version(); +LOVE_EXPORT const char *love_codename(); +LOVE_EXPORT int luaopen_love(lua_State *L); +LOVE_EXPORT int luaopen_love_boot(lua_State *L); + +#ifdef __cplusplus } +#endif + +#endif // LOVE_LOVE_H diff --git a/src/modules/math/BezierCurve.cpp b/src/modules/math/BezierCurve.cpp new file mode 100644 index 000000000..33c96c56f --- /dev/null +++ b/src/modules/math/BezierCurve.cpp @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2006-2014 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 "BezierCurve.h" +#include "common/Exception.h" + +#include + +using namespace std; + +namespace +{ + +/** + * Subdivide Bezier polygon. + **/ +void subdivide(vector &points, int k) +{ + if (k <= 0) + return; + + // subdivision using de casteljau - subdivided control polygons are + // on the 'edges' of the computation scheme, e.g: + // + // ------LEFT-------> + // b00 b10 b20 b30 + // b01 b11 b21 .--- + // b02 b12 .---' + // b03 .---'RIGHT + // <--' + // + // the subdivided control polygon is: + // b00, b10, b20, b30, b21, b12, b03 + vector left, right; + left.reserve(points.size()); + right.reserve(points.size()); + + for (size_t step = 1; step < points.size(); ++step) + { + left.push_back(points[0]); + right.push_back(points[points.size() - step]); + for (size_t i = 0; i < points.size() - step; ++i) + points[i] = (points[i] + points[i+1]) * .5; + } + left.push_back(points[0]); + right.push_back(points[0]); + + // recurse + subdivide(left, k-1); + subdivide(right, k-1); + + // merge (right is in reversed order) + points.resize(left.size() + right.size() - 1); + for (size_t i = 0; i < left.size(); ++i) + points[i] = left[i]; + for (size_t i = 1; i < right.size(); ++i) + points[i-1 + left.size()] = right[right.size() - i - 1]; +} + +} + +namespace love +{ +namespace math +{ + +BezierCurve::BezierCurve(const vector &pts) + : controlPoints(pts) +{ +} + + +BezierCurve BezierCurve::getDerivative() const +{ + if (getDegree() < 1) + throw Exception("Cannot derive a curve of degree < 1."); + // actually we can, it just doesn't make any sense. + + vector forward_differences(controlPoints.size()-1); + float degree = float(getDegree()); + for (size_t i = 0; i < forward_differences.size(); ++i) + forward_differences[i] = (controlPoints[i+1] - controlPoints[i]) * degree; + + return BezierCurve(forward_differences); +} + +const Vector &BezierCurve::getControlPoint(int i) const +{ + if (i < 0) + i += controlPoints.size(); + + if (i < 0 || (size_t) i >= controlPoints.size()) + throw Exception("Invalid control point index"); + + return controlPoints[i]; +} + +void BezierCurve::setControlPoint(int i, const Vector &point) +{ + if (i < 0) + i += controlPoints.size(); + + if (i < 0 || (size_t) i >= controlPoints.size()) + throw Exception("Invalid control point index"); + + controlPoints[i] = point; +} + +void BezierCurve::insertControlPoint(const Vector &point, int pos) +{ + if (pos < 0) + pos += controlPoints.size() + 1; + + if (pos < 0 ||(size_t) pos > controlPoints.size()) + throw Exception("Invalid control point index"); + + controlPoints.insert(controlPoints.begin() + pos, point); +} + +void BezierCurve::translate(const Vector &t) +{ + for (size_t i = 0; i < controlPoints.size(); ++i) + controlPoints[i] += t; +} + +void BezierCurve::rotate(double phi, const Vector ¢er) +{ + float c = cos(phi), s = sin(phi); + for (size_t i = 0; i < controlPoints.size(); ++i) + { + Vector v = controlPoints[i] - center; + controlPoints[i].x = c * v.x - s * v.y + center.x; + controlPoints[i].y = s * v.x + c * v.y + center.y; + } +} + +void BezierCurve::scale(double s, const Vector ¢er) +{ + for (size_t i = 0; i < controlPoints.size(); ++i) + controlPoints[i] = (controlPoints[i] - center) * s + center; +} + +Vector BezierCurve::evaluate(double t) const +{ + if (t < 0 || t > 1) + throw Exception("Invalid evaluation parameter: must be between 0 and 1"); + if (controlPoints.size() < 2) + throw Exception("Invalid Bezier curve: Not enough control points."); + + // de casteljau + vector points(controlPoints); + for (size_t step = 1; step < controlPoints.size(); ++step) + for (size_t i = 0; i < controlPoints.size() - step; ++i) + points[i] = points[i] * (1-t) + points[i+1] * t; + + return points[0]; +} + +vector BezierCurve::render(size_t accuracy) const +{ + if (controlPoints.size() < 2) + throw Exception("Invalid Bezier curve: Not enough control points."); + vector vertices(controlPoints); + subdivide(vertices, accuracy); + return vertices; +} + + +} // namespace math +} // namespace love diff --git a/src/modules/math/BezierCurve.h b/src/modules/math/BezierCurve.h new file mode 100644 index 000000000..9370dc52f --- /dev/null +++ b/src/modules/math/BezierCurve.h @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MATH_BEZIER_CURVE_H +#define LOVE_MATH_BEZIER_CURVE_H + +// LOVE +#include "common/Object.h" +#include "common/Vector.h" +#include + +namespace love +{ +namespace math +{ + +class BezierCurve : public Object +{ +public: + + /** + * @param controlPoints Control polygon of the curve. + **/ + BezierCurve(const std::vector &controlPoints); + + /** + * @returns Degree of the curve + **/ + size_t getDegree() const + { + return controlPoints.size() - 1; + } + + /** + * @returns First derivative of the curve. + */ + BezierCurve getDerivative() const; + + /** + * @returns i'th control point. + **/ + const Vector &getControlPoint(int i) const; + + /** + * Sets the i'th control point. + * @param i Control point to change. + * @param point New control point. + **/ + void setControlPoint(int i, const Vector &point); + + /** + * Insert a new control point before the i'th control point. + * If i < 0, Lua string indexing rules apply. + * @param point Control point to insert. + * @param pos Position to insert. + **/ + void insertControlPoint(const Vector &point, int pos = -1); + + /** + * @returns Number of control points. + **/ + size_t getControlPointCount() const + { + return controlPoints.size(); + } + + /** + * Move the curve. + * @param t Translation vector. + */ + void translate(const Vector &t); + + /** + * Rotate the curve. + * @param phi Rotation angle (radians). + * @param center Rotation center. + */ + void rotate(double phi, const Vector ¢er); + + /** + * Scale the curve. + * @param phi Scale factor. + * @param center Scale center. + */ + void scale(double phi, const Vector ¢er); + + /** + * Evaluates the curve at time t. + * @param t Curve parameter, must satisfy 0 <= t <= 1. + **/ + Vector evaluate(double t) const; + + /** + * Renders the curve by subdivision. + * @param accuracy The 'fineness' of the curve. + * @returns A polygon chain that approximates the bezier curve. + **/ + std::vector render(size_t accuracy = 4) const; + +private: + std::vector controlPoints; +}; + +} +} + +#endif diff --git a/src/modules/math/MathModule.cpp b/src/modules/math/MathModule.cpp new file mode 100644 index 000000000..9ffefe839 --- /dev/null +++ b/src/modules/math/MathModule.cpp @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2006-2014 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 "MathModule.h" +#include "common/Vector.h" +#include "BezierCurve.h" + +// STL +#include +#include +#include + +using std::list; +using std::vector; +using love::Vertex; + +namespace +{ + // check if an angle is oriented counter clockwise + inline bool is_oriented_ccw(const Vertex &a, const Vertex &b, const Vertex &c) + { + // return det(b-a, c-a) >= 0 + return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) >= 0; + } + + // check if a and b are on the same side of the line c->d + bool on_same_side(const Vertex &a, const Vertex &b, const Vertex &c, const Vertex &d) + { + float px = d.x - c.x, py = d.y - c.y; + // return det(p, a-c) * det(p, b-c) >= 0 + float l = px * (a.y - c.y) - py * (a.x - c.x); + float m = px * (b.y - c.y) - py * (b.x - c.x); + return l * m >= 0; + } + + // checks is p is contained in the triangle abc + inline bool point_in_triangle(const Vertex &p, const Vertex &a, const Vertex &b, const Vertex &c) + { + return on_same_side(p,a, b,c) && on_same_side(p,b, a,c) && on_same_side(p,c, a,b); + } + + // checks if any vertex in `vertices' is in the triangle abc. + bool any_point_in_triangle(const list &vertices, const Vertex &a, const Vertex &b, const Vertex &c) + { + list::const_iterator it, end = vertices.end(); + for (it = vertices.begin(); it != end; ++it) + { + const Vertex *p = *it; + if ((p != &a) && (p != &b) && (p != &c) && point_in_triangle(*p, a,b,c)) // oh god... + return true; + } + + return false; + } + + inline bool is_ear(const Vertex &a, const Vertex &b, const Vertex &c, const list &vertices) + { + return is_oriented_ccw(a,b,c) && !any_point_in_triangle(vertices, a,b,c); + } +} + +namespace love +{ +namespace math +{ + +Math Math::instance; + +Math::Math() + : rng() +{ + // prevent the runtime from free()-ing this + retain(); +} + +RandomGenerator *Math::newRandomGenerator() +{ + return new RandomGenerator(); +} + +BezierCurve *Math::newBezierCurve(const vector &points) +{ + return new BezierCurve(points); +} + +vector Math::triangulate(const vector &polygon) +{ + if (polygon.size() < 3) + throw love::Exception("Not a polygon"); + else if (polygon.size() == 3) + return vector(1, Triangle(polygon[0], polygon[1], polygon[2])); + + // collect list of connections and record leftmost item to check if the polygon + // has the expected winding + vector next_idx(polygon.size()), prev_idx(polygon.size()); + size_t idx_lm = 0; + for (size_t i = 0; i < polygon.size(); ++i) + { + const Vertex &lm = polygon[idx_lm], &p = polygon[i]; + if (p.x < lm.x || (p.x == lm.x && p.y < lm.y)) + idx_lm = i; + next_idx[i] = i+1; + prev_idx[i] = i-1; + } + next_idx[next_idx.size()-1] = 0; + prev_idx[0] = prev_idx.size()-1; + + // check if the polygon has the expected winding and reverse polygon if needed + if (!is_oriented_ccw(polygon[prev_idx[idx_lm]], polygon[idx_lm], polygon[next_idx[idx_lm]])) + next_idx.swap(prev_idx); + + // collect list of concave polygons + list concave_vertices; + for (size_t i = 0; i < polygon.size(); ++i) + { + if (!is_oriented_ccw(polygon[prev_idx[i]], polygon[i], polygon[next_idx[i]])) + concave_vertices.push_back(&polygon[i]); + } + + // triangulation according to kong + vector triangles; + size_t n_vertices = polygon.size(); + size_t current = 1, skipped = 0, next, prev; + while (n_vertices > 3) + { + next = next_idx[current]; + prev = prev_idx[current]; + const Vertex &a = polygon[prev], &b = polygon[current], &c = polygon[next]; + if (is_ear(a,b,c, concave_vertices)) + { + triangles.push_back(Triangle(a,b,c)); + next_idx[prev] = next; + prev_idx[next] = prev; + concave_vertices.remove(&b); + --n_vertices; + skipped = 0; + } + else if (++skipped > n_vertices) + { + throw love::Exception("Cannot triangulate polygon."); + } + current = next; + } + next = next_idx[current]; + prev = prev_idx[current]; + triangles.push_back(Triangle(polygon[prev], polygon[current], polygon[next])); + + return triangles; +} + +bool Math::isConvex(const std::vector &polygon) +{ + if (polygon.size() < 3) + return false; + + // a polygon is convex if all corners turn in the same direction + // turning direction can be determined using the cross-product of + // the forward difference vectors + size_t i = polygon.size() - 2, j = polygon.size() - 1, k = 0; + Vector p(polygon[j].x - polygon[i].x, polygon[j].y - polygon[i].y); + Vector q(polygon[k].x - polygon[j].x, polygon[k].y - polygon[j].y); + float winding = p ^ q; + + while (k+1 < polygon.size()) + { + i = j; j = k; k++; + p.x = polygon[j].x - polygon[i].x; + p.y = polygon[j].y - polygon[i].y; + q.x = polygon[k].x - polygon[j].x; + q.y = polygon[k].y - polygon[j].y; + + if ((p^q) * winding < 0) + return false; + } + return true; +} + +} // math +} // love diff --git a/src/modules/math/MathModule.h b/src/modules/math/MathModule.h new file mode 100644 index 000000000..70f420515 --- /dev/null +++ b/src/modules/math/MathModule.h @@ -0,0 +1,180 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MATH_MODMATH_H +#define LOVE_MATH_MODMATH_H + +#include "RandomGenerator.h" + +// LOVE +#include "common/Module.h" +#include "common/math.h" +#include "common/Vector.h" +#include "common/int.h" + +// Noise +#include "libraries/noise1234/simplexnoise1234.h" + +// STL +#include + +namespace love +{ +namespace math +{ + +class BezierCurve; + +class Math : public Module +{ +private: + + RandomGenerator rng; + +public: + + virtual ~Math() + {} + + inline void setRandomSeed(RandomGenerator::Seed seed) + { + rng.setSeed(seed); + } + + inline void setRandomSeed(uint32 low, uint32 high) + { + rng.setSeed(low, high); + } + + inline RandomGenerator::Seed getRandomSeed() const + { + return rng.getSeed(); + } + + inline void getRandomSeed(uint32 &low, uint32 &high) const + { + rng.getSeed(low, high); + } + + /** + * @copydoc RandomGenerator::random() + **/ + inline double random() + { + return rng.random(); + } + + /** + * @copydoc RandomGenerator::random(double) + **/ + inline double random(double max) + { + return rng.random(max); + } + + /** + * @copydoc RandomGenerator::random(double,double) + **/ + inline double random(double min, double max) + { + return rng.random(min, max); + } + + /** + * @copydoc RandomGenerator::randomNormal() + **/ + inline double randomNormal(double stddev) + { + return rng.randomNormal(stddev); + } + + /** + * Create a new random number generator. + **/ + RandomGenerator *newRandomGenerator(); + + /** + * Creates a new bezier curve. + **/ + BezierCurve *newBezierCurve(const std::vector &points); + + virtual const char *getName() const + { + return "love.math"; + } + + /** + * Triangulate a simple polygon. + * + * @param polygon Polygon to triangulate. Must not intersect itself. + * @return List of triangles the polygon is composed of. + **/ + std::vector triangulate(const std::vector &polygon); + + /** + * Checks whether a polygon is convex. + * + * @param polygon Polygon to test. + * @return True if the polygon is convex, false otherwise. + **/ + bool isConvex(const std::vector &polygon); + + /** + * Calculate Simplex noise for the specified coordinate(s). + * + * @return Noise value in the range of [0, 1]. + **/ + float noise(float x) const; + float noise(float x, float y) const; + float noise(float x, float y, float z) const; + float noise(float x, float y, float z, float w) const; + + static Math instance; + +private: + + Math(); + +}; // Math + +inline float Math::noise(float x) const +{ + return SimplexNoise1234::noise(x) * 0.5f + 0.5f; +} + +inline float Math::noise(float x, float y) const +{ + return SimplexNoise1234::noise(x, y) * 0.5f + 0.5f; +} + +inline float Math::noise(float x, float y, float z) const +{ + return SimplexNoise1234::noise(x, y, z) * 0.5f + 0.5f; +} + +inline float Math::noise(float x, float y, float z, float w) const +{ + return SimplexNoise1234::noise(x, y, z, w) * 0.5f + 0.5f; +} + +} // math +} // love + +#endif diff --git a/src/modules/math/ModMath.h b/src/modules/math/ModMath.h deleted file mode 100644 index f5486ccf0..000000000 --- a/src/modules/math/ModMath.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2006-2013 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. - **/ - -#ifndef LOVE_MATH_MODMATH_H -#define LOVE_MATH_MODMATH_H - -// LOVE -#include "common/Module.h" - -// STL -#include -#include - -namespace love -{ -namespace math -{ - -class ModMath : public Module -{ -public: - ModMath(); - virtual ~ModMath() {} - - /** Set pseudo random seed. - * - * It's up to the implementation how to use this. - * - * @param seed The random seed. - */ - inline void randomseed(uint64_t seed) - { - RNGState.seed = seed; - } - - /** Return uniformly distributed pseudo random integer. - * - * @returns Pseudo random integer in [0,2^32). - */ - uint32_t rand(); - - /** Get uniformly distributed pseudo random number in [0,1). - * - * @returns Pseudo random number in [0,1). - */ - inline double random() - { - return double(rand()) / (double(std::numeric_limits::max()) + 1.0); - } - - /** Get normally distributed pseudo random number. - * - * @param stddev Standard deviation of the distribution. - * @returns Normally distributed random number with mean 0 and variance (stddev)². - */ - double randnormal(double stddev); - - virtual const char *getName() const - { - return "love.math"; - } - -private: - struct - { - uint64_t seed; - double last_randnormal; - } RNGState; -}; - -} // math -} // love - -#endif diff --git a/src/modules/math/ModMath.cpp b/src/modules/math/RandomGenerator.cpp similarity index 53% rename from src/modules/math/ModMath.cpp rename to src/modules/math/RandomGenerator.cpp index 6e873d7d6..1f7b58a47 100644 --- a/src/modules/math/ModMath.cpp +++ b/src/modules/math/RandomGenerator.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,9 +18,9 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "ModMath.h" -#include "common/math.h" +#include "RandomGenerator.h" +// STL #include namespace love @@ -30,35 +30,56 @@ namespace math // 64 bit Xorshift implementation taken from the end of Sec. 3 (page 4) in // George Marsaglia, "Xorshift RNGs", Journal of Statistical Software, Vol.8 (Issue 14), 2003 -ModMath::ModMath() + +RandomGenerator::RandomGenerator() + : last_randomnormal(std::numeric_limits::infinity()) { - RNGState.seed = 0x0139408DCBBF7A44; - RNGState.last_randnormal = std::numeric_limits::infinity(); + // because it is too big for some compilers to handle ... if you know what + // i mean +#ifdef LOVE_BIG_ENDIAN + seed.b32.a = 0x0139408D; + seed.b32.b = 0xCBBF7A44; +#else + seed.b32.b = 0x0139408D; + seed.b32.a = 0xCBBF7A44; +#endif + + rng_state = seed; } -uint32_t ModMath::rand() +void RandomGenerator::setSeed(RandomGenerator::Seed newseed) { - uint64_t &x = RNGState.seed; - x ^= (x << 13); - x ^= (x >> 7); - x ^= (x << 17); - return x; + // 0 xor 0 is still 0, so Xorshift can't generate new numbers. + if (newseed.b64 == 0) + throw love::Exception("Invalid random seed."); + + seed = newseed; + rng_state = seed; +} + +uint64 RandomGenerator::rand() +{ + rng_state.b64 ^= (rng_state.b64 << 13); + rng_state.b64 ^= (rng_state.b64 >> 7); + rng_state.b64 ^= (rng_state.b64 << 17); + return rng_state.b64; } // Box–Muller transform -double ModMath::randnormal(double stddev) +double RandomGenerator::randomNormal(double stddev) { - if (RNGState.last_randnormal != std::numeric_limits::infinity()) + // use cached number if possible + if (last_randomnormal != std::numeric_limits::infinity()) { - double r = RNGState.last_randnormal; - RNGState.last_randnormal = std::numeric_limits::infinity(); + double r = last_randomnormal; + last_randomnormal = std::numeric_limits::infinity(); return r * stddev; } double r = sqrt(-2.0 * log(1. - random())); double phi = 2.0 * LOVE_M_PI * (1. - random()); - RNGState.last_randnormal = r * cos(phi); + last_randomnormal = r * cos(phi); return r * sin(phi) * stddev; } diff --git a/src/modules/math/RandomGenerator.h b/src/modules/math/RandomGenerator.h new file mode 100644 index 000000000..830a9506c --- /dev/null +++ b/src/modules/math/RandomGenerator.h @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MATH_RANDOM_GENERATOR_H +#define LOVE_MATH_RANDOM_GENERATOR_H + +// LOVE +#include "common/config.h" +#include "common/Exception.h" +#include "common/math.h" +#include "common/int.h" +#include "common/Object.h" + +// STL +#include + +namespace love +{ +namespace math +{ + +class RandomGenerator : public Object +{ +public: + + union Seed + { + uint64 b64; + struct + { + uint32 a; + uint32 b; + } b32; + }; + + RandomGenerator(); + virtual ~RandomGenerator() {} + + /** + * Set pseudo-random seed. + * It's up to the implementation how to use this. + **/ + void setSeed(Seed seed); + + /** + * Separately set the low and high bits of the pseudo-random seed. + **/ + inline void setSeed(uint32 low, uint32 high) + { + Seed newseed; + +#ifdef LOVE_BIG_ENDIAN + newseed.b32.a = high; + newseed.b32.b = low; +#else + newseed.b32.b = high; + newseed.b32.a = low; +#endif + + setSeed(newseed); + } + + inline Seed getSeed() const + { + return seed; + } + + inline void getSeed(uint32 &low, uint32 &high) const + { +#ifdef LOVE_BIG_ENDIAN + high = seed.b32.a; + low = seed.b32.b; +#else + high = seed.b32.b; + low = seed.b32.a; +#endif + } + + /** + * Return uniformly distributed pseudo random integer. + * + * @return Pseudo random integer in [0,2^64). + **/ + uint64 rand(); + + /** + * Get uniformly distributed pseudo random number in [0,1). + * + * @return Pseudo random number in [0,1). + **/ + inline double random() + { + return double(rand()) / (double(std::numeric_limits::max()) + 1.0); + } + + /** + * Get uniformly distributed pseudo random number in [0,max). + * + * @return Pseudo random number in [0,max). + **/ + inline double random(double max) + { + return random() * max; + } + + /** + * Get uniformly distributed pseudo random number in [min, max). + * + * @return Pseudo random number in [min, max). + **/ + inline double random(double min, double max) + { + return random() * (max - min) + min; + } + + /** + * Get normally distributed pseudo random number. + * + * @param stddev Standard deviation of the distribution. + * @return Normally distributed random number with mean 0 and variance (stddev)². + **/ + double randomNormal(double stddev); + +private: + + Seed seed; + Seed rng_state; + double last_randomnormal; + +}; // RandomGenerator + +} // math +} // love + +#endif // LOVE_MATH_RANDOM_GENERATOR_H diff --git a/src/modules/math/wrap_BezierCurve.cpp b/src/modules/math/wrap_BezierCurve.cpp new file mode 100644 index 000000000..4ab196455 --- /dev/null +++ b/src/modules/math/wrap_BezierCurve.cpp @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "common/Exception.h" +#include "wrap_BezierCurve.h" + +#include + +namespace love +{ +namespace math +{ + +BezierCurve *luax_checkbeziercurve(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "BezierCurve", MATH_BEZIER_CURVE_T); +} + +int w_BezierCurve_getDegree(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + lua_pushnumber(L, curve->getDegree()); + return 1; +} + +int w_BezierCurve_getDerivative(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + BezierCurve *deriv = new BezierCurve(curve->getDerivative()); + luax_pushtype(L, "BezierCurve", MATH_BEZIER_CURVE_T, deriv); + return 1; +} + +int w_BezierCurve_getControlPoint(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + int idx = luaL_checkinteger(L, 2); + + if (idx > 0) // 1-indexing + idx--; + + EXCEPT_GUARD( + Vector v = curve->getControlPoint(idx); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + ) + + return 2; +} + +int w_BezierCurve_setControlPoint(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + int idx = luaL_checkinteger(L, 2); + float vx = (float) luaL_checknumber(L, 3); + float vy = (float) luaL_checknumber(L, 4); + + if (idx > 0) // 1-indexing + idx--; + + EXCEPT_GUARD(curve->setControlPoint(idx, Vector(vx,vy));) + return 0; +} + +int w_BezierCurve_insertControlPoint(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + float vx = (float) luaL_checknumber(L, 2); + float vy = (float) luaL_checknumber(L, 3); + int idx = luaL_optinteger(L, 4, -1); + + if (idx > 0) // 1-indexing + idx--; + + EXCEPT_GUARD(curve->insertControlPoint(Vector(vx,vy), idx);) + return 0; +} + +int w_BezierCurve_getControlPointCount(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + lua_pushinteger(L, curve->getControlPointCount()); + return 1; +} + +int w_BezierCurve_translate(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + float dx = (float) luaL_checknumber(L, 2); + float dy = (float) luaL_checknumber(L, 3); + curve->translate(Vector(dx,dy)); + return 0; +} + +int w_BezierCurve_rotate(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + double phi = luaL_checknumber(L, 2); + float ox = (float) luaL_optnumber(L, 3, 0); + float oy = (float) luaL_optnumber(L, 4, 0); + curve->rotate(phi, Vector(ox,oy)); + return 0; +} + +int w_BezierCurve_scale(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + double s = luaL_checknumber(L, 2); + float ox = (float) luaL_optnumber(L, 3, 0); + float oy = (float) luaL_optnumber(L, 4, 0); + curve->scale(s, Vector(ox,oy)); + return 0; +} + +int w_BezierCurve_evaluate(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + double t = luaL_checknumber(L, 2); + + EXCEPT_GUARD( + Vector v = curve->evaluate(t); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + ) + + return 2; + +} + +int w_BezierCurve_render(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + int accuracy = luaL_optinteger(L, 2, 5); + + std::vector points; + EXCEPT_GUARD(points = curve->render(accuracy);) + + lua_createtable(L, points.size()*2, 0); + for (size_t i = 0; i < points.size(); ++i) + { + lua_pushnumber(L, points[i].x); + lua_rawseti(L, -2, 2*i+1); + lua_pushnumber(L, points[i].y); + lua_rawseti(L, -2, 2*i+2); + } + + return 1; +} + +static const luaL_Reg functions[] = +{ + {"getDegree", w_BezierCurve_getDegree}, + {"getDerivative", w_BezierCurve_getDerivative}, + {"getControlPoint", w_BezierCurve_getControlPoint}, + {"setControlPoint", w_BezierCurve_setControlPoint}, + {"insertControlPoint", w_BezierCurve_insertControlPoint}, + {"getControlPointCount", w_BezierCurve_getControlPointCount}, + {"translate", w_BezierCurve_translate}, + {"rotate", w_BezierCurve_rotate}, + {"scale", w_BezierCurve_scale}, + {"evaluate", w_BezierCurve_evaluate}, + {"render", w_BezierCurve_render}, + { 0, 0 } +}; + +extern "C" int luaopen_beziercurve(lua_State *L) +{ + return luax_register_type(L, "BezierCurve", functions); +} + +} // math +} // love diff --git a/src/modules/math/wrap_BezierCurve.h b/src/modules/math/wrap_BezierCurve.h new file mode 100644 index 000000000..ad0558e96 --- /dev/null +++ b/src/modules/math/wrap_BezierCurve.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MATH_WRAP_BEZIER_CURVE_H +#define LOVE_MATH_WRAP_BEZIER_CURVE_H + +// LOVE +#include "BezierCurve.h" +#include "common/runtime.h" + +namespace love +{ +namespace math +{ + +BezierCurve *luax_checkbeziercurve(lua_State *L, int idx); +int w_BezierCurve_getDegree(lua_State *L); +int w_BezierCurve_getDerivative(lua_State *L); +int w_BezierCurve_getControlPoint(lua_State *L); +int w_BezierCurve_setControlPoint(lua_State *L); +int w_BezierCurve_insertControlPoint(lua_State *L); +int w_BezierCurve_getControlPointCount(lua_State *L); +int w_BezierCurve_translate(lua_State *L); +int w_BezierCurve_rotate(lua_State *L); +int w_BezierCurve_scale(lua_State *L); +int w_BezierCurve_evaluate(lua_State *L); +int w_BezierCurve_render(lua_State *L); +extern "C" int luaopen_beziercurve(lua_State *L); + +} // math +} // love + +#endif // LOVE_MATH_WRAP_RANDOM_GENERATOR_H diff --git a/src/modules/math/wrap_Math.cpp b/src/modules/math/wrap_Math.cpp index 0959f2910..95cf37940 100644 --- a/src/modules/math/wrap_Math.cpp +++ b/src/modules/math/wrap_Math.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,108 +19,289 @@ **/ #include "wrap_Math.h" -#include "ModMath.h" +#include "wrap_RandomGenerator.h" +#include "wrap_BezierCurve.h" +#include "MathModule.h" +#include "BezierCurve.h" #include #include -namespace -{ - -union SeedConverter -{ - double seed_double; - uint64_t seed_uint; -}; - -} // anonymous namespace - namespace love { namespace math { -static ModMath *instance = 0; - -int w_randomseed(lua_State *L) +int w_setRandomSeed(lua_State *L) { - SeedConverter s; - s.seed_double = luaL_checknumber(L, 1); - instance->randomseed(s.seed_uint); + EXCEPT_GUARD(Math::instance.setRandomSeed(luax_checkrandomseed(L, 1));) return 0; } +int w_getRandomSeed(lua_State *L) +{ + uint32 low = 0, high = 0; + Math::instance.getRandomSeed(low, high); + lua_pushnumber(L, (lua_Number) low); + lua_pushnumber(L, (lua_Number) high); + return 2; +} + int w_random(lua_State *L) { - double r = instance->random(); - int l, u; - // verbatim from lua 5.1.4 source code: lmathlib.c:185 ff. - switch (lua_gettop(L)) - { - case 0: - lua_pushnumber(L, r); - break; - case 1: - u = luaL_checkint(L, 1); - luaL_argcheck(L, 1 <= u, 1, "interval is empty"); - lua_pushnumber(L, floor(r * u) + 1); - break; - case 2: - l = luaL_checkint(L, 1); - u = luaL_checkint(L, 2); - luaL_argcheck(L, l <= u, 2, "interval is empty"); - lua_pushnumber(L, floor(r * (u - l + 1)) + l); - break; - default: - return luaL_error(L, "wrong number of arguments"); - } + return luax_getrandom(L, 1, Math::instance.random()); +} + +int w_randomNormal(lua_State *L) +{ + double stddev = luaL_optnumber(L, 1, 1.0); + double mean = luaL_optnumber(L, 2, 0.0); + double r = Math::instance.randomNormal(stddev); + + lua_pushnumber(L, r + mean); return 1; } -int w_randnormal(lua_State *L) +int w_newRandomGenerator(lua_State *L) { - double mean = 0.0, stddev = 1.0; - if (lua_gettop(L) > 1) + RandomGenerator::Seed s; + if (lua_gettop(L) > 0) + s = luax_checkrandomseed(L, 1); + + RandomGenerator *t = Math::instance.newRandomGenerator(); + + if (lua_gettop(L) > 0) { - mean = luaL_checknumber(L, 1); - stddev = luaL_checknumber(L, 2); + bool should_error = false; + + try + { + t->setSeed(s); + } + catch (love::Exception &e) + { + t->release(); + should_error = true; + lua_pushstring(L, e.what()); + } + + if (should_error) + return luaL_error(L, "%s", lua_tostring(L, -1)); + } + + luax_pushtype(L, "RandomGenerator", MATH_RANDOM_GENERATOR_T, t); + return 1; +} + +int w_newBezierCurve(lua_State *L) +{ + std::vector points; + if (lua_istable(L, 1)) + { + size_t top = lua_objlen(L, 1); + points.reserve(top / 2); + for (size_t i = 1; i <= top; i += 2) + { + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 1, i+1); + + Vector v; + v.x = (float) luaL_checknumber(L, -2); + v.y = (float) luaL_checknumber(L, -1); + points.push_back(v); + + lua_pop(L, 2); + } } else { - stddev = luaL_optnumber(L, 1, 1.); + size_t top = lua_gettop(L); + points.reserve(top / 2); + for (size_t i = 1; i <= top; i += 2) + { + Vector v; + v.x = (float) luaL_checknumber(L, i); + v.y = (float) luaL_checknumber(L, i+1); + points.push_back(v); + } } - double r = instance->randnormal(stddev); - lua_pushnumber(L, r + mean); + BezierCurve *curve = Math::instance.newBezierCurve(points); + luax_pushtype(L, "BezierCurve", MATH_BEZIER_CURVE_T, curve); + return 1; +} + +int w_triangulate(lua_State *L) +{ + std::vector vertices; + if (lua_istable(L, 1)) + { + size_t top = lua_objlen(L, 1); + vertices.reserve(top / 2); + for (size_t i = 1; i <= top; i += 2) + { + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 1, i+1); + + Vertex v; + v.x = (float) luaL_checknumber(L, -2); + v.y = (float) luaL_checknumber(L, -1); + vertices.push_back(v); + + lua_pop(L, 2); + } + } + else + { + size_t top = lua_gettop(L); + vertices.reserve(top / 2); + for (size_t i = 1; i <= top; i += 2) + { + Vertex v; + v.x = (float) luaL_checknumber(L, i); + v.y = (float) luaL_checknumber(L, i+1); + vertices.push_back(v); + } + } + + if (vertices.size() < 3) + return luaL_error(L, "Need at least 3 vertices to triangulate"); + + std::vector triangles; + + EXCEPT_GUARD( + if (vertices.size() == 3) + triangles.push_back(Triangle(vertices[0], vertices[1], vertices[2])); + else + triangles = Math::instance.triangulate(vertices); + ) + + lua_createtable(L, triangles.size(), 0); + for (size_t i = 0; i < triangles.size(); ++i) + { + const Triangle &tri = triangles[i]; + + lua_createtable(L, 6, 0); + lua_pushnumber(L, tri.a.x); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, tri.a.y); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, tri.b.x); + lua_rawseti(L, -2, 3); + lua_pushnumber(L, tri.b.y); + lua_rawseti(L, -2, 4); + lua_pushnumber(L, tri.c.x); + lua_rawseti(L, -2, 5); + lua_pushnumber(L, tri.c.y); + lua_rawseti(L, -2, 6); + + lua_rawseti(L, -2, i+1); + } + + return 1; +} + +int w_isConvex(lua_State *L) +{ + std::vector vertices; + if (lua_istable(L, 1)) + { + size_t top = lua_objlen(L, 1); + vertices.reserve(top / 2); + for (size_t i = 1; i <= top; i += 2) + { + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 1, i+1); + + Vertex v; + v.x = (float) luaL_checknumber(L, -2); + v.y = (float) luaL_checknumber(L, -1); + vertices.push_back(v); + + lua_pop(L, 2); + } + } + else + { + int top = lua_gettop(L); + vertices.reserve(top / 2); + for (int i = 1; i <= top; i += 2) + { + Vertex v; + v.x = (float) luaL_checknumber(L, i); + v.y = (float) luaL_checknumber(L, i+1); + vertices.push_back(v); + } + } + + lua_pushboolean(L, Math::instance.isConvex(vertices)); + return 1; +} + +int w_noise(lua_State *L) +{ + float w, x, y, z; + float val; + + switch (lua_gettop(L)) + { + case 1: + x = (float) luaL_checknumber(L, 1); + val = Math::instance.noise(x); + break; + case 2: + x = (float) luaL_checknumber(L, 1); + y = (float) luaL_checknumber(L, 2); + val = Math::instance.noise(x, y); + break; + case 3: + x = (float) luaL_checknumber(L, 1); + y = (float) luaL_checknumber(L, 2); + z = (float) luaL_checknumber(L, 3); + val = Math::instance.noise(x, y, z); + break; + case 4: + default: + x = (float) luaL_checknumber(L, 1); + y = (float) luaL_checknumber(L, 2); + z = (float) luaL_checknumber(L, 3); + w = (float) luaL_checknumber(L, 4); + val = Math::instance.noise(x, y, z, w); + break; + } + + lua_pushnumber(L, (lua_Number) val); return 1; } // List of functions to wrap. static const luaL_Reg functions[] = { - { "randomseed", w_randomseed }, + { "setRandomSeed", w_setRandomSeed }, + { "getRandomSeed", w_getRandomSeed }, { "random", w_random }, - { "randnormal", w_randnormal }, + { "randomNormal", w_randomNormal }, + { "newRandomGenerator", w_newRandomGenerator }, + { "newBezierCurve", w_newBezierCurve }, + { "triangulate", w_triangulate }, + { "isConvex", w_isConvex }, + { "noise", w_noise }, { 0, 0 } }; static const lua_CFunction types[] = { + luaopen_randomgenerator, + luaopen_beziercurve, 0 }; extern "C" int luaopen_love_math(lua_State *L) { - if (instance == 0) - instance = new love::math::ModMath(); - else - instance->retain(); - - if (instance == 0) - return luaL_error(L, "Could not open module math."); + Math::instance.retain(); WrappedModule w; - w.module = instance; + w.module = &Math::instance; w.name = "math"; w.flags = MODULE_T; w.functions = functions; diff --git a/src/modules/math/wrap_Math.h b/src/modules/math/wrap_Math.h index b907013ee..8693535dc 100644 --- a/src/modules/math/wrap_Math.h +++ b/src/modules/math/wrap_Math.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -30,9 +30,15 @@ namespace love namespace math { -int w_randomseed(lua_State *L); +int w_setRandomSeed(lua_State *L); +int w_getRandomSeed(lua_State *L); int w_random(lua_State *L); -int w_randnormal(lua_State *L); +int w_randomNormal(lua_State *L); +int w_newRandomGenerator(lua_State *L); +int w_newBezierCurve(lua_State *L); +int w_triangulate(lua_State *L); +int w_isConvex(lua_State *L); +int w_noise(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_math(lua_State *L); } // random diff --git a/src/modules/math/wrap_RandomGenerator.cpp b/src/modules/math/wrap_RandomGenerator.cpp new file mode 100644 index 000000000..78cf53a04 --- /dev/null +++ b/src/modules/math/wrap_RandomGenerator.cpp @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "wrap_RandomGenerator.h" + +#include +#include + +namespace love +{ +namespace math +{ + +template +static T checkrandomseed_part(lua_State *L, int idx) +{ + double num = luaL_checknumber(L, idx); + double inf = std::numeric_limits::infinity(); + + // Disallow conversions from infinity and NaN. + if (num == inf || num == -inf || num != num) + luaL_argerror(L, idx, "invalid random seed"); + + return (T) num; +} + +RandomGenerator::Seed luax_checkrandomseed(lua_State *L, int idx) +{ + RandomGenerator::Seed s; + + if (!lua_isnoneornil(L, idx + 1)) + { + uint32 low = checkrandomseed_part(L, idx); + uint32 high = checkrandomseed_part(L, idx + 1); + +#ifdef LOVE_BIG_ENDIAN + s.b32.a = high; + s.b32.b = low; +#else + s.b32.b = high; + s.b32.a = low; +#endif + } + else + s.b64 = checkrandomseed_part(L, idx); + + return s; +} + +int luax_getrandom(lua_State *L, int startidx, double r) +{ + int l, u; + // from lua 5.1.4 source code: lmathlib.c:185 ff. + switch (lua_gettop(L) - (startidx - 1)) + { + case 0: + lua_pushnumber(L, r); + break; + case 1: + u = luaL_checkint(L, startidx); + luaL_argcheck(L, 1 <= u, startidx, "interval is empty"); + lua_pushnumber(L, floor(r * u) + 1); + break; + case 2: + l = luaL_checkint(L, startidx); + u = luaL_checkint(L, startidx + 1); + luaL_argcheck(L, l <= u, startidx + 1, "interval is empty"); + lua_pushnumber(L, floor(r * (u - l + 1)) + l); + break; + default: + return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + +RandomGenerator *luax_checkrandomgenerator(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "RandomGenerator", MATH_RANDOM_GENERATOR_T); +} + +int w_RandomGenerator_setSeed(lua_State *L) +{ + RandomGenerator *rng = luax_checkrandomgenerator(L, 1); + EXCEPT_GUARD(rng->setSeed(luax_checkrandomseed(L, 2));) + return 0; +} + +int w_RandomGenerator_getSeed(lua_State *L) +{ + RandomGenerator *rng = luax_checkrandomgenerator(L, 1); + + uint32 low = 0, high = 0; + rng->getSeed(low, high); + + lua_pushnumber(L, (lua_Number) low); + lua_pushnumber(L, (lua_Number) high); + return 2; +} + +int w_RandomGenerator_random(lua_State *L) +{ + RandomGenerator *rng = luax_checkrandomgenerator(L, 1); + return luax_getrandom(L, 2, rng->random()); +} + +int w_RandomGenerator_randomNormal(lua_State *L) +{ + RandomGenerator *rng = luax_checkrandomgenerator(L, 1); + + double stddev = luaL_optnumber(L, 2, 1.0); + double mean = luaL_optnumber(L, 3, 0.0); + double r = rng->randomNormal(stddev); + + lua_pushnumber(L, r + mean); + return 1; +} + +static const luaL_Reg functions[] = +{ + { "setSeed", w_RandomGenerator_setSeed }, + { "getSeed", w_RandomGenerator_getSeed }, + { "random", w_RandomGenerator_random }, + { "randomNormal", w_RandomGenerator_randomNormal }, + { 0, 0 } +}; + +extern "C" int luaopen_randomgenerator(lua_State *L) +{ + return luax_register_type(L, "RandomGenerator", functions); +} + +} // math +} // love diff --git a/src/modules/math/wrap_RandomGenerator.h b/src/modules/math/wrap_RandomGenerator.h new file mode 100644 index 000000000..07e82894e --- /dev/null +++ b/src/modules/math/wrap_RandomGenerator.h @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MATH_WRAP_RANDOM_GENERATOR_H +#define LOVE_MATH_WRAP_RANDOM_GENERATOR_H + +// LOVE +#include "RandomGenerator.h" +#include "common/config.h" +#include "common/runtime.h" + +namespace love +{ +namespace math +{ + +// Helper functions. +RandomGenerator::Seed luax_checkrandomseed(lua_State *L, int idx); +int luax_getrandom(lua_State *L, int startidx, double r); + +RandomGenerator *luax_checkrandomgenerator(lua_State *L, int idx); +int w_RandomGenerator_setSeed(lua_State *L); +int w_RandomGenerator_getSeed(lua_State *L); +int w_RandomGenerator_random(lua_State *L); +int w_RandomGenerator_randomNormal(lua_State *L); +extern "C" int luaopen_randomgenerator(lua_State *L); + +} // math +} // love + +#endif // LOVE_MATH_WRAP_RANDOM_GENERATOR_H diff --git a/src/modules/mouse/Cursor.cpp b/src/modules/mouse/Cursor.cpp new file mode 100644 index 000000000..e1a0d717b --- /dev/null +++ b/src/modules/mouse/Cursor.cpp @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "Cursor.h" + +namespace love +{ +namespace mouse +{ + +Cursor::~Cursor() +{ +} + +bool Cursor::getConstant(const char *in, SystemCursor &out) +{ + return systemCursors.find(in, out); +} + +bool Cursor::getConstant(SystemCursor in, const char *&out) +{ + return systemCursors.find(in, out); +} + +bool Cursor::getConstant(const char *in, CursorType &out) +{ + return types.find(in, out); +} + +bool Cursor::getConstant(CursorType in, const char *&out) +{ + return types.find(in, out); +} + +StringMap::Entry Cursor::systemCursorEntries[] = +{ + {"arrow", Cursor::CURSOR_ARROW}, + {"ibeam", Cursor::CURSOR_IBEAM}, + {"wait", Cursor::CURSOR_WAIT}, + {"crosshair", Cursor::CURSOR_CROSSHAIR}, + {"waitarrow", Cursor::CURSOR_WAITARROW}, + {"sizenwse", Cursor::CURSOR_SIZENWSE}, + {"sizenesw", Cursor::CURSOR_SIZENESW}, + {"sizewe", Cursor::CURSOR_SIZEWE}, + {"sizens", Cursor::CURSOR_SIZENS}, + {"sizeall", Cursor::CURSOR_SIZEALL}, + {"no", Cursor::CURSOR_NO}, + {"hand", Cursor::CURSOR_HAND}, +}; + +StringMap Cursor::systemCursors(Cursor::systemCursorEntries, sizeof(Cursor::systemCursorEntries)); + +StringMap::Entry Cursor::typeEntries[] = +{ + {"system", Cursor::CURSORTYPE_SYSTEM}, + {"image", Cursor::CURSORTYPE_IMAGE}, +}; + +StringMap Cursor::types(Cursor::typeEntries, sizeof(Cursor::typeEntries)); + +} // mouse +} // love diff --git a/src/modules/mouse/Cursor.h b/src/modules/mouse/Cursor.h new file mode 100644 index 000000000..08f2f17f6 --- /dev/null +++ b/src/modules/mouse/Cursor.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MOUSE_CURSOR_H +#define LOVE_MOUSE_CURSOR_H + +// LOVE +#include "image/ImageData.h" +#include "common/Object.h" +#include "common/StringMap.h" + +namespace love +{ +namespace mouse +{ + +class Cursor : public Object +{ +public: + + // Types of system cursors. + enum SystemCursor + { + CURSOR_ARROW, + CURSOR_IBEAM, + CURSOR_WAIT, + CURSOR_CROSSHAIR, + CURSOR_WAITARROW, + CURSOR_SIZENWSE, + CURSOR_SIZENESW, + CURSOR_SIZEWE, + CURSOR_SIZENS, + CURSOR_SIZEALL, + CURSOR_NO, + CURSOR_HAND, + CURSOR_MAX_ENUM + }; + + enum CursorType + { + CURSORTYPE_SYSTEM, + CURSORTYPE_IMAGE, + CURSORTYPE_MAX_ENUM + }; + + virtual ~Cursor(); + + /** + * Returns a pointer to the implementation-dependent handle of this Cursor. + **/ + virtual void *getHandle() const = 0; + + /** + * Returns whether this Cursor is system-defined or a custom image. + **/ + virtual CursorType getType() const = 0; + + /** + * Returns the type type of system cursor used, if this Cursor is using a + * system-defined image. + **/ + virtual SystemCursor getSystemType() const = 0; + + static bool getConstant(const char *in, SystemCursor &out); + static bool getConstant(SystemCursor in, const char *&out); + + static bool getConstant(const char *in, CursorType &out); + static bool getConstant(CursorType in, const char *&out); + +private: + + static StringMap::Entry systemCursorEntries[]; + static StringMap systemCursors; + + static StringMap::Entry typeEntries[]; + static StringMap types; + +}; + +} // mouse +} // love + +#endif // LOVE_MOUSE_CURSOR_H diff --git a/src/modules/mouse/Mouse.cpp b/src/modules/mouse/Mouse.cpp index 1924276c2..10db0ecd9 100644 --- a/src/modules/mouse/Mouse.cpp +++ b/src/modules/mouse/Mouse.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/mouse/Mouse.h b/src/modules/mouse/Mouse.h index 7a7aef99d..3a178fd4d 100644 --- a/src/modules/mouse/Mouse.h +++ b/src/modules/mouse/Mouse.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,8 +22,10 @@ #define LOVE_MOUSE_MOUSE_H // LOVE +#include "Cursor.h" #include "common/Module.h" #include "common/StringMap.h" +#include "image/ImageData.h" namespace love { @@ -40,15 +42,23 @@ public: BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT, - BUTTON_WHEELUP, - BUTTON_WHEELDOWN, BUTTON_X1, BUTTON_X2, + BUTTON_WHEELUP, + BUTTON_WHEELDOWN, BUTTON_MAX_ENUM }; virtual ~Mouse() {}; + virtual Cursor *newCursor(love::image::ImageData *data, int hotx, int hoty) = 0; + virtual Cursor *getSystemCursor(Cursor::SystemCursor cursortype) = 0; + + virtual void setCursor(Cursor *cursor) = 0; + virtual void setCursor() = 0; + + virtual Cursor *getCursor() const = 0; + virtual int getX() const = 0; virtual int getY() const = 0; virtual void getPosition(int &x, int &y) const = 0; @@ -58,7 +68,7 @@ public: virtual void setVisible(bool visible) = 0; virtual bool isDown(Button *buttonlist) const = 0; virtual bool isVisible() const = 0; - virtual void setGrab(bool grab) = 0; + virtual void setGrabbed(bool grab) = 0; virtual bool isGrabbed() const = 0; static bool getConstant(const char *in, Button &out); diff --git a/src/modules/mouse/sdl/Cursor.cpp b/src/modules/mouse/sdl/Cursor.cpp new file mode 100644 index 000000000..37dea9fb8 --- /dev/null +++ b/src/modules/mouse/sdl/Cursor.cpp @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2006-2014 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 "Cursor.h" +#include "common/config.h" + +namespace love +{ +namespace mouse +{ +namespace sdl +{ + +Cursor::Cursor(image::ImageData *data, int hotx, int hoty) + : cursor(0) + , type(CURSORTYPE_IMAGE) + , systemType(CURSOR_MAX_ENUM) +{ + Uint32 rmask, gmask, bmask, amask; +#ifdef LOVE_BIG_ENDIAN + rmask = 0xFF000000; + gmask = 0x00FF0000; + bmask = 0x0000FF00; + amask = 0x000000FF; +#else + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0xFF000000; +#endif + + int w = data->getWidth(); + int h = data->getHeight(); + int pitch = w * 4; + + SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(data->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask); + if (!surface) + throw love::Exception("Cannot create cursor: out of memory!"); + + cursor = SDL_CreateColorCursor(surface, hotx, hoty); + SDL_FreeSurface(surface); + + if (!cursor) + throw love::Exception("Cannot create cursor: %s", SDL_GetError()); +} + +Cursor::Cursor(mouse::Cursor::SystemCursor cursortype) + : cursor(0) + , type(CURSORTYPE_SYSTEM) + , systemType(cursortype) +{ + SDL_SystemCursor sdlcursortype; + + if (systemCursors.find(cursortype, sdlcursortype)) + cursor = SDL_CreateSystemCursor(sdlcursortype); + else + throw love::Exception("Cannot create system cursor: invalid type."); + + if (!cursor) + throw love::Exception("Cannot create system cursor: %s", SDL_GetError()); +} + +Cursor::~Cursor() +{ + if (cursor) + SDL_FreeCursor(cursor); +} + +void *Cursor::getHandle() const +{ + return cursor; +} + +Cursor::CursorType Cursor::getType() const +{ + return type; +} + +Cursor::SystemCursor Cursor::getSystemType() const +{ + return systemType; +} + +EnumMap::Entry Cursor::systemCursorEntries[] = +{ + {Cursor::CURSOR_ARROW, SDL_SYSTEM_CURSOR_ARROW}, + {Cursor::CURSOR_IBEAM, SDL_SYSTEM_CURSOR_IBEAM}, + {Cursor::CURSOR_WAIT, SDL_SYSTEM_CURSOR_WAIT}, + {Cursor::CURSOR_CROSSHAIR, SDL_SYSTEM_CURSOR_CROSSHAIR}, + {Cursor::CURSOR_WAITARROW, SDL_SYSTEM_CURSOR_WAITARROW}, + {Cursor::CURSOR_SIZENWSE, SDL_SYSTEM_CURSOR_SIZENWSE}, + {Cursor::CURSOR_SIZENESW, SDL_SYSTEM_CURSOR_SIZENESW}, + {Cursor::CURSOR_SIZEWE, SDL_SYSTEM_CURSOR_SIZEWE}, + {Cursor::CURSOR_SIZENS, SDL_SYSTEM_CURSOR_SIZENS}, + {Cursor::CURSOR_SIZEALL, SDL_SYSTEM_CURSOR_SIZEALL}, + {Cursor::CURSOR_NO, SDL_SYSTEM_CURSOR_NO}, + {Cursor::CURSOR_HAND, SDL_SYSTEM_CURSOR_HAND}, +}; + +EnumMap Cursor::systemCursors(Cursor::systemCursorEntries, sizeof(Cursor::systemCursorEntries)); + +} // sdl +} // mouse +} // love diff --git a/src/modules/mouse/sdl/Cursor.h b/src/modules/mouse/sdl/Cursor.h new file mode 100644 index 000000000..de2d89da9 --- /dev/null +++ b/src/modules/mouse/sdl/Cursor.h @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_MOUSE_SDL_CURSOR_H +#define LOVE_MOUSE_SDL_CURSOR_H + +// LOVE +#include "mouse/Cursor.h" +#include "common/EnumMap.h" + +// SDL +#include + +namespace love +{ +namespace mouse +{ +namespace sdl +{ + +class Cursor : public love::mouse::Cursor +{ +public: + + Cursor(image::ImageData *imageData, int hotx, int hoty); + Cursor(SystemCursor cursortype); + ~Cursor(); + + void *getHandle() const; + CursorType getType() const; + SystemCursor getSystemType() const; + +private: + + SDL_Cursor *cursor; + CursorType type; + SystemCursor systemType; + + static EnumMap::Entry systemCursorEntries[]; + static EnumMap systemCursors; +}; + +} // sdl +} // mouse +} // love + +#endif // LOVE_MOUSE_SDL_CURSOR_H diff --git a/src/modules/mouse/sdl/Mouse.cpp b/src/modules/mouse/sdl/Mouse.cpp index 5ea238804..94b187a7a 100644 --- a/src/modules/mouse/sdl/Mouse.cpp +++ b/src/modules/mouse/sdl/Mouse.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,10 +18,12 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "Mouse.h" +#include "window/sdl/Window.h" // SDL -#include +#include namespace love { @@ -35,6 +37,64 @@ const char *Mouse::getName() const return "love.mouse.sdl"; } +Mouse::Mouse() + : curCursor(0) +{ +} + +Mouse::~Mouse() +{ + if (curCursor) + setCursor(); + + for (auto it = systemCursors.begin(); it != systemCursors.end(); ++it) + it->second->release(); +} + +love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, int hoty) +{ + return new Cursor(data, hotx, hoty); +} + +love::mouse::Cursor *Mouse::getSystemCursor(Cursor::SystemCursor cursortype) +{ + Cursor *cursor = NULL; + auto it = systemCursors.find(cursortype); + + if (it != systemCursors.end()) + cursor = it->second; + else + { + cursor = new Cursor(cursortype); + systemCursors[cursortype] = cursor; + } + + return cursor; +} + +void Mouse::setCursor(love::mouse::Cursor *cursor) +{ + Object::AutoRelease cursorrelease(curCursor); + + curCursor = cursor; + curCursor->retain(); + + SDL_SetCursor((SDL_Cursor *) cursor->getHandle()); +} + +void Mouse::setCursor() +{ + Object::AutoRelease cursorrelease(curCursor); + curCursor = NULL; + + SDL_SetCursor(SDL_GetDefaultCursor()); +} + +love::mouse::Cursor *Mouse::getCursor() const +{ + return curCursor; +} + int Mouse::getX() const { int x; @@ -56,7 +116,13 @@ void Mouse::getPosition(int &x, int &y) const void Mouse::setPosition(int x, int y) { - SDL_WarpMouse(x, y); + love::window::Window *window = love::window::sdl::Window::getSingleton(); + + SDL_Window *handle = NULL; + if (window) + handle = (SDL_Window *) window->getHandle(); + + SDL_WarpMouseInWindow(handle, x, y); } void Mouse::setX(int x) @@ -78,7 +144,7 @@ void Mouse::setVisible(bool visible) bool Mouse::isDown(Button *buttonlist) const { - Uint8 buttonstate = SDL_GetMouseState(0, 0); + Uint32 buttonstate = SDL_GetMouseState(0, 0); for (Button button = *buttonlist; button != BUTTON_MAX_ENUM; button = *(++buttonlist)) { @@ -91,17 +157,23 @@ bool Mouse::isDown(Button *buttonlist) const bool Mouse::isVisible() const { - return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) ? true : false; + return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE; } -void Mouse::setGrab(bool grab) +void Mouse::setGrabbed(bool grab) { - SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF); + love::window::Window *window = love::window::sdl::Window::getSingleton(); + if (window) + window->setMouseGrab(grab); } bool Mouse::isGrabbed() const { - return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON ? true : false); + love::window::Window *window = love::window::sdl::Window::getSingleton(); + if (window) + return window->isMouseGrabbed(); + else + return false; } } // sdl diff --git a/src/modules/mouse/sdl/Mouse.h b/src/modules/mouse/sdl/Mouse.h index 8d23937d9..43b8dad61 100644 --- a/src/modules/mouse/sdl/Mouse.h +++ b/src/modules/mouse/sdl/Mouse.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -23,6 +23,10 @@ // LOVE #include "mouse/Mouse.h" +#include "Cursor.h" + +// C++ +#include namespace love { @@ -38,6 +42,17 @@ public: // Implements Module. const char *getName() const; + Mouse(); + ~Mouse(); + + love::mouse::Cursor *newCursor(love::image::ImageData *data, int hotx, int hoty); + love::mouse::Cursor *getSystemCursor(Cursor::SystemCursor cursortype); + + void setCursor(love::mouse::Cursor *cursor); + void setCursor(); + + love::mouse::Cursor *getCursor() const; + int getX() const; int getY() const; void getPosition(int &x, int &y) const; @@ -47,8 +62,15 @@ public: void setVisible(bool visible); bool isDown(Button *buttonlist) const; bool isVisible() const; - void setGrab(bool grab); + void setGrabbed(bool grab); bool isGrabbed() const; + +private: + + love::mouse::Cursor *curCursor; + + std::map systemCursors; + }; // Mouse } // sdl diff --git a/src/modules/mouse/wrap_Cursor.cpp b/src/modules/mouse/wrap_Cursor.cpp new file mode 100644 index 000000000..9e0702937 --- /dev/null +++ b/src/modules/mouse/wrap_Cursor.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2006-2014 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 "wrap_Cursor.h" + +namespace love +{ +namespace mouse +{ + +Cursor *luax_checkcursor(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "Cursor", MOUSE_CURSOR_T); +} + +int w_Cursor_getType(lua_State *L) +{ + Cursor *cursor = luax_checkcursor(L, 1); + + Cursor::CursorType ctype = cursor->getType(); + const char *typestr = 0; + + if (ctype == Cursor::CURSORTYPE_IMAGE) + mouse::Cursor::getConstant(ctype, typestr); + else if (ctype == Cursor::CURSORTYPE_SYSTEM) + { + Cursor::SystemCursor systype = cursor->getSystemType(); + mouse::Cursor::getConstant(systype, typestr); + } + + if (!typestr) + return luaL_error(L, "Unknown cursor type."); + + lua_pushstring(L, typestr); + return 1; +}; + +static const luaL_Reg functions[] = +{ + { "getType", w_Cursor_getType }, + { 0, 0 }, +}; + +extern "C" int luaopen_cursor(lua_State *L) +{ + return luax_register_type(L, "Cursor", functions); +} + +} // mouse +} // love \ No newline at end of file diff --git a/src/modules/graphics/DrawQable.cpp b/src/modules/mouse/wrap_Cursor.h similarity index 71% rename from src/modules/graphics/DrawQable.cpp rename to src/modules/mouse/wrap_Cursor.h index a58a61291..a1cfaa0fa 100644 --- a/src/modules/graphics/DrawQable.cpp +++ b/src/modules/mouse/wrap_Cursor.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,16 +18,24 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "DrawQable.h" +#ifndef LOVE_MOUSE_WRAP_CURSOR_H +#define LOVE_MOUSE_WRAP_CURSOR_H + +// LOVE +#include "common/runtime.h" +#include "Cursor.h" namespace love { -namespace graphics +namespace mouse { -DrawQable::~DrawQable() -{ -} +Cursor *luax_checkcursor(lua_State *L, int idx); +int w_Cursor_getType(lua_State *L); +extern "C" int luaopen_cursor(lua_State *L); -} // graphics +} // mouse } // love + + +#endif // LOVE_MOUSE_WRAP_CURSOR_H diff --git a/src/modules/mouse/wrap_Mouse.cpp b/src/modules/mouse/wrap_Mouse.cpp index 3967d5551..1ba9b2bc0 100644 --- a/src/modules/mouse/wrap_Mouse.cpp +++ b/src/modules/mouse/wrap_Mouse.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,12 +18,13 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE +#include "wrap_Mouse.h" +#include "wrap_Cursor.h" #include "common/config.h" #include "sdl/Mouse.h" -#include "wrap_Mouse.h" - namespace love { namespace mouse @@ -31,6 +32,68 @@ namespace mouse static Mouse *instance = 0; +int w_newCursor(lua_State *L) +{ + Cursor *cursor = 0; + + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T) || luax_istype(L, 1, FILESYSTEM_FILE_DATA_T)) + luax_convobj(L, 1, "image", "newImageData"); + + love::image::ImageData *data = luax_checktype(L, 1, "ImageData", IMAGE_IMAGE_DATA_T); + int hotx = luaL_optint(L, 2, 0); + int hoty = luaL_optint(L, 3, 0); + + EXCEPT_GUARD(cursor = instance->newCursor(data, hotx, hoty);) + + luax_pushtype(L, "Cursor", MOUSE_CURSOR_T, cursor); + return 1; +} + +int w_getSystemCursor(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + Cursor::SystemCursor systemCursor; + + if (!Cursor::getConstant(str, systemCursor)) + return luaL_error(L, "Invalid system cursor type: %s", str); + + Cursor *cursor = 0; + EXCEPT_GUARD(cursor = instance->getSystemCursor(systemCursor);) + + cursor->retain(); + luax_pushtype(L, "Cursor", MOUSE_CURSOR_T, cursor); + return 1; +} + +int w_setCursor(lua_State *L) +{ + // Revert to the default system cursor if no argument is given. + if (lua_isnoneornil(L, 1)) + { + instance->setCursor(); + return 0; + } + + Cursor *cursor = luax_checkcursor(L, 1); + instance->setCursor(cursor); + return 0; +} + +int w_getCursor(lua_State *L) +{ + Cursor *cursor = instance->getCursor(); + + if (cursor) + { + cursor->retain(); + luax_pushtype(L, "Cursor", MOUSE_CURSOR_T, cursor); + } + else + lua_pushnil(L); + + return 1; +} + int w_getX(lua_State *L) { lua_pushnumber(L, instance->getX()); @@ -106,10 +169,10 @@ int w_isVisible(lua_State *L) return 1; } -int w_setGrab(lua_State *L) +int w_setGrabbed(lua_State *L) { bool b = luax_toboolean(L, 1); - instance->setGrab(b); + instance->setGrabbed(b); return 0; } @@ -122,6 +185,10 @@ int w_isGrabbed(lua_State *L) // List of functions to wrap. static const luaL_Reg functions[] = { + { "newCursor", w_newCursor }, + { "getSystemCursor", w_getSystemCursor }, + { "setCursor", w_setCursor }, + { "getCursor", w_getCursor }, { "getX", w_getX }, { "getY", w_getY }, { "setX", w_setX }, @@ -131,23 +198,23 @@ static const luaL_Reg functions[] = { "setVisible", w_setVisible }, { "isVisible", w_isVisible }, { "getPosition", w_getPosition }, - { "setGrab", w_setGrab }, + { "setGrabbed", w_setGrabbed }, { "isGrabbed", w_isGrabbed }, { 0, 0 } }; +// Types for this module. +static const lua_CFunction types[] = +{ + luaopen_cursor, + 0, +}; + extern "C" int luaopen_love_mouse(lua_State *L) { if (instance == 0) { - try - { - instance = new love::mouse::sdl::Mouse(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new love::mouse::sdl::Mouse();) } else instance->retain(); @@ -157,7 +224,7 @@ extern "C" int luaopen_love_mouse(lua_State *L) w.name = "mouse"; w.flags = MODULE_T; w.functions = functions; - w.types = 0; + w.types = types; return luax_register_module(L, w); } diff --git a/src/modules/mouse/wrap_Mouse.h b/src/modules/mouse/wrap_Mouse.h index 7310e4b8b..0d1242f00 100644 --- a/src/modules/mouse/wrap_Mouse.h +++ b/src/modules/mouse/wrap_Mouse.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,13 +22,18 @@ #define LOVE_MOUSE_WRAP_MOUSE_H // LOVE -#include "Mouse.h" +#include "common/runtime.h" +#include "common/config.h" namespace love { namespace mouse { +int w_newCursor(lua_State *L); +int w_getSystemCursor(lua_State *L); +int w_setCursor(lua_State *L); +int w_getCursor(lua_State *L); int w_getX(lua_State *L); int w_getY(lua_State *L); int w_getPosition(lua_State *L); @@ -38,7 +43,7 @@ int w_setPosition(lua_State *L); int w_isDown(lua_State *L); int w_setVisible(lua_State *L); int w_isVisible(lua_State *L); -int w_setGrap(lua_State *L); +int w_setGrabbed(lua_State *L); int w_isGrabbed(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_mouse(lua_State *L); diff --git a/src/modules/physics/Body.cpp b/src/modules/physics/Body.cpp index 9b715f7b1..22bbb5d2c 100644 --- a/src/modules/physics/Body.cpp +++ b/src/modules/physics/Body.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/Body.h b/src/modules/physics/Body.h index ec9cdf691..1f5a4c7d4 100644 --- a/src/modules/physics/Body.h +++ b/src/modules/physics/Body.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/Joint.cpp b/src/modules/physics/Joint.cpp index 5df7c079e..e04eff112 100644 --- a/src/modules/physics/Joint.cpp +++ b/src/modules/physics/Joint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -51,6 +51,7 @@ StringMap::Entry Joint::typeEntries[] = {"weld", Joint::JOINT_WELD}, {"wheel", Joint::JOINT_WHEEL}, {"rope", Joint::JOINT_ROPE}, + {"motor", Joint::JOINT_MOTOR}, }; StringMap Joint::types(Joint::typeEntries, sizeof(Joint::typeEntries)); diff --git a/src/modules/physics/Joint.h b/src/modules/physics/Joint.h index c0155e64c..9ab80c215 100644 --- a/src/modules/physics/Joint.h +++ b/src/modules/physics/Joint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -47,6 +47,7 @@ public: JOINT_WELD, JOINT_WHEEL, JOINT_ROPE, + JOINT_MOTOR, JOINT_MAX_ENUM }; diff --git a/src/modules/physics/Shape.cpp b/src/modules/physics/Shape.cpp index d250109d3..bbb81b372 100644 --- a/src/modules/physics/Shape.cpp +++ b/src/modules/physics/Shape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/Shape.h b/src/modules/physics/Shape.h index 498deef38..5eb3e42e4 100644 --- a/src/modules/physics/Shape.h +++ b/src/modules/physics/Shape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index 1783ed73c..72565658c 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -168,36 +168,36 @@ Body::Type Body::getType() const } } -void Body::applyLinearImpulse(float jx, float jy) +void Body::applyLinearImpulse(float jx, float jy, bool wake) { - body->ApplyLinearImpulse(Physics::scaleDown(b2Vec2(jx, jy)), body->GetWorldCenter()); + body->ApplyLinearImpulse(Physics::scaleDown(b2Vec2(jx, jy)), body->GetWorldCenter(), wake); } -void Body::applyLinearImpulse(float jx, float jy, float rx, float ry) +void Body::applyLinearImpulse(float jx, float jy, float rx, float ry, bool wake) { - body->ApplyLinearImpulse(Physics::scaleDown(b2Vec2(jx, jy)), Physics::scaleDown(b2Vec2(rx, ry))); + body->ApplyLinearImpulse(Physics::scaleDown(b2Vec2(jx, jy)), Physics::scaleDown(b2Vec2(rx, ry)), wake); } -void Body::applyAngularImpulse(float impulse) +void Body::applyAngularImpulse(float impulse, bool wake) { // Angular impulse is in kg*m^2/s, meaning it needs to be scaled twice - body->ApplyAngularImpulse(Physics::scaleDown(Physics::scaleDown(impulse))); + body->ApplyAngularImpulse(Physics::scaleDown(Physics::scaleDown(impulse)), wake); } -void Body::applyTorque(float t) +void Body::applyTorque(float t, bool wake) { // Torque is in N*m, or kg*m^2/s^2, meaning it also needs to be scaled twice - body->ApplyTorque(Physics::scaleDown(Physics::scaleDown(t))); + body->ApplyTorque(Physics::scaleDown(Physics::scaleDown(t)), wake); } -void Body::applyForce(float fx, float fy, float rx, float ry) +void Body::applyForce(float fx, float fy, float rx, float ry, bool wake) { - body->ApplyForce(Physics::scaleDown(b2Vec2(fx, fy)), Physics::scaleDown(b2Vec2(rx, ry))); + body->ApplyForce(Physics::scaleDown(b2Vec2(fx, fy)), Physics::scaleDown(b2Vec2(rx, ry)), wake); } -void Body::applyForce(float fx, float fy) +void Body::applyForce(float fx, float fy, bool wake) { - body->ApplyForceToCenter(Physics::scaleDown(b2Vec2(fx, fy))); + body->ApplyForceToCenter(Physics::scaleDown(b2Vec2(fx, fy)), wake); } void Body::setX(float x) @@ -428,7 +428,7 @@ int Body::getFixtureList(lua_State *L) const if (!fixture) throw love::Exception("A fixture has escaped Memoizer!"); fixture->retain(); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)fixture); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, fixture); lua_rawseti(L, -2, i); i++; } diff --git a/src/modules/physics/box2d/Body.h b/src/modules/physics/box2d/Body.h index 69e6a66ba..30cd1229b 100644 --- a/src/modules/physics/box2d/Body.h +++ b/src/modules/physics/box2d/Body.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -91,29 +91,31 @@ public: /** * Gets the current position of the Body. - * @returns The current position. + * @param[out] x_o The x-component of the position. + * @param[out] y_o The y-component of the position. **/ void getPosition(float &x_o, float &y_o); /** * Gets the velocity in the current center of mass. - * @returns The velocity in the current center of mass. + * @param[out] x_o The x-component of the velocity. + * @param[out] y_o The y-component of the velocity. **/ void getLinearVelocity(float &x_o, float &y_o); /** * The current center of mass for the Body in world * coordinates. - * @returns The x-component of the point. - * @returns The y-component of the point. + * @param[out] x_o The x-component of the center of mass. + * @param[out] y_o The y-component of the center of mass. **/ void getWorldCenter(float &x_o, float &y_o); /** * The current center of mass for the Body in local * coordinates. - * @returns The x-component of the point. - * @returns The y-component of the point. + * @param[out] x_o The x-component of the center of mass. + * @param[out] y_o The y-component of the center of mass. **/ void getLocalCenter(float &x_o, float &y_o); @@ -160,32 +162,32 @@ public: /** * Apply an impulse (jx, jy) with offset (0, 0). **/ - void applyLinearImpulse(float jx, float jy); + void applyLinearImpulse(float jx, float jy, bool wake); /** * Apply an impulse (jx, jy) with offset (rx, ry). **/ - void applyLinearImpulse(float jx, float jy, float rx, float ry); + void applyLinearImpulse(float jx, float jy, float rx, float ry, bool wake); /** * Apply an angular impulse to the body. **/ - void applyAngularImpulse(float impulse); + void applyAngularImpulse(float impulse, bool wake); /** * Apply torque (t). **/ - void applyTorque(float t); + void applyTorque(float t, bool wake); /** * Apply force (fx, fy) with offset (0, 0). **/ - void applyForce(float fx, float fy); + void applyForce(float fx, float fy, bool wake); /** * Apply force (fx, fy) with offset (rx, ry). **/ - void applyForce(float fx, float fy, float rx, float ry); + void applyForce(float fx, float fy, float rx, float ry, bool wake); /** * Sets the x-position of the Body. @@ -269,8 +271,8 @@ public: * to world coordinates. * @param x The x-coordinate of the local point. * @param y The y-coordinate of the local point. - * @returns The x-coordinate of the point in world coordinates. - * @returns The y-coordinate of the point in world coordinates. + * @param[out] x_o The x-coordinate of the point in world coordinates. + * @param[out] y_o The y-coordinate of the point in world coordinates. **/ void getWorldPoint(float x, float y, float &x_o, float &y_o); @@ -279,8 +281,8 @@ public: * to world coordinates. * @param x The x-coordinate of the local vector. * @param y The y-coordinate of the local vector. - * @returns The x-coordinate of the vector in world coordinates. - * @returns The y-coordinate of the vector in world coordinates. + * @param[out] x_o The x-coordinate of the vector in world coordinates. + * @param[out] y_o The y-coordinate of the vector in world coordinates. **/ void getWorldVector(float x, float y, float &x_o, float &y_o); @@ -295,8 +297,8 @@ public: * to local coordinates. * @param x The x-coordinate of the world point. * @param y The y-coordinate of the world point. - * @returns The x-coordinate of the point in local coordinates. - * @returns The y-coordinate of the point in local coordinates. + * @param[out] x_o The x-coordinate of the point in local coordinates. + * @param[out] y_o The y-coordinate of the point in local coordinates. **/ void getLocalPoint(float x, float y, float &x_o, float &y_o); @@ -305,8 +307,8 @@ public: * to local coordinates. * @param x The x-coordinate of the world vector. * @param y The y-coordinate of the world vector. - * @returns The x-coordinate of the vector in local coordinates. - * @returns The y-coordinate of the vector in local coordinates. + * @param[out] x_o The x-coordinate of the vector in local coordinates. + * @param[out] y_o The y-coordinate of the vector in local coordinates. **/ void getLocalVector(float x, float y, float &x_o, float &y_o); @@ -314,8 +316,8 @@ public: * Gets the velocity on the Body for the given world point. * @param x The x-coordinate of the world point. * @param y The y-coordinate of the world point. - * @returns The x-component of the velocity vector. - * @returns The y-component of the velocity vector. + * @param[out] x_o The x-component of the velocity vector. + * @param[out] y_o The y-component of the velocity vector. **/ void getLinearVelocityFromWorldPoint(float x, float y, float &x_o, float &y_o); @@ -323,8 +325,8 @@ public: * Gets the velocity on the Body for the given local point. * @param x The x-coordinate of the local point. * @param y The y-coordinate of the local point. - * @returns The x-component of the velocity vector. - * @returns The y-component of the velocity vector. + * @param[out] x_o The x-component of the velocity vector. + * @param[out] y_o The y-component of the velocity vector. **/ void getLinearVelocityFromLocalPoint(float x, float y, float &x_o, float &y_o); diff --git a/src/modules/physics/box2d/ChainShape.cpp b/src/modules/physics/box2d/ChainShape.cpp index 6972e0a19..0ea60d033 100644 --- a/src/modules/physics/box2d/ChainShape.cpp +++ b/src/modules/physics/box2d/ChainShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -55,11 +55,11 @@ void ChainShape::setNextVertex(float x, float y) c->SetNextVertex(Physics::scaleDown(v)); } -void ChainShape::setPrevVertex(float x, float y) +void ChainShape::setPreviousVertex(float x, float y) { if (loop) { - throw love::Exception("Physics error: Can't call setPrevVertex on a loop ChainShape"); + throw love::Exception("Physics error: Can't call setPreviousVertex on a loop ChainShape"); return; } b2Vec2 v(x, y); @@ -70,16 +70,19 @@ void ChainShape::setPrevVertex(float x, float y) EdgeShape *ChainShape::getChildEdge(int index) const { b2ChainShape *c = (b2ChainShape *)shape; - b2EdgeShape e; - c->GetChildEdge(&e, index); - EdgeShape *edge = (EdgeShape *)Memoizer::find(&e); - if (!edge) - return new EdgeShape(&e); - else + b2EdgeShape *e = new b2EdgeShape; + + try { - edge->retain(); - return edge; + c->GetChildEdge(e, index); } + catch (love::Exception &ex) + { + delete e; + throw; + } + + return new EdgeShape(e, true); } int ChainShape::getChildCount() const diff --git a/src/modules/physics/box2d/ChainShape.h b/src/modules/physics/box2d/ChainShape.h index ffa51ef9c..52bb6673d 100644 --- a/src/modules/physics/box2d/ChainShape.h +++ b/src/modules/physics/box2d/ChainShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -61,7 +61,7 @@ public: * @param x The x-coordinate of the vertex. * @param y The y-coordinate of the vertex. **/ - void setPrevVertex(float x, float y); + void setPreviousVertex(float x, float y); /** * Gets the number of children shapes. diff --git a/src/modules/physics/box2d/CircleShape.cpp b/src/modules/physics/box2d/CircleShape.cpp index f93b3809d..97d4c5e56 100644 --- a/src/modules/physics/box2d/CircleShape.cpp +++ b/src/modules/physics/box2d/CircleShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -53,6 +53,19 @@ void CircleShape::setRadius(float r) shape->m_radius = Physics::scaleDown(r); } +void CircleShape::getPoint(float &x_o, float &y_o) const +{ + b2CircleShape *c = (b2CircleShape *) shape; + x_o = Physics::scaleUp(c->m_p.x); + y_o = Physics::scaleUp(c->m_p.y); +} + +void CircleShape::setPoint(float x, float y) +{ + b2CircleShape *c = (b2CircleShape *) shape; + c->m_p = Physics::scaleDown(b2Vec2(x, y)); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/CircleShape.h b/src/modules/physics/box2d/CircleShape.h index 34190fe28..68bf70d83 100644 --- a/src/modules/physics/box2d/CircleShape.h +++ b/src/modules/physics/box2d/CircleShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -45,10 +45,8 @@ class CircleShape : public Shape public: /** - * Create a new CircleShape from the parent body and a - * Box2D CircleShape definition. - * @param body The parent body. - * @param def The CircleShape definition. + * Create a new CircleShape from the a Box2D CircleShape definition. + * @param c The CircleShape definition. **/ CircleShape(b2CircleShape *c, bool own = true); @@ -60,10 +58,21 @@ public: float getRadius() const; /** - * Sets the radius for the circle. + * Sets the radius of the circle. **/ void setRadius(float r); -}; + + /** + * Gets the position of the circle. + **/ + void getPoint(float &x_o, float &y_o) const; + + /** + * Sets the position for the circle. + **/ + void setPoint(float x, float y); + +}; // CircleShape } // box2d } // physics diff --git a/src/modules/physics/box2d/Contact.cpp b/src/modules/physics/box2d/Contact.cpp index b5fc966e9..2142bb487 100644 --- a/src/modules/physics/box2d/Contact.cpp +++ b/src/modules/physics/box2d/Contact.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -126,6 +126,22 @@ void Contact::resetRestitution() contact->ResetRestitution(); } +void Contact::setTangentSpeed(float speed) +{ + contact->SetTangentSpeed(speed); +} + +float Contact::getTangentSpeed() const +{ + return contact->GetTangentSpeed(); +} + +void Contact::getChildren(int &childA, int &childB) +{ + childA = contact->GetChildIndexA(); + childB = contact->GetChildIndexB(); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/Contact.h b/src/modules/physics/box2d/Contact.h index 0c1a92440..1222a3681 100644 --- a/src/modules/physics/box2d/Contact.h +++ b/src/modules/physics/box2d/Contact.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -53,7 +53,7 @@ public: * Creates a new Contact by copying a Box2D contact * point. It does not store the pointer, but copy the * data pointed to. - * @param point Pointer to the Box2D contact. + * @param contact Pointer to the Box2D contact. **/ Contact(b2Contact *contact); @@ -136,6 +136,18 @@ public: **/ void resetRestitution(); + /** + * Set the desired tangent speed. + **/ + void setTangentSpeed(float speed); + + /** + * Get the desired tangent speed. + **/ + float getTangentSpeed() const; + + void getChildren(int &childA, int &childB); + private: // The Box2D contact. diff --git a/src/modules/physics/box2d/DistanceJoint.cpp b/src/modules/physics/box2d/DistanceJoint.cpp index 2f73ea9a4..0f6d6262a 100644 --- a/src/modules/physics/box2d/DistanceJoint.cpp +++ b/src/modules/physics/box2d/DistanceJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/DistanceJoint.h b/src/modules/physics/box2d/DistanceJoint.h index 9b49f7d2d..c87ef982b 100644 --- a/src/modules/physics/box2d/DistanceJoint.h +++ b/src/modules/physics/box2d/DistanceJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp index f120ee987..9272042aa 100644 --- a/src/modules/physics/box2d/EdgeShape.cpp +++ b/src/modules/physics/box2d/EdgeShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/EdgeShape.h b/src/modules/physics/box2d/EdgeShape.h index ffebe7454..a006a4e47 100644 --- a/src/modules/physics/box2d/EdgeShape.h +++ b/src/modules/physics/box2d/EdgeShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Fixture.cpp b/src/modules/physics/box2d/Fixture.cpp index 68cbd9592..f133bac62 100644 --- a/src/modules/physics/box2d/Fixture.cpp +++ b/src/modules/physics/box2d/Fixture.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -76,7 +76,7 @@ Fixture::~Fixture() Shape::Type Fixture::getType() const { - return Shape(fixture->GetShape()).getType(); + return Shape(fixture->GetShape(), false).getType(); } void Fixture::setFriction(float friction) @@ -140,18 +140,18 @@ bool Fixture::isValid() const void Fixture::setFilterData(int *v) { b2Filter f; - f.categoryBits = (unsigned short)v[0]; - f.maskBits = (unsigned short)v[1]; - f.groupIndex = v[2]; + f.categoryBits = (uint16) v[0]; + f.maskBits = (uint16) v[1]; + f.groupIndex = (int16) v[2]; fixture->SetFilterData(f); } void Fixture::getFilterData(int *v) { b2Filter f = fixture->GetFilterData(); - v[0] = (int)f.categoryBits; - v[1] = (int)f.maskBits; - v[2] = f.groupIndex; + v[0] = (int) f.categoryBits; + v[1] = (int) f.maskBits; + v[2] = (int) f.groupIndex; } int Fixture::setCategory(lua_State *L) diff --git a/src/modules/physics/box2d/Fixture.h b/src/modules/physics/box2d/Fixture.h index a8d22bf3f..e7f18f942 100644 --- a/src/modules/physics/box2d/Fixture.h +++ b/src/modules/physics/box2d/Fixture.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/FrictionJoint.cpp b/src/modules/physics/box2d/FrictionJoint.cpp index 38e7416c4..7edc04320 100644 --- a/src/modules/physics/box2d/FrictionJoint.cpp +++ b/src/modules/physics/box2d/FrictionJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/FrictionJoint.h b/src/modules/physics/box2d/FrictionJoint.h index d8047dcd6..b2cde0de2 100644 --- a/src/modules/physics/box2d/FrictionJoint.h +++ b/src/modules/physics/box2d/FrictionJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/GearJoint.cpp b/src/modules/physics/box2d/GearJoint.cpp index faa9a7cf8..c2ea845dc 100644 --- a/src/modules/physics/box2d/GearJoint.cpp +++ b/src/modules/physics/box2d/GearJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/GearJoint.h b/src/modules/physics/box2d/GearJoint.h index 167bca0c8..c36cbffb7 100644 --- a/src/modules/physics/box2d/GearJoint.h +++ b/src/modules/physics/box2d/GearJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Joint.cpp b/src/modules/physics/box2d/Joint.cpp index 539a0bc19..5e3ec277f 100644 --- a/src/modules/physics/box2d/Joint.cpp +++ b/src/modules/physics/box2d/Joint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Joint.h b/src/modules/physics/box2d/Joint.h index 14aa0e9af..22622df1d 100644 --- a/src/modules/physics/box2d/Joint.h +++ b/src/modules/physics/box2d/Joint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/MotorJoint.cpp b/src/modules/physics/box2d/MotorJoint.cpp new file mode 100644 index 000000000..74d4006e4 --- /dev/null +++ b/src/modules/physics/box2d/MotorJoint.cpp @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "MotorJoint.h" + +// Module +#include "Body.h" +#include "World.h" +#include "Physics.h" + +namespace love +{ +namespace physics +{ +namespace box2d +{ + +MotorJoint::MotorJoint(Body *body1, Body *body2) + : Joint(body1, body2) + , joint(NULL) +{ + b2MotorJointDef def; + + def.Initialize(body1->body, body2->body); + joint = (b2MotorJoint *) createJoint(&def); +} + +MotorJoint::MotorJoint(Body *body1, Body *body2, float correctionFactor) + : Joint(body1, body2) + , joint(NULL) +{ + b2MotorJointDef def; + + def.Initialize(body1->body, body2->body); + def.correctionFactor = correctionFactor; + + joint = (b2MotorJoint *) createJoint(&def); +} + +MotorJoint::~MotorJoint() +{ +} + +void MotorJoint::setLinearOffset(float x, float y) +{ + joint->SetLinearOffset(Physics::scaleDown(b2Vec2(x, y))); +} + +int MotorJoint::getLinearOffset(lua_State *L) const +{ + lua_pushnumber(L, Physics::scaleUp(joint->GetLinearOffset().x)); + lua_pushnumber(L, Physics::scaleUp(joint->GetLinearOffset().y)); + return 2; +} + +void MotorJoint::setAngularOffset(float angularOffset) +{ + joint->SetAngularOffset(angularOffset); +} + +float MotorJoint::getAngularOffset() const +{ + return joint->GetAngularOffset(); +} + +void MotorJoint::setMaxForce(float force) +{ + joint->SetMaxForce(Physics::scaleDown(force)); +} + +float MotorJoint::getMaxForce() const +{ + return Physics::scaleUp(joint->GetMaxForce()); +} + +void MotorJoint::setMaxTorque(float torque) +{ + joint->SetMaxTorque(Physics::scaleDown(Physics::scaleDown(torque))); +} + +float MotorJoint::getMaxTorque() const +{ + return Physics::scaleUp(Physics::scaleUp(joint->GetMaxTorque())); +} + +void MotorJoint::setCorrectionFactor(float factor) +{ + joint->SetCorrectionFactor(factor); +} + +float MotorJoint::getCorrectionFactor() const +{ + return joint->GetCorrectionFactor(); +} + +} // box2d +} // physics +} // love diff --git a/src/modules/physics/box2d/MotorJoint.h b/src/modules/physics/box2d/MotorJoint.h new file mode 100644 index 000000000..b40626dd6 --- /dev/null +++ b/src/modules/physics/box2d/MotorJoint.h @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_PHYSICS_BOX2D_MOTOR_JOINT_H +#define LOVE_PHYSICS_BOX2D_MOTOR_JOINT_H + +// Module +#include "Joint.h" + +namespace love +{ +namespace physics +{ +namespace box2d +{ + +/** + * A motor joint is used to control the relative motion + * between two bodies. A typical usage is to control the movement + * of a dynamic body with respect to the ground. + */ +class MotorJoint : public Joint +{ +public: + + MotorJoint(Body *body1, Body* body2); + MotorJoint(Body *body1, Body* body2, float correctionFactor); + virtual ~MotorJoint(); + + /// Set/get the target linear offset, in frame A, in meters. + void setLinearOffset(float x, float y); + int getLinearOffset(lua_State *L) const; + + /// Set/get the target angular offset, in radians. + void setAngularOffset(float angularOffset); + float getAngularOffset() const; + + /// Set the maximum friction force. + void setMaxForce(float force); + + /// Get the maximum friction force. + float getMaxForce() const; + + /// Set the maximum friction torque. + void setMaxTorque(float torque); + + /// Get the maximum friction torque. + float getMaxTorque() const; + + /// Set the position correction factor in the range [0,1]. + void setCorrectionFactor(float factor); + + /// Get the position correction factor in the range [0,1]. + float getCorrectionFactor() const; + +private: + + // The Box2D MotorJoint object. + b2MotorJoint *joint; + +}; // MotorJoint + + +} // box2d +} // physics +} // love + +#endif // LOVE_PHYSICS_BOX2D_MOTOR_JOINT_H diff --git a/src/modules/physics/box2d/MouseJoint.cpp b/src/modules/physics/box2d/MouseJoint.cpp index 2d2b0f187..bd8c1ad5e 100644 --- a/src/modules/physics/box2d/MouseJoint.cpp +++ b/src/modules/physics/box2d/MouseJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/MouseJoint.h b/src/modules/physics/box2d/MouseJoint.h index 4a8c73f8d..f8cdef67b 100644 --- a/src/modules/physics/box2d/MouseJoint.h +++ b/src/modules/physics/box2d/MouseJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 35253dbb9..e5c6a03a3 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -98,62 +98,34 @@ int Physics::newPolygonShape(lua_State *L) // 3 to 8 (b2_maxPolygonVertices) vertices int vcount = argc / 2; if (vcount < 3) - luaL_error(L, "Expected a minimum of 3 vertices, got %d.", vcount); + return luaL_error(L, "Expected a minimum of 3 vertices, got %d.", vcount); else if (vcount > b2_maxPolygonVertices) - luaL_error(L, "Expected a maximum of %d vertices, got %d.", b2_maxPolygonVertices, vcount); + return luaL_error(L, "Expected a maximum of %d vertices, got %d.", b2_maxPolygonVertices, vcount); b2PolygonShape *s = new b2PolygonShape(); - bool reverse = false; - b2Vec2 edge1; b2Vec2 vecs[b2_maxPolygonVertices]; for (int i = 0; i < vcount; i++) { - float x = (float)luaL_checknumber(L, -2); - float y = (float)luaL_checknumber(L, -1); + float x = (float)luaL_checknumber(L, 1 + i * 2); + float y = (float)luaL_checknumber(L, 2 + i * 2); vecs[i] = Physics::scaleDown(b2Vec2(x, y)); - lua_pop(L, 2); - - if (!reverse) - { - // Detect clockwise winding. - if (i == 1) - { - edge1 = vecs[1] - vecs[0]; - } - else if (i == vcount - 1) - { - b2Vec2 edge2 = vecs[i] - vecs[i-1]; - // Also check the edge from the last and first point. - b2Vec2 edge3 = vecs[0] - vecs[i]; - if (b2Cross(edge1, edge2) < 0.0f || b2Cross(edge2, edge3) < 0.0f) - reverse = true; - } - else if (i > 1) - { - b2Vec2 edge2 = vecs[i] - vecs[i-1]; - if (b2Cross(edge1, edge2) < 0.0f) - reverse = true; - edge1 = edge2; - } - } } - if (reverse) + try { - for (int i = 0, j = vcount-1; i < j; ++i, --j) - { - b2Vec2 swap = vecs[i]; - vecs[i] = vecs[j]; - vecs[j] = swap; - } + s->Set(vecs, vcount); + } + catch (love::Exception &) + { + delete s; + throw; } - s->Set(vecs, vcount); PolygonShape *p = new PolygonShape(s); - luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)p); + luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, p); return 1; } @@ -177,16 +149,24 @@ int Physics::newChainShape(lua_State *L) lua_pop(L, 2); } - if (loop) - s->CreateLoop(vecs, vcount); - else - s->CreateChain(vecs, vcount); + try + { + if (loop) + s->CreateLoop(vecs, vcount); + else + s->CreateChain(vecs, vcount); + } + catch (love::Exception &) + { + delete[] vecs; + throw; + } - ChainShape *c = new ChainShape(s); delete[] vecs; - luax_newtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, (void *)c); + ChainShape *c = new ChainShape(s); + luax_pushtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, c); return 1; } @@ -240,6 +220,17 @@ RopeJoint *Physics::newRopeJoint(Body *body1, Body *body2, float x1, float y1, f return new RopeJoint(body1, body2, x1, y1, x2, y2, maxLength, collideConnected); } +MotorJoint *Physics::newMotorJoint(Body *body1, Body *body2) +{ + return new MotorJoint(body1, body2); +} + +MotorJoint *Physics::newMotorJoint(Body *body1, Body *body2, float correctionFactor) +{ + return new MotorJoint(body1, body2, correctionFactor); +} + + Fixture *Physics::newFixture(Body *body, Shape *shape, float density) { return new Fixture(body, shape, density); @@ -254,8 +245,8 @@ int Physics::getDistance(lua_State *L) b2DistanceOutput o; b2SimplexCache c; c.count = 0; - try - { + + EXCEPT_GUARD( pA.Set(fixtureA->fixture->GetShape(), 0); pB.Set(fixtureB->fixture->GetShape(), 0); i.proxyA = pA; @@ -264,11 +255,8 @@ int Physics::getDistance(lua_State *L) i.transformB = fixtureB->fixture->GetBody()->GetTransform(); i.useRadii = true; b2Distance(&o, &c, &i); - } - catch (love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + ) + lua_pushnumber(L, Physics::scaleUp(o.distance)); lua_pushnumber(L, Physics::scaleUp(o.pointA.x)); lua_pushnumber(L, Physics::scaleUp(o.pointA.y)); @@ -277,10 +265,10 @@ int Physics::getDistance(lua_State *L) return 5; } -void Physics::setMeter(int meter) +void Physics::setMeter(int scale) { - if (meter < 1) throw love::Exception("Physics error: invalid meter"); - Physics::meter = meter; + if (scale < 1) throw love::Exception("Physics error: invalid meter"); + Physics::meter = scale; } int Physics::getMeter() diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index 877a76eb6..e4d5a90b6 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -43,6 +43,7 @@ #include "WeldJoint.h" #include "WheelJoint.h" #include "RopeJoint.h" +#include "MotorJoint.h" namespace love { @@ -75,7 +76,7 @@ public: * Creates a new Body at the specified position. * @param world The world to create the Body in. * @param x The position along the x-axis. - * @param x The position along the y-axis. + * @param y The position along the y-axis. * @param type The type of body to create. **/ Body *newBody(World *world, float x, float y, Body::Type type); @@ -141,14 +142,12 @@ public: EdgeShape *newEdgeShape(float x1, float y1, float x2, float y2); /** - * Creates a new PolygonShape. - * @param ... A variable number of vertices. + * Creates a new PolygonShape from a variable number of vertices. **/ int newPolygonShape(lua_State *L); /** - * Creates a new ChainShape. - * @param ... A variable number of vertices. + * Creates a new ChainShape from a variable number of vertices. **/ int newChainShape(lua_State *L); @@ -252,6 +251,13 @@ public: **/ RopeJoint *newRopeJoint(Body *body1, Body *body2, float x1, float y1, float x2, float y2, float maxLength, bool collideConnected); + /** + * Creates a new MotorJoint controlling the relative motion between body1 + * and body2. + **/ + MotorJoint *newMotorJoint(Body *body1, Body *body2); + MotorJoint *newMotorJoint(Body *body1, Body *body2, float correctionFactor); + /** * Creates a new Fixture attaching shape to body. * @param body The body to attach the Fixture to. @@ -272,13 +278,13 @@ public: /** * Sets the number of pixels in one meter. - * @param pixels The number of pixels in one meter. (1m ~= 3.3ft). + * @param scale The number of pixels in one meter. (1m ~= 3.3ft). **/ - static void setMeter(int meter); + static void setMeter(int scale); /** * Gets the number of pixels in one meter. - * @param pixels The number of pixels in one meter. (1m ~= 3.3ft). + * @return The number of pixels in one meter. (1m ~= 3.3ft). **/ static int getMeter(); @@ -326,14 +332,14 @@ public: /** * Scales a b2AABB down according to the current meter in pixels. - * @param v The unscaled input AABB. + * @param aabb The unscaled input AABB. * @return The scaled AABB. **/ static b2AABB scaleDown(const b2AABB &aabb); /** * Scales a b2AABB up according to the current meter in pixels. - * @param v The unscaled input AABB. + * @param aabb The unscaled input AABB. * @return The scaled AABB. **/ static b2AABB scaleUp(const b2AABB &aabb); diff --git a/src/modules/physics/box2d/PolygonShape.cpp b/src/modules/physics/box2d/PolygonShape.cpp index fd5ead1e7..5d4c2af65 100644 --- a/src/modules/physics/box2d/PolygonShape.cpp +++ b/src/modules/physics/box2d/PolygonShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -57,6 +57,12 @@ int PolygonShape::getPoints(lua_State *L) return count*2; } +bool PolygonShape::validate() const +{ + b2PolygonShape *p = (b2PolygonShape *)shape; + return p->Validate(); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/PolygonShape.h b/src/modules/physics/box2d/PolygonShape.h index 5b25577e0..873420301 100644 --- a/src/modules/physics/box2d/PolygonShape.h +++ b/src/modules/physics/box2d/PolygonShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -43,10 +43,8 @@ class PolygonShape : public Shape public: /** - * Create a new PolygonShape from the parent Body and - * a Box2D polygon definition. - * @param body The parent Body. - * @param def The polygon definition. + * Create a new PolygonShape from a Box2D polygon definition. + * @param p The polygon definition. **/ PolygonShape(b2PolygonShape *p, bool own = true); @@ -59,6 +57,11 @@ public: * The result can be directly passed into love.graphics.polygon(). **/ int getPoints(lua_State *L); + + /** + * Validate convexity. + **/ + bool validate() const; }; } // box2d diff --git a/src/modules/physics/box2d/PrismaticJoint.cpp b/src/modules/physics/box2d/PrismaticJoint.cpp index 617f1f49f..6621b512d 100644 --- a/src/modules/physics/box2d/PrismaticJoint.cpp +++ b/src/modules/physics/box2d/PrismaticJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -61,9 +61,9 @@ float PrismaticJoint::getJointSpeed() const return Physics::scaleUp(joint->GetJointSpeed()); } -void PrismaticJoint::enableMotor(bool motor) +void PrismaticJoint::setMotorEnabled(bool enable) { - return joint->EnableMotor(motor); + return joint->EnableMotor(enable); } bool PrismaticJoint::isMotorEnabled() const @@ -96,12 +96,12 @@ float PrismaticJoint::getMaxMotorForce() const return Physics::scaleUp(joint->GetMaxMotorForce()); } -void PrismaticJoint::enableLimit(bool limit) +void PrismaticJoint::setLimitsEnabled(bool enable) { - joint->EnableLimit(limit); + joint->EnableLimit(enable); } -bool PrismaticJoint::isLimitEnabled() const +bool PrismaticJoint::hasLimitsEnabled() const { return joint->IsLimitEnabled(); } diff --git a/src/modules/physics/box2d/PrismaticJoint.h b/src/modules/physics/box2d/PrismaticJoint.h index c412dd225..609678793 100644 --- a/src/modules/physics/box2d/PrismaticJoint.h +++ b/src/modules/physics/box2d/PrismaticJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -59,7 +59,7 @@ public: /** * Enable/disable the joint motor. **/ - void enableMotor(bool motor); + void setMotorEnabled(bool enable); /** * Checks whether the motor is enabled. @@ -93,14 +93,14 @@ public: float getMaxMotorForce() const; /** - * Enable/disable the joint limit. + * Enable/disable the joint limits. **/ - void enableLimit(bool limit); + void setLimitsEnabled(bool enable); /** * Checks whether limits are enabled. **/ - bool isLimitEnabled() const; + bool hasLimitsEnabled() const; /** * Sets the upper limit, usually in meters. diff --git a/src/modules/physics/box2d/PulleyJoint.cpp b/src/modules/physics/box2d/PulleyJoint.cpp index 901752afe..b093e6616 100644 --- a/src/modules/physics/box2d/PulleyJoint.cpp +++ b/src/modules/physics/box2d/PulleyJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/PulleyJoint.h b/src/modules/physics/box2d/PulleyJoint.h index 3af2f792d..6d2e2beae 100644 --- a/src/modules/physics/box2d/PulleyJoint.h +++ b/src/modules/physics/box2d/PulleyJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/RevoluteJoint.cpp b/src/modules/physics/box2d/RevoluteJoint.cpp index 5f9b90fa0..0acecc2ff 100644 --- a/src/modules/physics/box2d/RevoluteJoint.cpp +++ b/src/modules/physics/box2d/RevoluteJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -58,9 +58,9 @@ float RevoluteJoint::getJointSpeed() const return joint->GetJointSpeed(); } -void RevoluteJoint::enableMotor(bool motor) +void RevoluteJoint::setMotorEnabled(bool enable) { - return joint->EnableMotor(motor); + return joint->EnableMotor(enable); } bool RevoluteJoint::isMotorEnabled() const @@ -93,12 +93,12 @@ float RevoluteJoint::getMaxMotorTorque() const return Physics::scaleUp(Physics::scaleUp(joint->GetMaxMotorTorque())); } -void RevoluteJoint::enableLimit(bool limit) +void RevoluteJoint::setLimitsEnabled(bool enable) { - joint->EnableLimit(limit); + joint->EnableLimit(enable); } -bool RevoluteJoint::isLimitEnabled() const +bool RevoluteJoint::hasLimitsEnabled() const { return joint->IsLimitEnabled(); } diff --git a/src/modules/physics/box2d/RevoluteJoint.h b/src/modules/physics/box2d/RevoluteJoint.h index 82b6113ae..1a128ab1f 100644 --- a/src/modules/physics/box2d/RevoluteJoint.h +++ b/src/modules/physics/box2d/RevoluteJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -59,7 +59,7 @@ public: /** * Enable/disable the joint motor. **/ - void enableMotor(bool motor); + void setMotorEnabled(bool enable); /** * Checks whether the motor is enabled. @@ -95,12 +95,12 @@ public: /** * Enable/disable the joint limit. **/ - void enableLimit(bool limit); + void setLimitsEnabled(bool enable); /** * Checks whether limits are enabled. **/ - bool isLimitEnabled() const; + bool hasLimitsEnabled() const; /** * Sets the upper limit in degrees. diff --git a/src/modules/physics/box2d/RopeJoint.cpp b/src/modules/physics/box2d/RopeJoint.cpp index a38095b35..3c83d9cd3 100644 --- a/src/modules/physics/box2d/RopeJoint.cpp +++ b/src/modules/physics/box2d/RopeJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/RopeJoint.h b/src/modules/physics/box2d/RopeJoint.h index 951e06340..39f9b6460 100644 --- a/src/modules/physics/box2d/RopeJoint.h +++ b/src/modules/physics/box2d/RopeJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Shape.cpp b/src/modules/physics/box2d/Shape.cpp index 9d911b174..690fe6f7a 100644 --- a/src/modules/physics/box2d/Shape.cpp +++ b/src/modules/physics/box2d/Shape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/Shape.h b/src/modules/physics/box2d/Shape.h index 6ce20dcc6..db0b4d015 100644 --- a/src/modules/physics/box2d/Shape.h +++ b/src/modules/physics/box2d/Shape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index 769ab177e..62c58eff9 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/WeldJoint.h b/src/modules/physics/box2d/WeldJoint.h index 5cc08beb3..a8f91a281 100644 --- a/src/modules/physics/box2d/WeldJoint.h +++ b/src/modules/physics/box2d/WeldJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp index b5c27e2b4..294c24e60 100644 --- a/src/modules/physics/box2d/WheelJoint.cpp +++ b/src/modules/physics/box2d/WheelJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -58,9 +58,9 @@ float WheelJoint::getJointSpeed() const return Physics::scaleUp(joint->GetJointSpeed()); } -void WheelJoint::enableMotor(bool motor) +void WheelJoint::setMotorEnabled(bool enable) { - return joint->EnableMotor(motor); + return joint->EnableMotor(enable); } bool WheelJoint::isMotorEnabled() const diff --git a/src/modules/physics/box2d/WheelJoint.h b/src/modules/physics/box2d/WheelJoint.h index 7aaddccba..4a0732f36 100644 --- a/src/modules/physics/box2d/WheelJoint.h +++ b/src/modules/physics/box2d/WheelJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -60,7 +60,7 @@ public: /** * Enable/disable the joint motor. **/ - void enableMotor(bool motor); + void setMotorEnabled(bool enable); /** * Checks whether the motor is enabled. diff --git a/src/modules/physics/box2d/World.cpp b/src/modules/physics/box2d/World.cpp index 5cf8581c9..bf6f6ee1b 100644 --- a/src/modules/physics/box2d/World.cpp +++ b/src/modules/physics/box2d/World.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -59,7 +59,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse if (a != 0) { a->retain(); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)a); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a); } else throw love::Exception("A fixture has escaped Memoizer!"); @@ -71,7 +71,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse if (b != 0) { b->retain(); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)b); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b); } else throw love::Exception("A fixture has escaped Memoizer!"); @@ -83,7 +83,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse else cobj->retain(); - luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void *)cobj); + luax_pushtype(L, "Contact", (PHYSICS_CONTACT_T), cobj); int args = 3; if (impulse) @@ -133,8 +133,8 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b) { lua_State *L = ref->getL(); ref->push(); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)a); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)b); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b); lua_call(L, 2, 1); return luax_toboolean(L, -1); } @@ -162,7 +162,7 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture) if (!f) throw love::Exception("A fixture has escaped Memoizer!"); f->retain(); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)f); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, f); lua_call(L, 1, 1); return luax_toboolean(L, -1); } @@ -190,7 +190,7 @@ float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 & if (!f) throw love::Exception("A fixture has escaped Memoizer!"); f->retain(); - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)f); + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, f); b2Vec2 scaledPoint = Physics::scaleUp(point); lua_pushnumber(L, scaledPoint.x); lua_pushnumber(L, scaledPoint.y); @@ -257,21 +257,21 @@ void World::update(float dt) world->Step(dt, 8, 6); // Destroy all objects marked during the time step. - for (std::vector::iterator i = destructBodies.begin(); i < destructBodies.end(); i++) + for (auto i = destructBodies.begin(); i < destructBodies.end(); i++) { Body *b = *i; if (b->body != 0) b->destroy(); // Release for reference in vector. b->release(); } - for (std::vector::iterator i = destructFixtures.begin(); i < destructFixtures.end(); i++) + for (auto i = destructFixtures.begin(); i < destructFixtures.end(); i++) { Fixture *f = *i; if (f->isValid()) f->destroy(); // Release for reference in vector. f->release(); } - for (std::vector::iterator i = destructJoints.begin(); i < destructJoints.end(); i++) + for (auto i = destructJoints.begin(); i < destructJoints.end(); i++) { Joint *j = *i; if (j->isValid()) j->destroyJoint(); @@ -396,12 +396,17 @@ int World::getGravity(lua_State *L) return 2; } -void World::setAllowSleeping(bool allow) +void World::translateOrigin(float x, float y) +{ + world->ShiftOrigin(Physics::scaleDown(b2Vec2(x, y))); +} + +void World::setSleepingAllowed(bool allow) { world->SetAllowSleeping(allow); } -bool World::getAllowSleeping() const +bool World::isSleepingAllowed() const { return world->GetAllowSleeping(); } @@ -441,7 +446,7 @@ int World::getBodyList(lua_State *L) const if (!body) throw love::Exception("A body has escaped Memoizer!"); body->retain(); - luax_newtype(L, "Body", PHYSICS_BODY_T, (void *)body); + luax_pushtype(L, "Body", PHYSICS_BODY_T, body); lua_rawseti(L, -2, i); i++; } @@ -460,7 +465,7 @@ int World::getJointList(lua_State *L) const Joint *joint = (Joint *)Memoizer::find(j); if (!joint) throw love::Exception("A joint has escaped Memoizer!"); joint->retain(); - luax_newtype(L, "Joint", PHYSICS_JOINT_T, (void *)joint); + luax_pushtype(L, "Joint", PHYSICS_JOINT_T, joint); lua_rawseti(L, -2, i); i++; } @@ -481,7 +486,7 @@ int World::getContactList(lua_State *L) const contact = new Contact(c); else contact->retain(); - luax_newtype(L, "Contact", PHYSICS_CONTACT_T, (void *)contact); + luax_pushtype(L, "Contact", PHYSICS_CONTACT_T, contact); lua_rawseti(L, -2, i); i++; } diff --git a/src/modules/physics/box2d/World.h b/src/modules/physics/box2d/World.h index 47eaca921..aa9445810 100644 --- a/src/modules/physics/box2d/World.h +++ b/src/modules/physics/box2d/World.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -181,17 +181,24 @@ public: **/ int getGravity(lua_State *L); + /** + * Translate the world origin. + * @param x The new world origin's x-coordinate relative to the old origin. + * @param y The new world origin's y-coordinate relative to the old origin. + **/ + void translateOrigin(float x, float y); + /** * Sets whether this World allows sleep. * @param allow True to allow, false to disallow. **/ - void setAllowSleeping(bool allow); + void setSleepingAllowed(bool allow); /** * Returns whether this World allows sleep. * @return True if allowed, false if disallowed. **/ - bool getAllowSleeping() const; + bool isSleepingAllowed() const; /** * Returns whether this World is currently locked. diff --git a/src/modules/physics/box2d/wrap_Body.cpp b/src/modules/physics/box2d/wrap_Body.cpp index 600062874..419d1fb29 100644 --- a/src/modules/physics/box2d/wrap_Body.cpp +++ b/src/modules/physics/box2d/wrap_Body.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -169,15 +169,19 @@ int w_Body_applyLinearImpulse(lua_State *L) float jx = (float)luaL_checknumber(L, 2); float jy = (float)luaL_checknumber(L, 3); - if (lua_gettop(L) == 3) + int nargs = lua_gettop(L); + + if (nargs <= 3 || (nargs == 4 && lua_type(L, 4) == LUA_TBOOLEAN)) { - t->applyLinearImpulse(jx, jy); + bool awake = luax_optboolean(L, 4, true); + t->applyLinearImpulse(jx, jy, awake); } - else if (lua_gettop(L) == 5) + else if (nargs >= 5) { float rx = (float)luaL_checknumber(L, 4); float ry = (float)luaL_checknumber(L, 5); - t->applyLinearImpulse(jx, jy, rx, ry); + bool awake = luax_optboolean(L, 6, true); + t->applyLinearImpulse(jx, jy, rx, ry, awake); } else { @@ -191,7 +195,8 @@ int w_Body_applyAngularImpulse(lua_State *L) { Body *t = luax_checkbody(L, 1); float i = (float)luaL_checknumber(L, 2); - t->applyAngularImpulse(i); + bool awake = luax_optboolean(L, 3, true); + t->applyAngularImpulse(i, awake); return 0; } @@ -199,7 +204,8 @@ int w_Body_applyTorque(lua_State *L) { Body *t = luax_checkbody(L, 1); float arg = (float)luaL_checknumber(L, 2); - t->applyTorque(arg); + bool awake = luax_optboolean(L, 3, true); + t->applyTorque(arg, awake); return 0; } @@ -209,16 +215,19 @@ int w_Body_applyForce(lua_State *L) float fx = (float)luaL_checknumber(L, 2); float fy = (float)luaL_checknumber(L, 3); + int nargs = lua_gettop(L); - if (lua_gettop(L) == 3) + if (nargs <= 3 || (nargs == 4 && lua_type(L, 4) == LUA_TBOOLEAN)) { - t->applyForce(fx, fy); + bool awake = luax_optboolean(L, 4, true); + t->applyForce(fx, fy, awake); } - else if (lua_gettop(L) == 5) + else if (lua_gettop(L) >= 5) { float rx = (float)luaL_checknumber(L, 4); float ry = (float)luaL_checknumber(L, 5); - t->applyForce(fx, fy, rx, ry); + bool awake = luax_optboolean(L, 6, true); + t->applyForce(fx, fy, rx, ry, awake); } else { @@ -232,7 +241,7 @@ int w_Body_setX(lua_State *L) { Body *t = luax_checkbody(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setX(arg1); + EXCEPT_GUARD(t->setX(arg1);) return 0; } @@ -240,7 +249,7 @@ int w_Body_setY(lua_State *L) { Body *t = luax_checkbody(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setY(arg1); + EXCEPT_GUARD(t->setY(arg1);) return 0; } @@ -257,7 +266,7 @@ int w_Body_setAngle(lua_State *L) { Body *t = luax_checkbody(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setAngle(arg1); + EXCEPT_GUARD(t->setAngle(arg1);) return 0; } @@ -274,14 +283,14 @@ int w_Body_setPosition(lua_State *L) Body *t = luax_checkbody(L, 1); float arg1 = (float)luaL_checknumber(L, 2); float arg2 = (float)luaL_checknumber(L, 3); - t->setPosition(arg1, arg2); + EXCEPT_GUARD(t->setPosition(arg1, arg2);) return 0; } int w_Body_resetMassData(lua_State *L) { Body *t = luax_checkbody(L, 1); - t->resetMassData(); + EXCEPT_GUARD(t->resetMassData();) return 0; } @@ -292,7 +301,7 @@ int w_Body_setMassData(lua_State *L) float y = (float)luaL_checknumber(L, 3); float m = (float)luaL_checknumber(L, 4); float i = (float)luaL_checknumber(L, 5); - ASSERT_GUARD(t->setMassData(x, y, m, i);) + EXCEPT_GUARD(t->setMassData(x, y, m, i);) return 0; } @@ -300,7 +309,7 @@ int w_Body_setMass(lua_State *L) { Body *t = luax_checkbody(L, 1); float m = (float)luaL_checknumber(L, 2); - t->setMass(m); + EXCEPT_GUARD(t->setMass(m);) return 0; } @@ -308,7 +317,7 @@ int w_Body_setInertia(lua_State *L) { Body *t = luax_checkbody(L, 1); float i = (float)luaL_checknumber(L, 2); - t->setInertia(i); + EXCEPT_GUARD(t->setInertia(i);) return 0; } @@ -342,7 +351,7 @@ int w_Body_setType(lua_State *L) const char *typeStr = luaL_checkstring(L, 2); Body::Type type; Body::getConstant(typeStr, type); - t->setType(type); + EXCEPT_GUARD(t->setType(type);) return 0; } @@ -485,7 +494,7 @@ int w_Body_setActive(lua_State *L) { Body *t = luax_checkbody(L, 1); bool b = luax_toboolean(L, 2); - t->setActive(b); + EXCEPT_GUARD(t->setActive(b);) return 0; } @@ -501,7 +510,7 @@ int w_Body_setFixedRotation(lua_State *L) { Body *t = luax_checkbody(L, 1); bool b = luax_toboolean(L, 2); - t->setFixedRotation(b); + EXCEPT_GUARD(t->setFixedRotation(b);) return 0; } @@ -517,20 +526,15 @@ int w_Body_getFixtureList(lua_State *L) { Body *t = luax_checkbody(L, 1); lua_remove(L, 1); - return t->getFixtureList(L); + int n = 0; + EXCEPT_GUARD(n = t->getFixtureList(L);) + return n; } int w_Body_destroy(lua_State *L) { Body *t = luax_checkbody(L, 1); - try - { - t->destroy(); - } - catch(love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(t->destroy();) return 0; } diff --git a/src/modules/physics/box2d/wrap_Body.h b/src/modules/physics/box2d/wrap_Body.h index 960d8e5c3..f06348809 100644 --- a/src/modules/physics/box2d/wrap_Body.h +++ b/src/modules/physics/box2d/wrap_Body.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_ChainShape.cpp b/src/modules/physics/box2d/wrap_ChainShape.cpp index 2697b0771..245d4c0f4 100644 --- a/src/modules/physics/box2d/wrap_ChainShape.cpp +++ b/src/modules/physics/box2d/wrap_ChainShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,16 +39,16 @@ int w_ChainShape_setNextVertex(lua_State *L) ChainShape *c = luax_checkchainshape(L, 1); float x = (float)luaL_checknumber(L, 2); float y = (float)luaL_checknumber(L, 3); - c->setNextVertex(x, y); + EXCEPT_GUARD(c->setNextVertex(x, y);) return 0; } -int w_ChainShape_setPrevVertex(lua_State *L) +int w_ChainShape_setPreviousVertex(lua_State *L) { ChainShape *c = luax_checkchainshape(L, 1); float x = (float)luaL_checknumber(L, 2); float y = (float)luaL_checknumber(L, 3); - c->setPrevVertex(x, y); + EXCEPT_GUARD(c->setPreviousVertex(x, y);) return 0; } @@ -63,8 +63,9 @@ int w_ChainShape_getChildEdge(lua_State *L) { ChainShape *c = luax_checkchainshape(L, 1); int index = luaL_checkint(L, 2) - 1; // Convert from 1-based index - EdgeShape *e = c->getChildEdge(index); - luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, e); + EdgeShape *e = 0; + EXCEPT_GUARD(e = c->getChildEdge(index);) + luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, e); return 1; } @@ -81,7 +82,7 @@ int w_ChainShape_getPoint(lua_State *L) ChainShape *c = luax_checkchainshape(L, 1); int index = luaL_checkint(L, 2) - 1; // Convert from 1-based index b2Vec2 v; - ASSERT_GUARD(v = c->getPoint(index);) + EXCEPT_GUARD(v = c->getPoint(index);) lua_pushnumber(L, v.x); lua_pushnumber(L, v.y); return 2; @@ -92,6 +93,8 @@ int w_ChainShape_getPoints(lua_State *L) ChainShape *c = luax_checkchainshape(L, 1); const b2Vec2 *verts = c->getPoints(); int count = c->getVertexCount(); + if (!lua_checkstack(L, count*2)) + return luaL_error(L, "Too many return values"); for (int i = 0; i < count; i++) { b2Vec2 v = Physics::scaleUp(verts[i]); @@ -104,7 +107,7 @@ int w_ChainShape_getPoints(lua_State *L) static const luaL_Reg functions[] = { { "setNextVertex", w_ChainShape_setNextVertex }, - { "setPrevVertex", w_ChainShape_setPrevVertex }, + { "setPreviousVertex", w_ChainShape_setPreviousVertex }, { "getChildCount", w_ChainShape_getChildCount }, { "getChildEdge", w_ChainShape_getChildEdge }, { "getVertexCount", w_ChainShape_getVertexCount }, diff --git a/src/modules/physics/box2d/wrap_ChainShape.h b/src/modules/physics/box2d/wrap_ChainShape.h index 5df8b13f7..81a6877d7 100644 --- a/src/modules/physics/box2d/wrap_ChainShape.h +++ b/src/modules/physics/box2d/wrap_ChainShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,7 +36,7 @@ namespace box2d ChainShape *luax_checkchainshape(lua_State *L, int idx); int w_ChainShape_setNextVertex(lua_State *L); -int w_ChainShape_setPrevVertex(lua_State *L); +int w_ChainShape_setPreviousVertex(lua_State *L); int w_ChainShape_getChildCount(lua_State *L); int w_ChainShape_getChildEdge(lua_State *L); int w_ChainShape_getVertexCount(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_CircleShape.cpp b/src/modules/physics/box2d/wrap_CircleShape.cpp index 8fa46de7f..fad234c92 100644 --- a/src/modules/physics/box2d/wrap_CircleShape.cpp +++ b/src/modules/physics/box2d/wrap_CircleShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -47,10 +47,29 @@ int w_CircleShape_setRadius(lua_State *L) return 0; } +int w_CircleShape_getPoint(lua_State *L) +{ + CircleShape *c = luax_checkcircleshape(L, 1); + float x, y; + c->getPoint(x, y); + lua_pushnumber(L, x); + lua_pushnumber(L, y); + return 2; +} + +int w_CircleShape_setPoint(lua_State *L) +{ + CircleShape *c = luax_checkcircleshape(L, 1); + c->setPoint((float) luaL_checknumber(L, 2), (float) luaL_checknumber(L, 3)); + return 0; +} + static const luaL_Reg functions[] = { { "getRadius", w_CircleShape_getRadius }, { "setRadius", w_CircleShape_setRadius }, + { "getPoint", w_CircleShape_getPoint }, + { "setPoint", w_CircleShape_setPoint }, // From Shape. { "getType", w_Shape_getType }, { "getRadius", w_Shape_getRadius }, diff --git a/src/modules/physics/box2d/wrap_CircleShape.h b/src/modules/physics/box2d/wrap_CircleShape.h index 6876712bb..0a37fe9de 100644 --- a/src/modules/physics/box2d/wrap_CircleShape.h +++ b/src/modules/physics/box2d/wrap_CircleShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,6 +36,8 @@ namespace box2d CircleShape *luax_checkcircleshape(lua_State *L, int idx); int w_CircleShape_getRadius(lua_State *L); int w_CircleShape_setRadius(lua_State *L); +int w_CircleShape_getPoint(lua_State *L); +int w_CircleShape_setPoint(lua_State *L); extern "C" int luaopen_circleshape(lua_State *L); } // box2d diff --git a/src/modules/physics/box2d/wrap_Contact.cpp b/src/modules/physics/box2d/wrap_Contact.cpp index 5c8cd1eab..f6856ddf1 100644 --- a/src/modules/physics/box2d/wrap_Contact.cpp +++ b/src/modules/physics/box2d/wrap_Contact.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -113,6 +113,31 @@ int w_Contact_resetRestitution(lua_State *L) return 0; } +int w_Contact_setTangentSpeed(lua_State *L) +{ + Contact *t = luax_checkcontact(L, 1); + float speed = (float) luaL_checknumber(L, 2); + t->setTangentSpeed(speed); + return 0; +} + +int w_Contact_getTangentSpeed(lua_State *L) +{ + Contact *t = luax_checkcontact(L, 1); + lua_pushnumber(L, t->getTangentSpeed()); + return 1; +} + +int w_Contact_getChildren(lua_State *L) +{ + Contact *t = luax_checkcontact(L, 1); + int a, b; + t->getChildren(a, b); + lua_pushnumber(L, a + 1); + lua_pushnumber(L, b + 1); + return 2; +} + extern "C" int luaopen_contact(lua_State *L) { static const luaL_Reg functions[] = @@ -128,6 +153,9 @@ extern "C" int luaopen_contact(lua_State *L) { "setEnabled", w_Contact_setEnabled }, { "resetFriction", w_Contact_resetFriction }, { "resetRestitution", w_Contact_resetRestitution }, + { "setTangentSpeed", w_Contact_setTangentSpeed }, + { "getTangentSpeed", w_Contact_getTangentSpeed }, + { "getChildren", w_Contact_getChildren }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_Contact.h b/src/modules/physics/box2d/wrap_Contact.h index 080622242..c1c2e2e29 100644 --- a/src/modules/physics/box2d/wrap_Contact.h +++ b/src/modules/physics/box2d/wrap_Contact.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -44,6 +44,9 @@ int w_Contact_setRestitution(lua_State *L); int w_Contact_setEnabled(lua_State *L); int w_Contact_resetFriction(lua_State *L); int w_Contact_resetRestitution(lua_State *L); +int w_Contact_setTangentSpeed(lua_State *L); +int w_Contact_getTangentSpeed(lua_State *L); +int w_Contact_getChildren(lua_State *L); extern "C" int luaopen_contact(lua_State *L); } // box2d diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.cpp b/src/modules/physics/box2d/wrap_DistanceJoint.cpp index f58f610f2..0824e3566 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.h b/src/modules/physics/box2d/wrap_DistanceJoint.h index 1d4b8ef34..ae2a880d1 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.h +++ b/src/modules/physics/box2d/wrap_DistanceJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_EdgeShape.cpp b/src/modules/physics/box2d/wrap_EdgeShape.cpp index 95954880c..8784ccdef 100644 --- a/src/modules/physics/box2d/wrap_EdgeShape.cpp +++ b/src/modules/physics/box2d/wrap_EdgeShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_EdgeShape.h b/src/modules/physics/box2d/wrap_EdgeShape.h index e0b53679b..3a1ad4b66 100644 --- a/src/modules/physics/box2d/wrap_EdgeShape.h +++ b/src/modules/physics/box2d/wrap_EdgeShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_Fixture.cpp b/src/modules/physics/box2d/wrap_Fixture.cpp index 237b857fa..953f68069 100644 --- a/src/modules/physics/box2d/wrap_Fixture.cpp +++ b/src/modules/physics/box2d/wrap_Fixture.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -65,7 +65,7 @@ int w_Fixture_setDensity(lua_State *L) { Fixture *t = luax_checkfixture(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDensity(arg1); + EXCEPT_GUARD(t->setDensity(arg1);) return 0; } @@ -112,7 +112,7 @@ int w_Fixture_getBody(lua_State *L) if (body == 0) return 0; body->retain(); - luax_newtype(L, "Body", PHYSICS_BODY_T, (void *)body); + luax_pushtype(L, "Body", PHYSICS_BODY_T, body); return 1; } @@ -125,19 +125,19 @@ int w_Fixture_getShape(lua_State *L) switch (shape->getType()) { case Shape::SHAPE_EDGE: - luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, (void *)shape); + luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, shape); break; case Shape::SHAPE_CHAIN: - luax_newtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, (void *)shape); + luax_pushtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, shape); break; case Shape::SHAPE_CIRCLE: - luax_newtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, (void *)shape); + luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape); break; case Shape::SHAPE_POLYGON: - luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)shape); + luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape); break; default: - luax_newtype(L, "Shape", PHYSICS_SHAPE_T, (void *)shape); + luax_pushtype(L, "Shape", PHYSICS_SHAPE_T, shape); break; } return 1; @@ -156,7 +156,9 @@ int w_Fixture_rayCast(lua_State *L) { Fixture *t = luax_checkfixture(L, 1); lua_remove(L, 1); - ASSERT_GUARD(return t->rayCast(L);) + int ret = 0; + EXCEPT_GUARD(ret = t->rayCast(L);) + return ret; } int w_Fixture_setFilterData(lua_State *L) @@ -256,14 +258,7 @@ int w_Fixture_setGroupIndex(lua_State *L) int w_Fixture_destroy(lua_State *L) { Fixture *t = luax_checkfixture(L, 1); - try - { - t->destroy(); - } - catch(love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(t->destroy();) return 0; } diff --git a/src/modules/physics/box2d/wrap_Fixture.h b/src/modules/physics/box2d/wrap_Fixture.h index 51a5b2d25..4bce8e907 100644 --- a/src/modules/physics/box2d/wrap_Fixture.h +++ b/src/modules/physics/box2d/wrap_Fixture.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_FrictionJoint.cpp b/src/modules/physics/box2d/wrap_FrictionJoint.cpp index 48b1d5a88..ce5336fac 100644 --- a/src/modules/physics/box2d/wrap_FrictionJoint.cpp +++ b/src/modules/physics/box2d/wrap_FrictionJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,6 +19,7 @@ **/ #include "wrap_FrictionJoint.h" +#include "wrap_Physics.h" namespace love { @@ -39,7 +40,7 @@ int w_FrictionJoint_setMaxForce(lua_State *L) { FrictionJoint *t = luax_checkfrictionjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setMaxForce(arg1); + EXCEPT_GUARD(t->setMaxForce(arg1);) return 0; } @@ -54,7 +55,7 @@ int w_FrictionJoint_setMaxTorque(lua_State *L) { FrictionJoint *t = luax_checkfrictionjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setMaxTorque(arg1); + EXCEPT_GUARD(t->setMaxTorque(arg1);) return 0; } diff --git a/src/modules/physics/box2d/wrap_FrictionJoint.h b/src/modules/physics/box2d/wrap_FrictionJoint.h index fde5b8c82..9b16193df 100644 --- a/src/modules/physics/box2d/wrap_FrictionJoint.h +++ b/src/modules/physics/box2d/wrap_FrictionJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_GearJoint.cpp b/src/modules/physics/box2d/wrap_GearJoint.cpp index 6112de5ef..e8189f7a2 100644 --- a/src/modules/physics/box2d/wrap_GearJoint.cpp +++ b/src/modules/physics/box2d/wrap_GearJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,6 +19,7 @@ **/ #include "wrap_GearJoint.h" +#include "wrap_Physics.h" namespace love { @@ -39,7 +40,7 @@ int w_GearJoint_setRatio(lua_State *L) { GearJoint *t = luax_checkgearjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setRatio(arg1); + EXCEPT_GUARD(t->setRatio(arg1);) return 0; } diff --git a/src/modules/physics/box2d/wrap_GearJoint.h b/src/modules/physics/box2d/wrap_GearJoint.h index 5405794b0..c97c26b5f 100644 --- a/src/modules/physics/box2d/wrap_GearJoint.h +++ b/src/modules/physics/box2d/wrap_GearJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_Joint.cpp b/src/modules/physics/box2d/wrap_Joint.cpp index 4c9b1cccf..259a09b23 100644 --- a/src/modules/physics/box2d/wrap_Joint.cpp +++ b/src/modules/physics/box2d/wrap_Joint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -78,14 +78,7 @@ int w_Joint_getCollideConnected(lua_State *L) int w_Joint_destroy(lua_State *L) { Joint *t = luax_checkjoint(L, 1); - try - { - t->destroyJoint(); - } - catch(love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(t->destroyJoint();) return 0; } diff --git a/src/modules/physics/box2d/wrap_Joint.h b/src/modules/physics/box2d/wrap_Joint.h index d04462896..3a2495d83 100644 --- a/src/modules/physics/box2d/wrap_Joint.h +++ b/src/modules/physics/box2d/wrap_Joint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_MotorJoint.cpp b/src/modules/physics/box2d/wrap_MotorJoint.cpp new file mode 100644 index 000000000..7286d3504 --- /dev/null +++ b/src/modules/physics/box2d/wrap_MotorJoint.cpp @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "wrap_MotorJoint.h" + +namespace love +{ +namespace physics +{ +namespace box2d +{ + +MotorJoint *luax_checkmotorjoint(lua_State *L, int idx) +{ + MotorJoint *j = luax_checktype(L, idx, "MotorJoint", PHYSICS_MOTOR_JOINT_T); + if (!j->isValid()) + luaL_error(L, "Attempt to use destroyed joint."); + return j; +} + +int w_MotorJoint_setLinearOffset(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + float x = (float) luaL_checknumber(L, 2); + float y = (float) luaL_checknumber(L, 3); + t->setLinearOffset(x, y); + return 0; +} + +int w_MotorJoint_getLinearOffset(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + return t->getLinearOffset(L); +} + +int w_MotorJoint_setAngularOffset(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + float arg1 = (float) luaL_checknumber(L, 2); + t->setAngularOffset(arg1); + return 0; +} + +int w_MotorJoint_getAngularOffset(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + lua_pushnumber(L, t->getAngularOffset()); + return 1; +} + +int w_MotorJoint_setMaxForce(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + float arg1 = (float) luaL_checknumber(L, 2); + EXCEPT_GUARD(t->setMaxForce(arg1);) + return 0; +} + +int w_MotorJoint_getMaxForce(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + lua_pushnumber(L, t->getMaxForce()); + return 1; +} + +int w_MotorJoint_setMaxTorque(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + float arg1 = (float) luaL_checknumber(L, 2); + EXCEPT_GUARD(t->setMaxTorque(arg1);) + return 0; +} + +int w_MotorJoint_getMaxTorque(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + lua_pushnumber(L, t->getMaxTorque()); + return 1; +} + +int w_MotorJoint_setCorrectionFactor(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + float arg1 = (float) luaL_checknumber(L, 2); + EXCEPT_GUARD(t->setCorrectionFactor(arg1);) + return 0; +} + +int w_MotorJoint_getCorrectionFactor(lua_State *L) +{ + MotorJoint *t = luax_checkmotorjoint(L, 1); + lua_pushnumber(L, t->getCorrectionFactor()); + return 1; +} + +static const luaL_Reg functions[] = +{ + { "setLinearOffset", w_MotorJoint_setLinearOffset }, + { "getLinearOffset", w_MotorJoint_getLinearOffset }, + { "setAngularOffset", w_MotorJoint_setAngularOffset }, + { "getAngularOffset", w_MotorJoint_getAngularOffset }, + { "setMaxForce", w_MotorJoint_setMaxForce }, + { "getMaxForce", w_MotorJoint_getMaxForce }, + { "setMaxTorque", w_MotorJoint_setMaxTorque }, + { "getMaxTorque", w_MotorJoint_getMaxTorque }, + { "setCorrectionFactor", w_MotorJoint_setCorrectionFactor }, + { "getCorrectionFactor", w_MotorJoint_getCorrectionFactor }, + // From Joint. + { "getType", w_Joint_getType }, + { "getAnchors", w_Joint_getAnchors }, + { "getReactionForce", w_Joint_getReactionForce }, + { "getReactionTorque", w_Joint_getReactionTorque }, + { "getCollideConnected", w_Joint_getCollideConnected }, + { "destroy", w_Joint_destroy }, + { 0, 0 } +}; + +extern "C" int luaopen_motorjoint(lua_State *L) +{ + return luax_register_type(L, "MotorJoint", functions); +} + + +} // box2d +} // phyics +} // love \ No newline at end of file diff --git a/src/modules/physics/box2d/wrap_MotorJoint.h b/src/modules/physics/box2d/wrap_MotorJoint.h new file mode 100644 index 000000000..59cd31fe3 --- /dev/null +++ b/src/modules/physics/box2d/wrap_MotorJoint.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_PHYSICS_BOX2D_WRAP_MOTOR_JOINT_H +#define LOVE_PHYSICS_BOX2D_WRAP_MOTOR_JOINT_H + +// LOVE +#include "common/runtime.h" +#include "wrap_Joint.h" +#include "MotorJoint.h" + +namespace love +{ +namespace physics +{ +namespace box2d +{ + +MotorJoint *luax_checkmotorjoint(lua_State *L, int idx); +int w_MotorJoint_setLinearOffset(lua_State *L); +int w_MotorJoint_getLinearOffset(lua_State *L); +int w_MotorJoint_setAngularOffset(lua_State *L); +int w_MotorJoint_getAngularOffset(lua_State *L); +int w_MotorJoint_setMaxForce(lua_State *L); +int w_MotorJoint_getMaxForce(lua_State *L); +int w_MotorJoint_setMaxTorque(lua_State *L); +int w_MotorJoint_getMaxTorque(lua_State *L); +int w_MotorJoint_setCorrectionFactor(lua_State *L); +int w_MotorJoint_getCorrectionFactor(lua_State *L); +extern "C" int luaopen_motorjoint(lua_State *L); + +} // box2d +} // physics +} // love + +#endif // LOVE_PHYSICS_BOX2D_WRAP_MOTOR_JOINT_H diff --git a/src/modules/physics/box2d/wrap_MouseJoint.cpp b/src/modules/physics/box2d/wrap_MouseJoint.cpp index 82f7f1c4b..8e02addf7 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_MouseJoint.h b/src/modules/physics/box2d/wrap_MouseJoint.h index cf361785f..f00049805 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.h +++ b/src/modules/physics/box2d/wrap_MouseJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index 811e17a5c..b53bb5c78 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -40,6 +40,7 @@ #include "wrap_WeldJoint.h" #include "wrap_WheelJoint.h" #include "wrap_RopeJoint.h" +#include "wrap_MotorJoint.h" namespace love { @@ -57,8 +58,8 @@ int w_newWorld(lua_State *L) bool sleep = luax_optboolean(L, 3, true); World *w; - ASSERT_GUARD(w = instance->newWorld(gx, gy, sleep);) - luax_newtype(L, "World", PHYSICS_WORLD_T, (void *)w); + EXCEPT_GUARD(w = instance->newWorld(gx, gy, sleep);) + luax_pushtype(L, "World", PHYSICS_WORLD_T, w); return 1; } @@ -68,12 +69,15 @@ int w_newBody(lua_State *L) World *world = luax_checktype(L, 1, "World", PHYSICS_WORLD_T); float x = (float)luaL_optnumber(L, 2, 0.0); float y = (float)luaL_optnumber(L, 3, 0.0); - const char *type = luaL_optstring(L, 4, "static"); - Body::Type bodyType; - Body::getConstant(type, bodyType); + + Body::Type btype = Body::BODY_STATIC; + const char *typestr = lua_isnoneornil(L, 4) ? 0 : lua_tostring(L, 4); + if (typestr && !Body::getConstant(typestr, btype)) + return luaL_error(L, "Invalid Body type: %s", typestr); + Body *body; - ASSERT_GUARD(body = instance->newBody(world, x, y, bodyType);) - luax_newtype(L, "Body", PHYSICS_BODY_T, (void *)body); + EXCEPT_GUARD(body = instance->newBody(world, x, y, btype);) + luax_pushtype(L, "Body", PHYSICS_BODY_T, body); return 1; } @@ -83,8 +87,8 @@ int w_newFixture(lua_State *L) Shape *shape = luax_checkshape(L, 2); float density = (float)luaL_optnumber(L, 3, 1.0f); Fixture *fixture; - ASSERT_GUARD(fixture = instance->newFixture(body, shape, density);) - luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)fixture); + EXCEPT_GUARD(fixture = instance->newFixture(body, shape, density);) + luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, fixture); return 1; } @@ -96,8 +100,8 @@ int w_newCircleShape(lua_State *L) { float radius = (float)luaL_checknumber(L, 1); CircleShape *shape; - ASSERT_GUARD(shape = instance->newCircleShape(radius);) - luax_newtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, (void *)shape); + EXCEPT_GUARD(shape = instance->newCircleShape(radius);) + luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape); return 1; } else if (top == 3) @@ -106,8 +110,8 @@ int w_newCircleShape(lua_State *L) float y = (float)luaL_checknumber(L, 2); float radius = (float)luaL_checknumber(L, 3); CircleShape *shape; - ASSERT_GUARD(shape = instance->newCircleShape(x, y, radius);) - luax_newtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, (void *)shape); + EXCEPT_GUARD(shape = instance->newCircleShape(x, y, radius);) + luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape); return 1; } else @@ -123,8 +127,8 @@ int w_newRectangleShape(lua_State *L) float w = (float)luaL_checknumber(L, 1); float h = (float)luaL_checknumber(L, 2); PolygonShape *shape; - ASSERT_GUARD(shape = instance->newRectangleShape(w, h);) - luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)shape); + EXCEPT_GUARD(shape = instance->newRectangleShape(w, h);) + luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape); return 1; } else if (top == 4 || top == 5) @@ -135,8 +139,8 @@ int w_newRectangleShape(lua_State *L) float h = (float)luaL_checknumber(L, 4); float angle = (float)luaL_optnumber(L, 5, 0); PolygonShape *shape; - ASSERT_GUARD(shape = instance->newRectangleShape(x, y, w, h, angle);) - luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)shape); + EXCEPT_GUARD(shape = instance->newRectangleShape(x, y, w, h, angle);) + luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape); return 1; } else @@ -150,19 +154,23 @@ int w_newEdgeShape(lua_State *L) float x2 = (float)luaL_checknumber(L, 3); float y2 = (float)luaL_checknumber(L, 4); EdgeShape *shape; - ASSERT_GUARD(shape = instance->newEdgeShape(x1, y1, x2, y2);) - luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, (void *)shape); + EXCEPT_GUARD(shape = instance->newEdgeShape(x1, y1, x2, y2);) + luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, shape); return 1; } int w_newPolygonShape(lua_State *L) { - ASSERT_GUARD(return instance->newPolygonShape(L);) + int ret = 0; + EXCEPT_GUARD(ret = instance->newPolygonShape(L);) + return ret; } int w_newChainShape(lua_State *L) { - ASSERT_GUARD(return instance->newChainShape(L);) + int ret = 0; + EXCEPT_GUARD(ret = instance->newChainShape(L);) + return ret; } int w_newDistanceJoint(lua_State *L) @@ -175,8 +183,8 @@ int w_newDistanceJoint(lua_State *L) float y2 = (float)luaL_checknumber(L, 6); bool collideConnected = luax_optboolean(L, 7, false); DistanceJoint *j; - ASSERT_GUARD(j = instance->newDistanceJoint(body1, body2, x1, y1, x2, y2, collideConnected);) - luax_newtype(L, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newDistanceJoint(body1, body2, x1, y1, x2, y2, collideConnected);) + luax_pushtype(L, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T, j); return 1; } @@ -186,8 +194,8 @@ int w_newMouseJoint(lua_State *L) float x = (float)luaL_checknumber(L, 2); float y = (float)luaL_checknumber(L, 3); MouseJoint *j; - ASSERT_GUARD(j = instance->newMouseJoint(body, x, y);) - luax_newtype(L, "MouseJoint", PHYSICS_MOUSE_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newMouseJoint(body, x, y);) + luax_pushtype(L, "MouseJoint", PHYSICS_MOUSE_JOINT_T, j); return 1; } @@ -199,8 +207,8 @@ int w_newRevoluteJoint(lua_State *L) float y = (float)luaL_checknumber(L, 4); bool collideConnected = luax_optboolean(L, 5, false); RevoluteJoint *j; - ASSERT_GUARD(j = instance->newRevoluteJoint(body1, body2, x, y, collideConnected);) - luax_newtype(L, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newRevoluteJoint(body1, body2, x, y, collideConnected);) + luax_pushtype(L, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T, j); return 1; } @@ -229,8 +237,8 @@ int w_newPrismaticJoint(lua_State *L) collideConnected = luax_optboolean(L, 7, false); } PrismaticJoint *j; - ASSERT_GUARD(j = instance->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);) - luax_newtype(L, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);) + luax_pushtype(L, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T, j); return 1; } @@ -250,8 +258,8 @@ int w_newPulleyJoint(lua_State *L) bool collideConnected = luax_optboolean(L, 12, true); // PulleyJoints default to colliding connected bodies, see b2PulleyJoint.h PulleyJoint *j; - ASSERT_GUARD(j = instance->newPulleyJoint(body1, body2, b2Vec2(gx1,gy1), b2Vec2(gx2,gy2), b2Vec2(x1,y1), b2Vec2(x2,y2), ratio, collideConnected);) - luax_newtype(L, "PulleyJoint", PHYSICS_PULLEY_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newPulleyJoint(body1, body2, b2Vec2(gx1,gy1), b2Vec2(gx2,gy2), b2Vec2(x1,y1), b2Vec2(x2,y2), ratio, collideConnected);) + luax_pushtype(L, "PulleyJoint", PHYSICS_PULLEY_JOINT_T, j); return 1; } @@ -263,8 +271,8 @@ int w_newGearJoint(lua_State *L) bool collideConnected = luax_optboolean(L, 4, false); GearJoint *j; - ASSERT_GUARD(j = instance->newGearJoint(joint1, joint2, ratio, collideConnected);) - luax_newtype(L, "GearJoint", PHYSICS_GEAR_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newGearJoint(joint1, joint2, ratio, collideConnected);) + luax_pushtype(L, "GearJoint", PHYSICS_GEAR_JOINT_T, j); return 1; } @@ -289,8 +297,8 @@ int w_newFrictionJoint(lua_State *L) collideConnected = luax_optboolean(L, 5, false); } FrictionJoint *j; - ASSERT_GUARD(j = instance->newFrictionJoint(body1, body2, xA, yA, xB, yB, collideConnected);) - luax_newtype(L, "FrictionJoint", PHYSICS_FRICTION_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newFrictionJoint(body1, body2, xA, yA, xB, yB, collideConnected);) + luax_pushtype(L, "FrictionJoint", PHYSICS_FRICTION_JOINT_T, j); return 1; } @@ -315,8 +323,8 @@ int w_newWeldJoint(lua_State *L) collideConnected = luax_optboolean(L, 5, false); } WeldJoint *j; - ASSERT_GUARD(j = instance->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected);) - luax_newtype(L, "WeldJoint", PHYSICS_WELD_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected);) + luax_pushtype(L, "WeldJoint", PHYSICS_WELD_JOINT_T, j); return 1; } @@ -346,8 +354,8 @@ int w_newWheelJoint(lua_State *L) } WheelJoint *j; - ASSERT_GUARD(j = instance->newWheelJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);) - luax_newtype(L, "WheelJoint", PHYSICS_WHEEL_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newWheelJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);) + luax_pushtype(L, "WheelJoint", PHYSICS_WHEEL_JOINT_T, j); return 1; } @@ -362,8 +370,26 @@ int w_newRopeJoint(lua_State *L) float maxLength = (float)luaL_checknumber(L, 7); bool collideConnected = luax_optboolean(L, 8, false); RopeJoint *j; - ASSERT_GUARD(j = instance->newRopeJoint(body1, body2, x1, y1, x2, y2, maxLength, collideConnected);) - luax_newtype(L, "RopeJoint", PHYSICS_ROPE_JOINT_T, (void *)j); + EXCEPT_GUARD(j = instance->newRopeJoint(body1, body2, x1, y1, x2, y2, maxLength, collideConnected);) + luax_pushtype(L, "RopeJoint", PHYSICS_ROPE_JOINT_T, j); + return 1; +} + +int w_newMotorJoint(lua_State *L) +{ + Body *body1 = luax_checktype(L, 1, "Body", PHYSICS_BODY_T); + Body *body2 = luax_checktype(L, 2, "Body", PHYSICS_BODY_T); + MotorJoint *j = 0; + if (!lua_isnoneornil(L, 3)) + { + float correctionFactor = (float)luaL_checknumber(L, 3); + EXCEPT_GUARD(j = instance->newMotorJoint(body1, body2, correctionFactor);) + } + else + { + EXCEPT_GUARD(j = instance->newMotorJoint(body1, body2);) + } + luax_pushtype(L, "MotorJoint", PHYSICS_MOTOR_JOINT_T, j); return 1; } @@ -375,14 +401,7 @@ int w_getDistance(lua_State *L) int w_setMeter(lua_State *L) { int arg1 = luaL_checkint(L, 1); - try - { - Physics::setMeter(arg1); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(Physics::setMeter(arg1);) return 0; } @@ -413,6 +432,7 @@ static const luaL_Reg functions[] = { "newWeldJoint", w_newWeldJoint }, { "newWheelJoint", w_newWheelJoint }, { "newRopeJoint", w_newRopeJoint }, + { "newMotorJoint", w_newMotorJoint }, { "getDistance", w_getDistance }, { "getMeter", w_getMeter }, { "setMeter", w_setMeter }, @@ -441,6 +461,7 @@ static const lua_CFunction types[] = luaopen_weldjoint, luaopen_wheeljoint, luaopen_ropejoint, + luaopen_motorjoint, 0 }; @@ -448,14 +469,7 @@ extern "C" int luaopen_love_physics(lua_State *L) { if (instance == 0) { - try - { - instance = new Physics(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new Physics();) } else instance->retain(); diff --git a/src/modules/physics/box2d/wrap_Physics.h b/src/modules/physics/box2d/wrap_Physics.h index 9aac11d94..52a6bb97e 100644 --- a/src/modules/physics/box2d/wrap_Physics.h +++ b/src/modules/physics/box2d/wrap_Physics.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -25,8 +25,6 @@ #include "common/config.h" #include "Physics.h" -#define ASSERT_GUARD(A) try { A } catch (love::Exception & e) { return luaL_error(L, "%s", e.what()); } - namespace love { namespace physics @@ -52,6 +50,7 @@ int w_newFrictionJoint(lua_State *L); int w_newWeldJoint(lua_State *L); int w_newWheelJoint(lua_State *L); int w_newRopeJoint(lua_State *L); +int w_newMotorJoint(lua_State *L); int w_getDistance(lua_State *L); int w_setMeter(lua_State *L); int w_getMeter(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_PolygonShape.cpp b/src/modules/physics/box2d/wrap_PolygonShape.cpp index 948d39ef0..2d371016e 100644 --- a/src/modules/physics/box2d/wrap_PolygonShape.cpp +++ b/src/modules/physics/box2d/wrap_PolygonShape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,9 +39,17 @@ int w_PolygonShape_getPoints(lua_State *L) return t->getPoints(L); } +int w_PolygonShape_validate(lua_State *L) +{ + PolygonShape *t = luax_checkpolygonshape(L, 1); + luax_pushboolean(L, t->validate()); + return 1; +} + static const luaL_Reg functions[] = { { "getPoints", w_PolygonShape_getPoints }, + { "validate", w_PolygonShape_validate }, // From Shape. { "getType", w_Shape_getType }, { "getRadius", w_Shape_getRadius }, diff --git a/src/modules/physics/box2d/wrap_PolygonShape.h b/src/modules/physics/box2d/wrap_PolygonShape.h index 46ebee91b..45a0ef018 100644 --- a/src/modules/physics/box2d/wrap_PolygonShape.h +++ b/src/modules/physics/box2d/wrap_PolygonShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -35,6 +35,7 @@ namespace box2d PolygonShape *luax_checkpolygonshape(lua_State *L, int idx); int w_PolygonShape_getPoints(lua_State *L); +int w_PolygonShape_validate(lua_State *L); extern "C" int luaopen_polygonshape(lua_State *L); } // box2d diff --git a/src/modules/physics/box2d/wrap_PrismaticJoint.cpp b/src/modules/physics/box2d/wrap_PrismaticJoint.cpp index da56a0526..e3514bf41 100644 --- a/src/modules/physics/box2d/wrap_PrismaticJoint.cpp +++ b/src/modules/physics/box2d/wrap_PrismaticJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,6 +19,7 @@ **/ #include "wrap_PrismaticJoint.h" +#include "wrap_Physics.h" namespace love { @@ -49,11 +50,11 @@ int w_PrismaticJoint_getJointSpeed(lua_State *L) return 1; } -int w_PrismaticJoint_enableMotor(lua_State *L) +int w_PrismaticJoint_setMotorEnabled(lua_State *L) { PrismaticJoint *t = luax_checkprismaticjoint(L, 1); bool arg1 = luax_toboolean(L, 2); - t->enableMotor(arg1); + t->setMotorEnabled(arg1); return 0; } @@ -102,18 +103,18 @@ int w_PrismaticJoint_getMaxMotorForce(lua_State *L) return 1; } -int w_PrismaticJoint_enableLimit(lua_State *L) +int w_PrismaticJoint_setLimitsEnabled(lua_State *L) { PrismaticJoint *t = luax_checkprismaticjoint(L, 1); bool arg1 = luax_toboolean(L, 2); - t->enableLimit(arg1); + t->setLimitsEnabled(arg1); return 0; } -int w_PrismaticJoint_isLimitEnabled(lua_State *L) +int w_PrismaticJoint_hasLimitsEnabled(lua_State *L) { PrismaticJoint *t = luax_checkprismaticjoint(L, 1); - luax_pushboolean(L, t->isLimitEnabled()); + luax_pushboolean(L, t->hasLimitsEnabled()); return 1; } @@ -121,7 +122,7 @@ int w_PrismaticJoint_setUpperLimit(lua_State *L) { PrismaticJoint *t = luax_checkprismaticjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setUpperLimit(arg1); + EXCEPT_GUARD(t->setUpperLimit(arg1);) return 0; } @@ -129,7 +130,7 @@ int w_PrismaticJoint_setLowerLimit(lua_State *L) { PrismaticJoint *t = luax_checkprismaticjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setLowerLimit(arg1); + EXCEPT_GUARD(t->setLowerLimit(arg1);) return 0; } @@ -138,7 +139,7 @@ int w_PrismaticJoint_setLimits(lua_State *L) PrismaticJoint *t = luax_checkprismaticjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); float arg2 = (float)luaL_checknumber(L, 3); - t->setLimits(arg1, arg2); + EXCEPT_GUARD(t->setLimits(arg1, arg2);) return 0; } @@ -167,15 +168,15 @@ static const luaL_Reg functions[] = { { "getJointTranslation", w_PrismaticJoint_getJointTranslation }, { "getJointSpeed", w_PrismaticJoint_getJointSpeed }, - { "enableMotor", w_PrismaticJoint_enableMotor }, + { "setMotorEnabled", w_PrismaticJoint_setMotorEnabled }, { "isMotorEnabled", w_PrismaticJoint_isMotorEnabled }, { "setMaxMotorForce", w_PrismaticJoint_setMaxMotorForce }, { "setMotorSpeed", w_PrismaticJoint_setMotorSpeed }, { "getMotorSpeed", w_PrismaticJoint_getMotorSpeed }, { "getMotorForce", w_PrismaticJoint_getMotorForce }, { "getMaxMotorForce", w_PrismaticJoint_getMaxMotorForce }, - { "enableLimit", w_PrismaticJoint_enableLimit }, - { "isLimitEnabled", w_PrismaticJoint_isLimitEnabled }, + { "setLimitsEnabled", w_PrismaticJoint_setLimitsEnabled }, + { "hasLimitsEnabled", w_PrismaticJoint_hasLimitsEnabled }, { "setUpperLimit", w_PrismaticJoint_setUpperLimit }, { "setLowerLimit", w_PrismaticJoint_setLowerLimit }, { "setLimits", w_PrismaticJoint_setLimits }, diff --git a/src/modules/physics/box2d/wrap_PrismaticJoint.h b/src/modules/physics/box2d/wrap_PrismaticJoint.h index a515137ab..8d9c90fda 100644 --- a/src/modules/physics/box2d/wrap_PrismaticJoint.h +++ b/src/modules/physics/box2d/wrap_PrismaticJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,15 +36,15 @@ namespace box2d PrismaticJoint *luax_checkprismaticjoint(lua_State *L, int idx); int w_PrismaticJoint_getJointTranslation(lua_State *L); int w_PrismaticJoint_getJointSpeed(lua_State *L); -int w_PrismaticJoint_enableMotor(lua_State *L); +int w_PrismaticJoint_setMotorEnabled(lua_State *L); int w_PrismaticJoint_isMotorEnabled(lua_State *L); int w_PrismaticJoint_setMaxMotorForce(lua_State *L); int w_PrismaticJoint_setMotorSpeed(lua_State *L); int w_PrismaticJoint_getMotorSpeed(lua_State *L); int w_PrismaticJoint_getMotorForce(lua_State *L); int w_PrismaticJoint_getMaxMotorForce(lua_State *L); -int w_PrismaticJoint_enableLimit(lua_State *L); -int w_PrismaticJoint_isLimitEnabled(lua_State *L); +int w_PrismaticJoint_setLimitsEnabled(lua_State *L); +int w_PrismaticJoint_hasLimitsEnabled(lua_State *L); int w_PrismaticJoint_setUpperLimit(lua_State *L); int w_PrismaticJoint_setLowerLimit(lua_State *L); int w_PrismaticJoint_setLimits(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_PulleyJoint.cpp b/src/modules/physics/box2d/wrap_PulleyJoint.cpp index 55bf003c1..1e9e01aa2 100644 --- a/src/modules/physics/box2d/wrap_PulleyJoint.cpp +++ b/src/modules/physics/box2d/wrap_PulleyJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_PulleyJoint.h b/src/modules/physics/box2d/wrap_PulleyJoint.h index 9d921e3d2..47dbe4d18 100644 --- a/src/modules/physics/box2d/wrap_PulleyJoint.h +++ b/src/modules/physics/box2d/wrap_PulleyJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_RevoluteJoint.cpp b/src/modules/physics/box2d/wrap_RevoluteJoint.cpp index 4d91a4265..e510dcf3b 100644 --- a/src/modules/physics/box2d/wrap_RevoluteJoint.cpp +++ b/src/modules/physics/box2d/wrap_RevoluteJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -19,6 +19,7 @@ **/ #include "wrap_RevoluteJoint.h" +#include "wrap_Physics.h" namespace love { @@ -49,11 +50,11 @@ int w_RevoluteJoint_getJointSpeed(lua_State *L) return 1; } -int w_RevoluteJoint_enableMotor(lua_State *L) +int w_RevoluteJoint_setMotorEnabled(lua_State *L) { RevoluteJoint *t = luax_checkrevolutejoint(L, 1); bool arg1 = luax_toboolean(L, 2); - t->enableMotor(arg1); + t->setMotorEnabled(arg1); return 0; } @@ -102,18 +103,18 @@ int w_RevoluteJoint_getMaxMotorTorque(lua_State *L) return 1; } -int w_RevoluteJoint_enableLimit(lua_State *L) +int w_RevoluteJoint_setLimitsEnabled(lua_State *L) { RevoluteJoint *t = luax_checkrevolutejoint(L, 1); bool arg1 = luax_toboolean(L, 2); - t->enableLimit(arg1); + t->setLimitsEnabled(arg1); return 0; } -int w_RevoluteJoint_isLimitEnabled(lua_State *L) +int w_RevoluteJoint_hasLimitsEnabled(lua_State *L) { RevoluteJoint *t = luax_checkrevolutejoint(L, 1); - luax_pushboolean(L, t->isLimitEnabled()); + luax_pushboolean(L, t->hasLimitsEnabled()); return 1; } @@ -121,7 +122,7 @@ int w_RevoluteJoint_setUpperLimit(lua_State *L) { RevoluteJoint *t = luax_checkrevolutejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setUpperLimit(arg1); + EXCEPT_GUARD(t->setUpperLimit(arg1);) return 0; } @@ -129,7 +130,7 @@ int w_RevoluteJoint_setLowerLimit(lua_State *L) { RevoluteJoint *t = luax_checkrevolutejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setLowerLimit(arg1); + EXCEPT_GUARD(t->setLowerLimit(arg1);) return 0; } @@ -138,7 +139,7 @@ int w_RevoluteJoint_setLimits(lua_State *L) RevoluteJoint *t = luax_checkrevolutejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); float arg2 = (float)luaL_checknumber(L, 3); - t->setLimits(arg1, arg2); + EXCEPT_GUARD(t->setLimits(arg1, arg2);) return 0; } @@ -167,15 +168,15 @@ static const luaL_Reg functions[] = { { "getJointAngle", w_RevoluteJoint_getJointAngle }, { "getJointSpeed", w_RevoluteJoint_getJointSpeed }, - { "enableMotor", w_RevoluteJoint_enableMotor }, + { "setMotorEnabled", w_RevoluteJoint_setMotorEnabled }, { "isMotorEnabled", w_RevoluteJoint_isMotorEnabled }, { "setMaxMotorTorque", w_RevoluteJoint_setMaxMotorTorque }, { "setMotorSpeed", w_RevoluteJoint_setMotorSpeed }, { "getMotorSpeed", w_RevoluteJoint_getMotorSpeed }, { "getMotorTorque", w_RevoluteJoint_getMotorTorque }, { "getMaxMotorTorque", w_RevoluteJoint_getMaxMotorTorque }, - { "enableLimit", w_RevoluteJoint_enableLimit }, - { "isLimitEnabled", w_RevoluteJoint_isLimitEnabled }, + { "setLimitsEnabled", w_RevoluteJoint_setLimitsEnabled }, + { "hasLimitsEnabled", w_RevoluteJoint_hasLimitsEnabled }, { "setUpperLimit", w_RevoluteJoint_setUpperLimit }, { "setLowerLimit", w_RevoluteJoint_setLowerLimit }, { "setLimits", w_RevoluteJoint_setLimits }, diff --git a/src/modules/physics/box2d/wrap_RevoluteJoint.h b/src/modules/physics/box2d/wrap_RevoluteJoint.h index 31e1f59fc..a6b975712 100644 --- a/src/modules/physics/box2d/wrap_RevoluteJoint.h +++ b/src/modules/physics/box2d/wrap_RevoluteJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,15 +36,15 @@ namespace box2d RevoluteJoint *luax_checkrevolutejoint(lua_State *L, int idx); int w_RevoluteJoint_getJointAngle(lua_State *L); int w_RevoluteJoint_getJointSpeed(lua_State *L); -int w_RevoluteJoint_enableMotor(lua_State *L); +int w_RevoluteJoint_setMotorEnabled(lua_State *L); int w_RevoluteJoint_isMotorEnabled(lua_State *L); int w_RevoluteJoint_setMaxMotorTorque(lua_State *L); int w_RevoluteJoint_setMotorSpeed(lua_State *L); int w_RevoluteJoint_getMotorSpeed(lua_State *L); int w_RevoluteJoint_getMotorTorque(lua_State *L); int w_RevoluteJoint_getMaxMotorTorque(lua_State *L); -int w_RevoluteJoint_enableLimit(lua_State *L); -int w_RevoluteJoint_isLimitEnabled(lua_State *L); +int w_RevoluteJoint_setLimitsEnabled(lua_State *L); +int w_RevoluteJoint_hasLimitsEnabled(lua_State *L); int w_RevoluteJoint_setUpperLimit(lua_State *L); int w_RevoluteJoint_setLowerLimit(lua_State *L); int w_RevoluteJoint_setLimits(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_RopeJoint.cpp b/src/modules/physics/box2d/wrap_RopeJoint.cpp index c0deec320..907b519c5 100644 --- a/src/modules/physics/box2d/wrap_RopeJoint.cpp +++ b/src/modules/physics/box2d/wrap_RopeJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_RopeJoint.h b/src/modules/physics/box2d/wrap_RopeJoint.h index 5dd07351a..bf6c093cc 100644 --- a/src/modules/physics/box2d/wrap_RopeJoint.h +++ b/src/modules/physics/box2d/wrap_RopeJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_Shape.cpp b/src/modules/physics/box2d/wrap_Shape.cpp index 958e62a44..d31d0fae5 100644 --- a/src/modules/physics/box2d/wrap_Shape.cpp +++ b/src/modules/physics/box2d/wrap_Shape.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -75,7 +75,9 @@ int w_Shape_rayCast(lua_State *L) { Shape *t = luax_checkshape(L, 1); lua_remove(L, 1); - ASSERT_GUARD(return t->rayCast(L);) + int ret = 0; + EXCEPT_GUARD(ret = t->rayCast(L);) + return ret; } int w_Shape_computeAABB(lua_State *L) diff --git a/src/modules/physics/box2d/wrap_Shape.h b/src/modules/physics/box2d/wrap_Shape.h index 6177de418..bc992f469 100644 --- a/src/modules/physics/box2d/wrap_Shape.h +++ b/src/modules/physics/box2d/wrap_Shape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index 89c0caf3c..84476ee05 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_WeldJoint.h b/src/modules/physics/box2d/wrap_WeldJoint.h index aa75d5ee8..52fedab92 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.h +++ b/src/modules/physics/box2d/wrap_WeldJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/physics/box2d/wrap_WheelJoint.cpp b/src/modules/physics/box2d/wrap_WheelJoint.cpp index 7ae00db19..861b61904 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -49,11 +49,11 @@ int w_WheelJoint_getJointSpeed(lua_State *L) return 1; } -int w_WheelJoint_enableMotor(lua_State *L) +int w_WheelJoint_setMotorEnabled(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); bool arg1 = luax_toboolean(L, 2); - t->enableMotor(arg1); + t->setMotorEnabled(arg1); return 0; } @@ -136,7 +136,7 @@ static const luaL_Reg functions[] = { { "getJointTranslation", w_WheelJoint_getJointTranslation }, { "getJointSpeed", w_WheelJoint_getJointSpeed }, - { "enableMotor", w_WheelJoint_enableMotor }, + { "setMotorEnabled", w_WheelJoint_setMotorEnabled }, { "isMotorEnabled", w_WheelJoint_isMotorEnabled }, { "setMotorSpeed", w_WheelJoint_setMotorSpeed }, { "getMotorSpeed", w_WheelJoint_getMotorSpeed }, diff --git a/src/modules/physics/box2d/wrap_WheelJoint.h b/src/modules/physics/box2d/wrap_WheelJoint.h index ed22c0256..0cd8c68f1 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.h +++ b/src/modules/physics/box2d/wrap_WheelJoint.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,7 +36,7 @@ namespace box2d WheelJoint *luax_checkwheeljoint(lua_State *L, int idx); int w_WheelJoint_getJointTranslation(lua_State *L); int w_WheelJoint_getJointSpeed(lua_State *L); -int w_WheelJoint_enableMotor(lua_State *L); +int w_WheelJoint_setMotorEnabled(lua_State *L); int w_WheelJoint_isMotorEnabled(lua_State *L); int w_WheelJoint_setMotorSpeed(lua_State *L); int w_WheelJoint_getMotorSpeed(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_World.cpp b/src/modules/physics/box2d/wrap_World.cpp index aed67ee22..b4739f24c 100644 --- a/src/modules/physics/box2d/wrap_World.cpp +++ b/src/modules/physics/box2d/wrap_World.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,7 +39,7 @@ int w_World_update(lua_State *L) { World *t = luax_checkworld(L, 1); float dt = (float)luaL_checknumber(L, 2); - ASSERT_GUARD(t->update(dt);) + EXCEPT_GUARD(t->update(dt);) return 0; } @@ -87,18 +87,27 @@ int w_World_getGravity(lua_State *L) return t->getGravity(L); } -int w_World_setAllowSleeping(lua_State *L) +int w_World_translateOrigin(lua_State *L) { World *t = luax_checkworld(L, 1); - bool b = luax_toboolean(L, 2); - t->setAllowSleeping(b); + float arg1 = (float)luaL_checknumber(L, 2); + float arg2 = (float)luaL_checknumber(L, 3); + EXCEPT_GUARD(t->translateOrigin(arg1, arg2);) return 0; } -int w_World_getAllowSleeping(lua_State *L) +int w_World_setSleepingAllowed(lua_State *L) { World *t = luax_checkworld(L, 1); - luax_pushboolean(L, t->getAllowSleeping()); + bool b = luax_toboolean(L, 2); + t->setSleepingAllowed(b); + return 0; +} + +int w_World_isSleepingAllowed(lua_State *L) +{ + World *t = luax_checkworld(L, 1); + luax_pushboolean(L, t->isSleepingAllowed()); return 1; } @@ -162,20 +171,15 @@ int w_World_rayCast(lua_State *L) { World *t = luax_checkworld(L, 1); lua_remove(L, 1); - ASSERT_GUARD(return t->rayCast(L);) + int ret = 0; + EXCEPT_GUARD(ret = t->rayCast(L);) + return ret; } int w_World_destroy(lua_State *L) { World *t = luax_checkworld(L, 1); - try - { - t->destroy(); - } - catch(love::Exception &e) - { - luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(t->destroy();) return 0; } @@ -189,8 +193,9 @@ static const luaL_Reg functions[] = { "getContactFilter", w_World_getContactFilter }, { "setGravity", w_World_setGravity }, { "getGravity", w_World_getGravity }, - { "setAllowSleeping", w_World_setAllowSleeping }, - { "getAllowSleeping", w_World_getAllowSleeping }, + { "translateOrigin", w_World_translateOrigin }, + { "setSleepingAllowed", w_World_setSleepingAllowed }, + { "isSleepingAllowed", w_World_isSleepingAllowed }, { "isLocked", w_World_isLocked }, { "getBodyCount", w_World_getBodyCount }, { "getJointCount", w_World_getJointCount }, diff --git a/src/modules/physics/box2d/wrap_World.h b/src/modules/physics/box2d/wrap_World.h index 8946fe620..1a5d15c2c 100644 --- a/src/modules/physics/box2d/wrap_World.h +++ b/src/modules/physics/box2d/wrap_World.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -42,8 +42,9 @@ int w_World_setContactFilter(lua_State *L); int w_World_getContactFilter(lua_State *L); int w_World_setGravity(lua_State *L); int w_World_getGravity(lua_State *L); -int w_World_setAllowSleeping(lua_State *L); -int w_World_getAllowSleeping(lua_State *L); +int w_World_translateOrigin(lua_State *L); +int w_World_setSleepingAllowed(lua_State *L); +int w_World_isSleepingAllowed(lua_State *L); int w_World_isLocked(lua_State *L); int w_World_getBodyCount(lua_State *L); int w_World_getJointCount(lua_State *L); diff --git a/src/modules/sound/Decoder.h b/src/modules/sound/Decoder.h index 1b17fc556..3701c1e8f 100644 --- a/src/modules/sound/Decoder.h +++ b/src/modules/sound/Decoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -55,7 +55,7 @@ public: /** * 16 bit audio is the default. **/ - static const int DEFAULT_BITS = 16; + static const int DEFAULT_BIT_DEPTH = 16; /** * Creates a deep of itself. The sound stream can (and should) be @@ -126,7 +126,7 @@ public: * Gets the number of bits per sample. Supported values are 8 or 16. * @return Either 8, 16, or 0 if unsupported. **/ - virtual int getBits() const = 0; + virtual int getBitDepth() const = 0; /** * Gets the sample rate for the Decoder, that is, samples per second. diff --git a/src/modules/sound/Sound.cpp b/src/modules/sound/Sound.cpp index 7249a5d4e..afe4199d5 100644 --- a/src/modules/sound/Sound.cpp +++ b/src/modules/sound/Sound.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -34,9 +34,9 @@ SoundData *Sound::newSoundData(Decoder *decoder) return new SoundData(decoder); } -SoundData *Sound::newSoundData(int samples, int sampleRate, int bits, int channels) +SoundData *Sound::newSoundData(int samples, int sampleRate, int bitDepth, int channels) { - return new SoundData(samples, sampleRate, bits, channels); + return new SoundData(samples, sampleRate, bitDepth, channels); } diff --git a/src/modules/sound/Sound.h b/src/modules/sound/Sound.h index e1e296ada..72bb552cb 100644 --- a/src/modules/sound/Sound.h +++ b/src/modules/sound/Sound.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -58,20 +58,19 @@ public: /** * Creates a new SoundData with the specified number of samples and format. - * @param duration In seconds. + * @param samples The number of samples. * @param sampleRate Number of samples per second. - * @param bits Bits per sample (8 or 16). + * @param bitDepth Bits per sample (8 or 16). * @param channels Either 1 for mono, or 2 for stereo. * @return A new SoundData object, or zero in case of errors. **/ - SoundData *newSoundData(int samples, int sampleRate, int bits, int channels); + SoundData *newSoundData(int samples, int sampleRate, int bitDepth, int channels); /** * Attempts to find a decoder for the encoded sound data in the * specified file. * @param file The file with encoded sound data. * @param bufferSize The size of each decoded chunk. - * @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. **/ virtual Decoder *newDecoder(filesystem::FileData *file, int bufferSize) = 0; diff --git a/src/modules/sound/SoundData.cpp b/src/modules/sound/SoundData.cpp index f0646f67f..edc9720a6 100644 --- a/src/modules/sound/SoundData.cpp +++ b/src/modules/sound/SoundData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -38,10 +38,10 @@ SoundData::SoundData(Decoder *decoder) : data(0) , size(0) , sampleRate(Decoder::DEFAULT_SAMPLE_RATE) - , bits(0) + , bitDepth(0) , channels(0) { - size_t bufferSize = 524288; + size_t bufferSize = 524288; // 0x80000 int decoded = decoder->decode(); while (decoded > 0) @@ -79,41 +79,28 @@ SoundData::SoundData(Decoder *decoder) data = (char *) realloc(data, size); channels = decoder->getChannels(); - bits = decoder->getBits(); + bitDepth = decoder->getBitDepth(); sampleRate = decoder->getSampleRate(); } -SoundData::SoundData(int samples, int sampleRate, int bits, int channels) +SoundData::SoundData(int samples, int sampleRate, int bitDepth, int channels) : data(0) - , size(samples*(bits/8)*channels) - , sampleRate(sampleRate) - , bits(bits) - , channels(channels) + , size(0) + , sampleRate(0) + , bitDepth(0) + , channels(0) { - double realsize = samples; - realsize *= (bits/8)*channels; - if (realsize > INT_MAX) - throw love::Exception("Data is too big!"); - data = (char *)malloc(size); - if (!data) - throw love::Exception("Not enough memory."); + load(samples, sampleRate, bitDepth, channels); } -SoundData::SoundData(void *d, int samples, int sampleRate, int bits, int channels) +SoundData::SoundData(void *d, int samples, int sampleRate, int bitDepth, int channels) : data(0) - , size(samples*(bits/8)*channels) - , sampleRate(sampleRate) - , bits(bits) - , channels(channels) + , size(0) + , sampleRate(0) + , bitDepth(0) + , channels(0) { - double realsize = samples; - realsize *= (bits/8)*channels; - if (realsize > INT_MAX) - throw love::Exception("Data is too big!"); - data = (char *)malloc(size); - if (!data) - throw love::Exception("Not enough memory."); - memcpy(data, d, size); + load(samples, sampleRate, bitDepth, channels, d); } SoundData::~SoundData() @@ -122,6 +109,44 @@ SoundData::~SoundData() free(data); } +void SoundData::load(int samples, int sampleRate, int bitDepth, int channels, void *newData) +{ + if (samples <= 0) + throw love::Exception("Invalid sample count: %d", samples); + + if (sampleRate <= 0) + throw love::Exception("Invalid sample rate: %d", sampleRate); + + if (bitDepth <= 0) + throw love::Exception("Invalid bit depth: %d", bitDepth); + + if (channels <= 0) + throw love::Exception("Invalid channel count: %d", channels); + + if (data != 0) + { + free(data); + data = 0; + } + + size = samples * (bitDepth / 8) * channels; + this->sampleRate = sampleRate; + this->bitDepth = bitDepth; + this->channels = channels; + + double realsize = samples; + realsize *= (bitDepth / 8) * channels; + if (realsize > INT_MAX) + throw love::Exception("Data is too big!"); + + data = (char *)malloc(size); + if (!data) + throw love::Exception("Not enough memory."); + + if (newData) + memcpy(data, newData, size); +} + void *SoundData::getData() const { return (void *)data; @@ -137,9 +162,9 @@ int SoundData::getChannels() const return channels; } -int SoundData::getBits() const +int SoundData::getBitDepth() const { - return bits; + return bitDepth; } int SoundData::getSampleRate() const @@ -147,18 +172,23 @@ int SoundData::getSampleRate() const return sampleRate; } -int SoundData::getDuration() const +int SoundData::getSampleCount() const { - return size/(channels*sampleRate*bits/8); + return (size/channels)/(bitDepth/8); +} + +float SoundData::getDuration() const +{ + return float(size) / (channels*sampleRate*bitDepth/8); } void SoundData::setSample(int i, float sample) { // Check range. - if (i < 0 || i >= size/(bits/8)) - return; + if (i < 0 || i >= size/(bitDepth/8)) + throw love::Exception("Attempt to set out-of-range sample!"); - if (bits == 16) + if (bitDepth == 16) { short *s = (short *)data; s[i] = (short)(sample*(float)SHRT_MAX); @@ -174,10 +204,10 @@ void SoundData::setSample(int i, float sample) float SoundData::getSample(int i) const { // Check range. - if (i < 0 || i >= size/(bits/8)) - return 0; + if (i < 0 || i >= size/(bitDepth/8)) + throw love::Exception("Attempt to get out-of-range sample!"); - if (bits == 16) + if (bitDepth == 16) { short *s = (short *)data; return (float)s[i]/(float)SHRT_MAX; diff --git a/src/modules/sound/SoundData.h b/src/modules/sound/SoundData.h index 09a40c60a..d6b7528db 100644 --- a/src/modules/sound/SoundData.h +++ b/src/modules/sound/SoundData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -36,8 +36,8 @@ class SoundData : public love::Data public: SoundData(Decoder *decoder); - SoundData(int samples, int sampleRate, int bits, int channels); - SoundData(void *d, int samples, int sampleRate, int bits, int channels); + SoundData(int samples, int sampleRate, int bitDepth, int channels); + SoundData(void *d, int samples, int sampleRate, int bitDepth, int channels); virtual ~SoundData(); @@ -46,21 +46,24 @@ public: int getSize() const; virtual int getChannels() const; - virtual int getBits() const; + virtual int getBitDepth() const; virtual int getSampleRate() const; + virtual int getSampleCount() const; - virtual int getDuration() const; + virtual float getDuration() const; void setSample(int i, float sample); float getSample(int i) const; private: + void load(int samples, int sampleRate, int bitDepth, int channels, void *newData = 0); + char *data; int size; int sampleRate; - int bits; + int bitDepth; int channels; }; // SoundData diff --git a/src/modules/sound/lullaby/Decoder.cpp b/src/modules/sound/lullaby/Decoder.cpp index 9af268454..8a591fc8d 100644 --- a/src/modules/sound/lullaby/Decoder.cpp +++ b/src/modules/sound/lullaby/Decoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/sound/lullaby/Decoder.h b/src/modules/sound/lullaby/Decoder.h index 5cb52bc4b..4a962960e 100644 --- a/src/modules/sound/lullaby/Decoder.h +++ b/src/modules/sound/lullaby/Decoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/sound/lullaby/FLACDecoder.cpp b/src/modules/sound/lullaby/FLACDecoder.cpp index 431685b75..1fcd8245a 100644 --- a/src/modules/sound/lullaby/FLACDecoder.cpp +++ b/src/modules/sound/lullaby/FLACDecoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -41,7 +41,7 @@ FLACDecoder::FLACDecoder(Data *data, const std::string &ext, int nbufferSize) process_until_end_of_metadata(); process_single(); seek(0); - bufferSize = 256 * getBits() * getChannels() * 2; + bufferSize = 256 * getBitDepth() * getChannels() * 2; delete[](char *) buffer; buffer = new char[bufferSize]; } @@ -98,7 +98,7 @@ int FLACDecoder::getChannels() const return get_channels(); } -int FLACDecoder::getBits() const +int FLACDecoder::getBitDepth() const { return get_bits_per_sample(); } diff --git a/src/modules/sound/lullaby/FLACDecoder.h b/src/modules/sound/lullaby/FLACDecoder.h index d0379830d..61ed54051 100644 --- a/src/modules/sound/lullaby/FLACDecoder.h +++ b/src/modules/sound/lullaby/FLACDecoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -50,7 +50,7 @@ public: bool rewind(); bool isSeekable(); int getChannels() const; - int getBits() const; + int getBitDepth() const; int getSampleRate() const; //needed for FLAC diff --git a/src/modules/sound/lullaby/GmeDecoder.cpp b/src/modules/sound/lullaby/GmeDecoder.cpp index 137000890..aa48fc283 100644 --- a/src/modules/sound/lullaby/GmeDecoder.cpp +++ b/src/modules/sound/lullaby/GmeDecoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -72,7 +72,7 @@ bool GmeDecoder::accepts(const std::string &ext) static const std::string supported[] = { "ay", "gbs", "gym", "hes", "kss", "nsf", - "nsfe", "sap", "spc", "vgm", "vgz" + "nsfe", "sap", "spc", "vgm", "vgz", "" }; for (int i = 0; !(supported[i].empty()); i++) @@ -137,7 +137,7 @@ int GmeDecoder::getChannels() const return 2; } -int GmeDecoder::getBits() const +int GmeDecoder::getBitDepth() const { return 16; } diff --git a/src/modules/sound/lullaby/GmeDecoder.h b/src/modules/sound/lullaby/GmeDecoder.h index 05a274ddd..d5c94941e 100644 --- a/src/modules/sound/lullaby/GmeDecoder.h +++ b/src/modules/sound/lullaby/GmeDecoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -27,7 +27,7 @@ #include "common/Data.h" #include "Decoder.h" -#ifdef LOVE_MACOSX +#ifdef LOVE_MACOSX_USE_FRAMEWORKS #include #else #include @@ -55,7 +55,7 @@ public: bool rewind(); bool isSeekable(); int getChannels() const; - int getBits() const; + int getBitDepth() const; private: Music_Emu *emu; diff --git a/src/modules/sound/lullaby/ModPlugDecoder.cpp b/src/modules/sound/lullaby/ModPlugDecoder.cpp index 66dc74180..4e383ea0a 100644 --- a/src/modules/sound/lullaby/ModPlugDecoder.cpp +++ b/src/modules/sound/lullaby/ModPlugDecoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -56,7 +56,7 @@ ModPlugDecoder::ModPlugDecoder(Data *data, const std::string &ext, int bufferSiz settings.mBassRange = 0; settings.mSurroundDepth = 0; settings.mSurroundDelay = 0; - settings.mLoopCount = 0; + settings.mLoopCount = -1; ModPlug_SetSettings(&settings); @@ -83,8 +83,8 @@ bool ModPlugDecoder::accepts(const std::string &ext) "699", "abc", "amf", "ams", "dbm", "dmf", "dsm", "far", "it", "j2b", "mdl", "med", "mid", "mod", "mt2", "mtm", "okt", "pat", - "psm", "s3m", "stm", "ult", "umx", "wav", - "xm", "" + "psm", "s3m", "stm", "ult", "umx", "xm", + "" }; for (int i = 0; !(supported[i].empty()); i++) @@ -137,7 +137,7 @@ int ModPlugDecoder::getChannels() const return 2; } -int ModPlugDecoder::getBits() const +int ModPlugDecoder::getBitDepth() const { return 16; } diff --git a/src/modules/sound/lullaby/ModPlugDecoder.h b/src/modules/sound/lullaby/ModPlugDecoder.h index 01e4405f1..d102fa429 100644 --- a/src/modules/sound/lullaby/ModPlugDecoder.h +++ b/src/modules/sound/lullaby/ModPlugDecoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -50,7 +50,7 @@ public: bool rewind(); bool isSeekable(); int getChannels() const; - int getBits() const; + int getBitDepth() const; private: diff --git a/src/modules/sound/lullaby/Mpg123Decoder.cpp b/src/modules/sound/lullaby/Mpg123Decoder.cpp index 96438f25b..a89b3ef68 100644 --- a/src/modules/sound/lullaby/Mpg123Decoder.cpp +++ b/src/modules/sound/lullaby/Mpg123Decoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,8 +18,6 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_NOMPG123 - #include "Mpg123Decoder.h" #include "common/Exception.h" @@ -209,7 +207,7 @@ int Mpg123Decoder::getChannels() const return channels; } -int Mpg123Decoder::getBits() const +int Mpg123Decoder::getBitDepth() const { return 16; } @@ -234,5 +232,3 @@ int Mpg123Decoder::feed(int bytes) } // lullaby } // sound } // love - -#endif // LOVE_NOMPG123 diff --git a/src/modules/sound/lullaby/Mpg123Decoder.h b/src/modules/sound/lullaby/Mpg123Decoder.h index 968540ce8..049380fd4 100644 --- a/src/modules/sound/lullaby/Mpg123Decoder.h +++ b/src/modules/sound/lullaby/Mpg123Decoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,7 +18,6 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_NOMPG123 #ifndef LOVE_SOUND_LULLABY_LIBMPG123_DECODER_H #define LOVE_SOUND_LULLABY_LIBMPG123_DECODER_H @@ -27,7 +26,7 @@ #include "Decoder.h" // libmpg123 -#ifdef LOVE_MACOSX +#ifdef LOVE_MACOSX_USE_FRAMEWORKS #include #else #include @@ -56,7 +55,7 @@ public: bool rewind(); bool isSeekable(); int getChannels() const; - int getBits() const; + int getBitDepth() const; private: @@ -77,4 +76,3 @@ private: } // love #endif // LOVE_SOUND_LULLABY_LIBMPG123_DECODER_H -#endif // LOVE_NOMPG123 diff --git a/src/modules/sound/lullaby/Sound.cpp b/src/modules/sound/lullaby/Sound.cpp index 992fb7a1d..993602006 100644 --- a/src/modules/sound/lullaby/Sound.cpp +++ b/src/modules/sound/lullaby/Sound.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -20,14 +20,20 @@ #include "common/config.h" +#include + #include "Sound.h" #include "ModPlugDecoder.h" -#include "Mpg123Decoder.h" #include "VorbisDecoder.h" #include "GmeDecoder.h" +#include "WaveDecoder.h" //#include "FLACDecoder.h" +#ifndef LOVE_NOMPG123 +# include "Mpg123Decoder.h" +#endif // LOVE_NOMPG123 + namespace love { namespace sound @@ -54,6 +60,7 @@ const char *Sound::getName() const sound::Decoder *Sound::newDecoder(love::filesystem::FileData *data, int bufferSize) { std::string ext = data->getExtension(); + std::transform(ext.begin(), ext.end(), ext.begin(), tolower); sound::Decoder *decoder = 0; @@ -70,6 +77,8 @@ sound::Decoder *Sound::newDecoder(love::filesystem::FileData *data, int bufferSi else if (GmeDecoder::accepts(ext)) decoder = new GmeDecoder(data, ext, bufferSize); #endif // LOVE_SUPPORT_GME + else if (WaveDecoder::accepts(ext)) + decoder = new WaveDecoder(data, ext, bufferSize); /*else if (FLACDecoder::accepts(ext)) decoder = new FLACDecoder(data, ext, bufferSize);*/ diff --git a/src/modules/sound/lullaby/Sound.h b/src/modules/sound/lullaby/Sound.h index d736f4454..15e38a45d 100644 --- a/src/modules/sound/lullaby/Sound.h +++ b/src/modules/sound/lullaby/Sound.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/sound/lullaby/VorbisDecoder.cpp b/src/modules/sound/lullaby/VorbisDecoder.cpp index 1165eba46..576244d2a 100644 --- a/src/modules/sound/lullaby/VorbisDecoder.cpp +++ b/src/modules/sound/lullaby/VorbisDecoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -34,13 +34,13 @@ namespace lullaby /** * CALLBACK FUNCTIONS **/ -int vorbisClose(void * /* ptr to the data that the vorbis files need*/) +static int vorbisClose(void * /* ptr to the data that the vorbis files need*/) { // Does nothing (handled elsewhere) return 1; } -size_t vorbisRead(void *ptr /* ptr to the data that the vorbis files need*/, +static size_t vorbisRead(void *ptr /* ptr to the data that the vorbis files need*/, size_t byteSize /* how big a byte is*/, size_t sizeToRead /* How much we can read*/, void *datasource /* this is a pointer to the data we passed into ov_open_callbacks (our SOggFile struct*/) @@ -72,7 +72,7 @@ size_t vorbisRead(void *ptr /* ptr to the data that the vorbis files need*/, return actualSizeToRead; } -int vorbisSeek(void *datasource /* ptr to the data that the vorbis files need*/, +static int vorbisSeek(void *datasource /* ptr to the data that the vorbis files need*/, ogg_int64_t offset /*offset from the point we wish to seek to*/, int whence /*where we want to seek to*/) { @@ -116,7 +116,7 @@ int vorbisSeek(void *datasource /* ptr to the data that the vorbis files need*/, return 0; } -long vorbisTell(void *datasource /* ptr to the data that the vorbis files need*/) +static long vorbisTell(void *datasource /* ptr to the data that the vorbis files need*/) { SOggFile *vorbisData; vorbisData = (SOggFile *) datasource; @@ -188,7 +188,7 @@ int VorbisDecoder::decode() while (size < bufferSize) { - int result = ov_read(&handle, (char *) buffer + size, bufferSize - size, endian, (getBits() == 16 ? 2 : 1), 1, 0); + int result = ov_read(&handle, (char *) buffer + size, bufferSize - size, endian, (getBitDepth() == 16 ? 2 : 1), 1, 0); if (result == OV_HOLE) continue; @@ -243,7 +243,7 @@ int VorbisDecoder::getChannels() const return vorbisInfo->channels; } -int VorbisDecoder::getBits() const +int VorbisDecoder::getBitDepth() const { return 16; } diff --git a/src/modules/sound/lullaby/VorbisDecoder.h b/src/modules/sound/lullaby/VorbisDecoder.h index d744a8431..d5297992d 100644 --- a/src/modules/sound/lullaby/VorbisDecoder.h +++ b/src/modules/sound/lullaby/VorbisDecoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -26,6 +26,7 @@ #include "Decoder.h" // vorbis +#define OV_EXCLUDE_STATIC_CALLBACKS #include #include @@ -59,7 +60,7 @@ public: bool rewind(); bool isSeekable(); int getChannels() const; - int getBits() const; + int getBitDepth() const; int getSampleRate() const; private: diff --git a/src/modules/sound/lullaby/WaveDecoder.cpp b/src/modules/sound/lullaby/WaveDecoder.cpp new file mode 100644 index 000000000..84f9fdf3d --- /dev/null +++ b/src/modules/sound/lullaby/WaveDecoder.cpp @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "WaveDecoder.h" + +#include +#include "common/config.h" +#include "common/Exception.h" + +namespace love +{ +namespace sound +{ +namespace lullaby +{ + +// Callbacks +static wuff_sint32 read_callback(void *userdata, wuff_uint8 *buffer, size_t *size) +{ + WaveFile *input = (WaveFile *) userdata; + size_t bytes_left = input->size - input->offset; + size_t target_size = *size < bytes_left ? *size : bytes_left; + memcpy(buffer, input->data + input->offset, target_size); + input->offset += target_size; + *size = target_size; + return WUFF_SUCCESS; +} + +static wuff_sint32 seek_callback(void *userdata, wuff_uint64 offset) +{ + WaveFile *input = (WaveFile *)userdata; + input->offset = (size_t) (offset < input->size ? offset : input->size); + return WUFF_SUCCESS; +} + +static wuff_sint32 tell_callback(void *userdata, wuff_uint64 *offset) +{ + WaveFile *input = (WaveFile *)userdata; + *offset = input->offset; + return WUFF_SUCCESS; +} + +wuff_callback WaveDecoderCallbacks = {read_callback, seek_callback, tell_callback}; + + +WaveDecoder::WaveDecoder(Data *data, const std::string &ext, int bufferSize) + : Decoder(data, ext, bufferSize) +{ + dataFile.data = (char *) data->getData(); + dataFile.size = data->getSize(); + dataFile.offset = 0; + + int wuff_status = wuff_open(&handle, &WaveDecoderCallbacks, &dataFile); + if (wuff_status < 0) + throw love::Exception("Could not open WAVE"); + + try + { + wuff_status = wuff_stream_info(handle, &info); + if (wuff_status < 0) + throw love::Exception("Could not retrieve WAVE stream info"); + + if (info.channels > 2) + throw love::Exception("Multichannel audio not supported"); + + if (info.format != WUFF_FORMAT_PCM_U8 && info.format != WUFF_FORMAT_PCM_S16) + { + wuff_status = wuff_format(handle, WUFF_FORMAT_PCM_S16); + if (wuff_status < 0) + throw love::Exception("Could not set output format"); + } + } + catch (love::Exception &) + { + wuff_close(handle); + throw; + } +} + +WaveDecoder::~WaveDecoder() +{ + wuff_close(handle); +} + +bool WaveDecoder::accepts(const std::string &ext) +{ + static const std::string supported[] = + { + "wav", "" + }; + + for (int i = 0; !(supported[i].empty()); i++) + { + if (supported[i].compare(ext) == 0) + return true; + } + + return false; +} + +love::sound::Decoder *WaveDecoder::clone() +{ + return new WaveDecoder(data, ext, bufferSize); +} + +int WaveDecoder::decode() +{ + size_t size = 0; + + while (size < (size_t) bufferSize) + { + size_t bytes = bufferSize; + int wuff_status = wuff_read(handle, (wuff_uint8 *) buffer, &bytes); + + if (wuff_status < 0) + return 0; + else if (bytes == 0) + { + eof = true; + break; + } + + size += bytes; + } + + return size; +} + +bool WaveDecoder::seek(float s) +{ + int wuff_status = wuff_seek(handle, (wuff_uint64) (s * info.sample_rate)); + + if (wuff_status >= 0) + { + eof = false; + return true; + } + + return false; +} + +bool WaveDecoder::rewind() +{ + int wuff_status = wuff_seek(handle, 0); + + if (wuff_status >= 0) + { + eof = false; + return true; + } + + return false; +} + +bool WaveDecoder::isSeekable() +{ + return true; +} + +int WaveDecoder::getChannels() const +{ + return info.channels; +} + +int WaveDecoder::getBitDepth() const +{ + return info.bits_per_sample == 8 ? 8 : 16; +} + +int WaveDecoder::getSampleRate() const +{ + return info.sample_rate; +} + +} // lullaby +} // sound +} // love diff --git a/src/modules/sound/lullaby/WaveDecoder.h b/src/modules/sound/lullaby/WaveDecoder.h new file mode 100644 index 000000000..d94157f30 --- /dev/null +++ b/src/modules/sound/lullaby/WaveDecoder.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_SOUND_LULLABY_WAVE_DECODER_H +#define LOVE_SOUND_LULLABY_WAVE_DECODER_H + +// LOVE +#include "common/Data.h" +#include "Decoder.h" + +#include "libraries/Wuff/wuff.h" + +namespace love +{ +namespace sound +{ +namespace lullaby +{ + +// Struct for handling data +struct WaveFile +{ + char *data; + size_t size; + size_t offset; +}; + +class WaveDecoder : public Decoder +{ +public: + + WaveDecoder(Data *data, const std::string &ext, int bufferSize); + virtual ~WaveDecoder(); + + static bool accepts(const std::string &ext); + + love::sound::Decoder *clone(); + int decode(); + bool seek(float s); + bool rewind(); + bool isSeekable(); + int getChannels() const; + int getBitDepth() const; + int getSampleRate() const; + +private: + + WaveFile dataFile; + wuff_handle * handle; + wuff_info info; + +}; // WaveDecoder + +} // lullaby +} // sound +} // love + +#endif // LOVE_SOUND_LULLABY_WAVE_DECODER_H diff --git a/src/modules/sound/wrap_Decoder.cpp b/src/modules/sound/wrap_Decoder.cpp index c6045d85e..63f61d6ed 100644 --- a/src/modules/sound/wrap_Decoder.cpp +++ b/src/modules/sound/wrap_Decoder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -37,10 +37,10 @@ int w_Decoder_getChannels(lua_State *L) return 1; } -int w_Decoder_getBits(lua_State *L) +int w_Decoder_getBitDepth(lua_State *L) { Decoder *t = luax_checkdecoder(L, 1); - lua_pushinteger(L, t->getBits()); + lua_pushinteger(L, t->getBitDepth()); return 1; } @@ -54,7 +54,7 @@ int w_Decoder_getSampleRate(lua_State *L) static const luaL_Reg functions[] = { { "getChannels", w_Decoder_getChannels }, - { "getBits", w_Decoder_getBits }, + { "getBitDepth", w_Decoder_getBitDepth }, { "getSampleRate", w_Decoder_getSampleRate }, { 0, 0 } }; diff --git a/src/modules/sound/wrap_Decoder.h b/src/modules/sound/wrap_Decoder.h index 9f25bde8c..1c1cd4c73 100644 --- a/src/modules/sound/wrap_Decoder.h +++ b/src/modules/sound/wrap_Decoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -32,7 +32,7 @@ namespace sound Decoder *luax_checkdecoder(lua_State *L, int idx); int w_Decoder_getChannels(lua_State *L); -int w_Decoder_getBits(lua_State *L); +int w_Decoder_getBitDepth(lua_State *L); int w_Decoder_getSampleRate(lua_State *L); extern "C" int luaopen_decoder(lua_State *L); diff --git a/src/modules/sound/wrap_Sound.cpp b/src/modules/sound/wrap_Sound.cpp index 93f47bde5..d91641e00 100644 --- a/src/modules/sound/wrap_Sound.cpp +++ b/src/modules/sound/wrap_Sound.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -38,23 +38,14 @@ int w_newSoundData(lua_State *L) { int samples = luaL_checkint(L, 1); int sampleRate = luaL_optint(L, 2, Decoder::DEFAULT_SAMPLE_RATE); - int bits = luaL_optint(L, 3, Decoder::DEFAULT_BITS); + int bitDepth = luaL_optint(L, 3, Decoder::DEFAULT_BIT_DEPTH); int channels = luaL_optint(L, 4, Decoder::DEFAULT_CHANNELS); - try - { - t = instance->newSoundData(samples, sampleRate, bits, channels); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } - + EXCEPT_GUARD(t = instance->newSoundData(samples, sampleRate, bitDepth, channels);) } // Must be string or decoder. else { - // Convert to Decoder, if necessary. if (!luax_istype(L, 1, SOUND_DECODER_T)) { @@ -62,55 +53,30 @@ int w_newSoundData(lua_State *L) lua_replace(L, 1); } - try - { - t = instance->newSoundData(luax_checkdecoder(L, 1)); - } - catch(love::Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(t = instance->newSoundData(luax_checkdecoder(L, 1));) } - luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void *)t); - + luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, t); return 1; } int w_newDecoder(lua_State *L) { - // Convert to File, if necessary. - if (lua_isstring(L, 1)) - luax_convobj(L, 1, "filesystem", "newFile"); + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); - love::filesystem::FileData *data; - if (luax_istype(L, 1, FILESYSTEM_FILE_T)) - { - love::filesystem::File *file = luax_checktype(L, 1, "File", FILESYSTEM_FILE_T); - data = file->read(); - } - else - { - data = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); - data->retain(); - } + love::filesystem::FileData *data = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); int bufferSize = luaL_optint(L, 2, Decoder::DEFAULT_BUFFER_SIZE); - try - { - Decoder *t = instance->newDecoder(data, bufferSize); - data->release(); - if (t == 0) - return luaL_error(L, "Extension \"%s\" not supported.", data->getExtension().c_str()); - luax_newtype(L, "Decoder", SOUND_DECODER_T, (void *)t); - } - catch(love::Exception &e) - { - data->release(); - return luaL_error(L, e.what()); - } + Decoder *t = 0; + EXCEPT_GUARD(t = instance->newDecoder(data, bufferSize);) + if (t == 0) + return luaL_error(L, "Extension \"%s\" not supported.", data->getExtension().c_str()); + + luax_pushtype(L, "Decoder", SOUND_DECODER_T, t); return 1; } @@ -133,14 +99,7 @@ extern "C" int luaopen_love_sound(lua_State *L) { if (instance == 0) { - try - { - instance = new lullaby::Sound(); - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new lullaby::Sound();) } else instance->retain(); diff --git a/src/modules/sound/wrap_Sound.h b/src/modules/sound/wrap_Sound.h index 62772b001..2c4edb357 100644 --- a/src/modules/sound/wrap_Sound.h +++ b/src/modules/sound/wrap_Sound.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/sound/wrap_SoundData.cpp b/src/modules/sound/wrap_SoundData.cpp index 86693b003..1c5d26a99 100644 --- a/src/modules/sound/wrap_SoundData.cpp +++ b/src/modules/sound/wrap_SoundData.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,10 +39,10 @@ int w_SoundData_getChannels(lua_State *L) return 1; } -int w_SoundData_getBits(lua_State *L) +int w_SoundData_getBitDepth(lua_State *L) { SoundData *t = luax_checksounddata(L, 1); - lua_pushinteger(L, t->getBits()); + lua_pushinteger(L, t->getBitDepth()); return 1; } @@ -53,40 +53,50 @@ int w_SoundData_getSampleRate(lua_State *L) return 1; } +int w_SoundData_getSampleCount(lua_State *L) +{ + SoundData *t = luax_checksounddata(L, 1); + lua_pushinteger(L, t->getSampleCount()); + return 1; +} + int w_SoundData_getDuration(lua_State *L) { SoundData *t = luax_checksounddata(L, 1); - lua_pushinteger(L, t->getDuration()); + lua_pushnumber(L, t->getDuration()); return 1; } int w_SoundData_setSample(lua_State *L) { SoundData *sd = luax_checksounddata(L, 1); - int i = (int)lua_tointeger(L, 2); - float sample = (float)lua_tonumber(L, 3); - sd->setSample(i, sample); + int i = (int) luaL_checkinteger(L, 2); + float sample = (float) luaL_checknumber(L, 3); + + EXCEPT_GUARD(sd->setSample(i, sample);) return 0; } int w_SoundData_getSample(lua_State *L) { SoundData *sd = luax_checksounddata(L, 1); - int i = (int)lua_tointeger(L, 2); - lua_pushnumber(L, sd->getSample(i)); + int i = (int) luaL_checkinteger(L, 2); + + EXCEPT_GUARD(lua_pushnumber(L, sd->getSample(i));) return 1; } static const luaL_Reg functions[] = { - // Data + { "getString", w_Data_getString }, { "getPointer", w_Data_getPointer }, { "getSize", w_Data_getSize }, { "getChannels", w_SoundData_getChannels }, - { "getBits", w_SoundData_getBits }, + { "getBitDepth", w_SoundData_getBitDepth }, { "getSampleRate", w_SoundData_getSampleRate }, + { "getSampleCount", w_SoundData_getSampleCount }, { "getDuration", w_SoundData_getDuration }, { "setSample", w_SoundData_setSample }, { "getSample", w_SoundData_getSample }, diff --git a/src/modules/sound/wrap_SoundData.h b/src/modules/sound/wrap_SoundData.h index 26177920c..8fdf30e06 100644 --- a/src/modules/sound/wrap_SoundData.h +++ b/src/modules/sound/wrap_SoundData.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -31,14 +31,13 @@ namespace sound { SoundData *luax_checksounddata(lua_State *L, int idx); -int w_getPointer(lua_State *L); -int w_getSize(lua_State *L); -int w_getChannels(lua_State *L); -int w_getBits(lua_State *L); -int w_getSampleRate(lua_State *L); -int w_getDuration(lua_State *L); -int w_setSample(lua_State *L); -int w_getSample(lua_State *L); +int w_SoundData_getChannels(lua_State *L); +int w_SoundData_getBitDepth(lua_State *L); +int w_SoundData_getSampleRate(lua_State *L); +int w_SoundData_getSampleCount(lua_State *L); +int w_SoundData_getDuration(lua_State *L); +int w_SoundData_setSample(lua_State *L); +int w_SoundData_getSample(lua_State *L); extern "C" int luaopen_sounddata(lua_State *L); } // sound diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp new file mode 100644 index 000000000..78b3fea7a --- /dev/null +++ b/src/modules/system/System.cpp @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "System.h" + +namespace love +{ +namespace system +{ + +std::string System::getOS() const +{ +#ifdef LOVE_MACOSX + return "OS X"; +#elif LOVE_WINDOWS + return "Windows"; +#elif LOVE_LINUX + return "Linux"; +#else + return "Unknown"; +#endif +} + +bool System::getConstant(const char *in, System::PowerState &out) +{ + return powerStates.find(in, out); +} + +bool System::getConstant(System::PowerState in, const char *&out) +{ + return powerStates.find(in, out); +} + +StringMap::Entry System::powerEntries[] = +{ + {"unknown", System::POWER_UNKNOWN}, + {"battery", System::POWER_BATTERY}, + {"nobattery", System::POWER_NO_BATTERY}, + {"charging", System::POWER_CHARGING}, + {"charged", System::POWER_CHARGED}, +}; + +StringMap System::powerStates(System::powerEntries, sizeof(System::powerEntries)); + +} // system +} // love diff --git a/src/modules/system/System.h b/src/modules/system/System.h new file mode 100644 index 000000000..03fa26332 --- /dev/null +++ b/src/modules/system/System.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_SYSTEM_H +#define LOVE_SYSTEM_H + +// LOVE +#include "common/config.h" +#include "common/Module.h" +#include "common/StringMap.h" + +// stdlib +#include + +namespace love +{ +namespace system +{ + +class System : public Module +{ +public: + + enum PowerState + { + POWER_UNKNOWN, + POWER_BATTERY, + POWER_NO_BATTERY, + POWER_CHARGING, + POWER_CHARGED, + POWER_MAX_ENUM + }; + + virtual ~System() {} + + /** + * Gets the current operating system. + **/ + std::string getOS() const; + + /** + * Gets the number of reported CPU cores on the current system. + * Does not account for technologies such as Hyperthreading: a 4-core + * Hyperthreading-enabled Intel CPU will report 8, instead of 4. + **/ + virtual int getProcessorCount() const = 0; + + /** + * Replaces the contents of the system's text clipboard with a string. + * @param text The clipboard text to set. + **/ + virtual void setClipboardText(const std::string &text) const = 0; + + /** + * Gets the contents of the system's text clipboard. + **/ + virtual std::string getClipboardText() const = 0; + + /** + * Gets information about the system's power supply. + * + * @param[out] seconds Time in seconds of battery life left. + * -1 if a value can't be determined. + * @param[out] percent The percentage of battery life left (0-100.) + * -1 if a value can't be determined. + * + * @return The current state of the battery. + **/ + virtual PowerState getPowerInfo(int &seconds, int &percent) const = 0; + + static bool getConstant(const char *in, PowerState &out); + static bool getConstant(PowerState in, const char *&out); + +private: + + static StringMap::Entry powerEntries[]; + static StringMap powerStates; + +}; // System + +} // system +} // love + +#endif // LOVE_SYSTEM_H diff --git a/src/modules/system/sdl/System.cpp b/src/modules/system/sdl/System.cpp new file mode 100644 index 000000000..639d78217 --- /dev/null +++ b/src/modules/system/sdl/System.cpp @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2006-2014 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 "System.h" + +// SDL +#include +#include + +namespace love +{ +namespace system +{ +namespace sdl +{ + +System::System() +{ +} + +const char *System::getName() const +{ + return "love.system.sdl"; +} + +int System::getProcessorCount() const +{ + return SDL_GetCPUCount(); +} + +void System::setClipboardText(const std::string &text) const +{ + SDL_SetClipboardText(text.c_str()); +} + +std::string System::getClipboardText() const +{ + std::string text(""); + + char *ctext = SDL_GetClipboardText(); + if (ctext) + { + text = std::string(ctext); + SDL_free(ctext); + } + + return text; +} + +love::system::System::PowerState System::getPowerInfo(int &seconds, int &percent) const +{ + SDL_PowerState sdlstate = SDL_GetPowerInfo(&seconds, &percent); + + PowerState state = POWER_UNKNOWN; + powerStates.find(sdlstate, state); + + return state; +} + +EnumMap::Entry System::powerEntries[] = +{ + {System::POWER_UNKNOWN, SDL_POWERSTATE_UNKNOWN}, + {System::POWER_BATTERY, SDL_POWERSTATE_ON_BATTERY}, + {System::POWER_NO_BATTERY, SDL_POWERSTATE_NO_BATTERY}, + {System::POWER_CHARGING, SDL_POWERSTATE_CHARGING}, + {System::POWER_CHARGED, SDL_POWERSTATE_CHARGED}, +}; + +EnumMap System::powerStates(System::powerEntries, sizeof(System::powerEntries)); + +} // sdl +} // system +} // love diff --git a/src/modules/system/sdl/System.h b/src/modules/system/sdl/System.h new file mode 100644 index 000000000..78e87a364 --- /dev/null +++ b/src/modules/system/sdl/System.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_SYSTEM_SDL_SYSTEM_H +#define LOVE_SYSTEM_SDL_SYSTEM_H + +// LOVE +#include "system/System.h" +#include "common/EnumMap.h" + +// SDL +#include + +namespace love +{ +namespace system +{ +namespace sdl +{ + +class System : public love::system::System +{ +public: + + System(); + virtual ~System() {} + + // Implements Module. + const char *getName() const; + + int getProcessorCount() const; + + void setClipboardText(const std::string &text) const; + std::string getClipboardText() const; + + PowerState getPowerInfo(int &seconds, int &percent) const; + +private: + + static EnumMap::Entry powerEntries[]; + static EnumMap powerStates; + +}; // System + +} // sdl +} // system +} // love + +#endif // LOVE_SYSTEM_SDL_SYSTEM_H diff --git a/src/modules/system/wrap_System.cpp b/src/modules/system/wrap_System.cpp new file mode 100644 index 000000000..c4df69f07 --- /dev/null +++ b/src/modules/system/wrap_System.cpp @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2006-2014 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 "wrap_System.h" +#include "sdl/System.h" + +namespace love +{ +namespace system +{ + +static System *instance = 0; + +int w_getOS(lua_State *L) +{ + luax_pushstring(L, instance->getOS()); + return 1; +} + +int w_getProcessorCount(lua_State *L) +{ + lua_pushinteger(L, instance->getProcessorCount()); + return 1; +} + +int w_setClipboardText(lua_State *L) +{ + const char *text = luaL_checkstring(L, 1); + instance->setClipboardText(text); + return 0; +} + +int w_getClipboardText(lua_State *L) +{ + luax_pushstring(L, instance->getClipboardText()); + return 1; +} + +int w_getPowerInfo(lua_State *L) +{ + int seconds = -1, percent = -1; + const char *str; + + System::PowerState state = instance->getPowerInfo(seconds, percent); + + if (!System::getConstant(state, str)) + str = "unknown"; + + lua_pushstring(L, str); + + if (percent >= 0) + lua_pushinteger(L, percent); + else + lua_pushnil(L); + + if (seconds >= 0) + lua_pushinteger(L, seconds); + else + lua_pushnil(L); + + return 3; +} + +static const luaL_Reg functions[] = +{ + { "getOS", w_getOS }, + { "getProcessorCount", w_getProcessorCount }, + { "setClipboardText", w_setClipboardText }, + { "getClipboardText", w_getClipboardText }, + { "getPowerInfo", w_getPowerInfo }, + { 0, 0 } +}; + +extern "C" int luaopen_love_system(lua_State *L) +{ + if (instance == 0) + { + instance = new love::system::sdl::System(); + } + else + instance->retain(); + + WrappedModule w; + w.module = instance; + w.name = "system"; + w.flags = MODULE_T; + w.functions = functions; + w.types = 0; + + return luax_register_module(L, w); +} + +} // system +} // love \ No newline at end of file diff --git a/src/modules/graphics/Drawable.cpp b/src/modules/system/wrap_System.h similarity index 66% rename from src/modules/graphics/Drawable.cpp rename to src/modules/system/wrap_System.h index 843e031d9..3cb89d424 100644 --- a/src/modules/graphics/Drawable.cpp +++ b/src/modules/system/wrap_System.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,16 +18,26 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "Drawable.h" +#ifndef LOVE_WRAP_SYSTEM_H +#define LOVE_WRAP_SYSTEM_H + +// LOVE +#include "System.h" +#include "common/runtime.h" namespace love { -namespace graphics +namespace system { -Drawable::~Drawable() -{ -} +int w_getOS(lua_State *L); +int w_getProcessorCount(lua_State *L); +int w_setClipboardText(lua_State *L); +int w_getClipboardText(lua_State *L); +int w_getPowerInfo(lua_State *L); +extern "C" LOVE_EXPORT int luaopen_love_system(lua_State *L); -} // graphics +} // system } // love + +#endif // LOVE_WRAP_SYSTEM_H diff --git a/src/modules/thread/Channel.cpp b/src/modules/thread/Channel.cpp index 09c90ba04..1e8532b34 100644 --- a/src/modules/thread/Channel.cpp +++ b/src/modules/thread/Channel.cpp @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #include "Channel.h" #include @@ -125,13 +125,11 @@ void Channel::supply(Variant *var) if (!var) return; - mutex->lock(); + Lock l(mutex); unsigned long id = push(var); while (!past(id, received)) cond->wait(mutex); - - mutex->unlock(); } Variant *Channel::pop() @@ -157,11 +155,10 @@ Variant *Channel::pop() Variant *Channel::demand() { Variant *var; - mutex->lock(); + Lock l(mutex); while (!(var = pop())) cond->wait(mutex); - mutex->unlock(); return var; } @@ -176,7 +173,7 @@ Variant *Channel::peek() return var; } -int Channel::count() +int Channel::getCount() { Lock l(mutex); return queue.size(); @@ -218,24 +215,20 @@ void Channel::unlockMutex() void Channel::retain() { + EmptyLock l; if (named) - namedChannelMutex->lock(); + l.setLock(namedChannelMutex); Object::retain(); - - if (named) - namedChannelMutex->unlock(); } void Channel::release() { + EmptyLock l; if (named) - namedChannelMutex->lock(); + l.setLock(namedChannelMutex); Object::release(); - - if (named) - namedChannelMutex->unlock(); } } // thread } // love diff --git a/src/modules/thread/Channel.h b/src/modules/thread/Channel.h index 2f49e6234..e54cb57e4 100644 --- a/src/modules/thread/Channel.h +++ b/src/modules/thread/Channel.h @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #ifndef LOVE_THREAD_CHANNEL_H #define LOVE_THREAD_CHANNEL_H @@ -49,7 +49,7 @@ public: Variant *pop(); Variant *demand(); // blocking pop Variant *peek(); - int count(); + int getCount(); void clear(); void retain(); diff --git a/src/modules/thread/LuaThread.cpp b/src/modules/thread/LuaThread.cpp index fef5c1b09..807994e1e 100644 --- a/src/modules/thread/LuaThread.cpp +++ b/src/modules/thread/LuaThread.cpp @@ -1,25 +1,26 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #include "LuaThread.h" -#include +#include "event/Event.h" +#include "common/config.h" #ifdef LOVE_BUILD_STANDALONE extern "C" int luaopen_love(lua_State * L); @@ -31,7 +32,10 @@ namespace love namespace thread { LuaThread::LuaThread(const std::string &name, love::Data *code) - : name(name), code(code) + : code(code) + , name(name) + , args(0) + , nargs(0) { code->retain(); } @@ -39,12 +43,18 @@ LuaThread::LuaThread(const std::string &name, love::Data *code) LuaThread::~LuaThread() { code->release(); + + // No args should still exist at this point, + // but you never know. + for (int i = 0; i < nargs; ++i) + args[i]->release(); } void LuaThread::threadFunction() { this->retain(); - lua_State * L = lua_open(); + error.clear(); + lua_State *L = luaL_newstate(); luaL_openlibs(L); #ifdef LOVE_BUILD_STANDALONE love::luax_preload(L, luaopen_love, "love"); @@ -54,15 +64,65 @@ void LuaThread::threadFunction() if (luaL_loadbuffer(L, (const char *) code->getData(), code->getSize(), name.c_str()) != 0) error = luax_tostring(L, -1); else - if (lua_pcall(L, 0, 0, 0) != 0) + { + int pushedargs = nargs; + for (int i = 0; i < nargs; ++i) + { + args[i]->toLua(L); + args[i]->release(); + } + // Set both args and nargs to nil, prevents the deconstructor from + // accessing it again. + nargs = 0; + args = 0; + + if (lua_pcall(L, pushedargs, 0, 0) != 0) error = luax_tostring(L, -1); + } lua_close(L); + if (!error.empty()) + onError(); this->release(); } -const std::string &LuaThread::getError() +bool LuaThread::start(Variant **args, int nargs) +{ + for (int i = 0; i < this->nargs; ++i) + this->args[i]->release(); + + this->args = args; + this->nargs = nargs; + + return Threadable::start(); +} + +const std::string &LuaThread::getError() const { return error; } + +void LuaThread::onError() +{ + if (error.empty()) + return; + + event::Event *event = (event::Event *) Module::findInstance("love.event."); + if (!event) + return; + + Proxy p; + p.flags = THREAD_THREAD_T; + p.data = this; + + Variant *arg1 = new Variant(THREAD_THREAD_ID, &p); + Variant *arg2 = new Variant(error.c_str(), error.length()); + event::Message *msg = new event::Message("threaderror", arg1, arg2); + arg1->release(); + arg2->release(); + + event->push(msg); + msg->release(); +} + } // thread } // love diff --git a/src/modules/thread/LuaThread.h b/src/modules/thread/LuaThread.h index 264dd84fa..e7eaab6e6 100644 --- a/src/modules/thread/LuaThread.h +++ b/src/modules/thread/LuaThread.h @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #ifndef LOVE_THREAD_LUATHREAD_H #define LOVE_THREAD_LUATHREAD_H @@ -25,8 +25,9 @@ #include // LOVE -#include #include +#include +#include #include namespace love @@ -36,15 +37,24 @@ namespace thread class LuaThread : public love::Object, public Threadable { public: + LuaThread(const std::string &name, love::Data *code); ~LuaThread(); void threadFunction(); - const std::string &getError(); + const std::string &getError() const; + + bool start(Variant **args, int nargs); private: + + void onError(); + love::Data *code; std::string name; std::string error; + + Variant **args; + int nargs; }; } // thread } // love diff --git a/src/modules/thread/Thread.h b/src/modules/thread/Thread.h index 45c190431..23c82b128 100644 --- a/src/modules/thread/Thread.h +++ b/src/modules/thread/Thread.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,10 +33,12 @@ namespace thread class Thread { public: + virtual ~Thread() {} virtual bool start() = 0; virtual void wait() = 0; - virtual void kill() = 0; + virtual bool isRunning() = 0; + }; // ThreadObject } // thread diff --git a/src/modules/thread/ThreadModule.cpp b/src/modules/thread/ThreadModule.cpp index 2c72a925f..6e433bcbf 100644 --- a/src/modules/thread/ThreadModule.cpp +++ b/src/modules/thread/ThreadModule.cpp @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #include "ThreadModule.h" @@ -24,10 +24,6 @@ namespace love { namespace thread { -const char *ThreadModule::getName() const -{ - return "love.thread.sdl"; -} LuaThread *ThreadModule::newThread(const std::string &name, love::Data *data) { @@ -44,5 +40,11 @@ Channel *ThreadModule::getChannel(const std::string &name) { return Channel::getChannel(name); } + +const char *ThreadModule::getName() const +{ + return "love.thread.sdl"; +} + } // thread } // love diff --git a/src/modules/thread/ThreadModule.h b/src/modules/thread/ThreadModule.h index d16fe957d..8aa396bbe 100644 --- a/src/modules/thread/ThreadModule.h +++ b/src/modules/thread/ThreadModule.h @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #ifndef LOVE_THREAD_THREADMODULE_H #define LOVE_THREAD_THREADMODULE_H @@ -25,12 +25,14 @@ #include // LOVE -#include -#include -#include -#include -#include -#include +#include "common/Data.h" +#include "common/Module.h" +#include "common/StringMap.h" + +#include "Thread.h" +#include "Channel.h" +#include "LuaThread.h" +#include "threads.h" namespace love { @@ -39,13 +41,17 @@ namespace thread class ThreadModule : public love::Module { public: - virtual ~ThreadModule() {} - LuaThread *newThread(const std::string &name, love::Data *data); - Channel *newChannel(); - Channel *getChannel(const std::string &name); - const char *getName() const; + virtual ~ThreadModule() {} + virtual LuaThread *newThread(const std::string &name, love::Data *data); + virtual Channel *newChannel(); + virtual Channel *getChannel(const std::string &name); + + // Implements Module. + virtual const char *getName() const; + }; // ThreadModule + } // thread } // love diff --git a/src/modules/thread/sdl/Thread.cpp b/src/modules/thread/sdl/Thread.cpp index 046f39a5a..416846331 100644 --- a/src/modules/thread/sdl/Thread.cpp +++ b/src/modules/thread/sdl/Thread.cpp @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #include "Thread.h" @@ -51,32 +51,28 @@ bool Thread::start() return false; if (thread) // Clean old handle up SDL_WaitThread(thread, 0); - thread = SDL_CreateThread(thread_runner, this); + thread = SDL_CreateThread(thread_runner, NULL, this); running = (thread != 0); return running; } void Thread::wait() { - mutex.lock(); - if (!thread) - return; - mutex.unlock(); + { + Lock l(mutex); + if (!thread) + return; + } SDL_WaitThread(thread, 0); Lock l(mutex); running = false; thread = 0; } -void Thread::kill() +bool Thread::isRunning() { Lock l(mutex); - if (!running) - return; - SDL_KillThread(thread); - SDL_WaitThread(thread, 0); - running = false; - thread = 0; + return running; } int Thread::thread_runner(void *data) diff --git a/src/modules/thread/sdl/Thread.h b/src/modules/thread/sdl/Thread.h index c8465fe59..ac2a860b2 100644 --- a/src/modules/thread/sdl/Thread.h +++ b/src/modules/thread/sdl/Thread.h @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #ifndef LOVE_THREAD_SDL_THREAD_H #define LOVE_THREAD_SDL_THREAD_H @@ -36,20 +36,25 @@ namespace sdl { class Thread : public thread::Thread { -private: - Threadable *t; - bool running; - SDL_Thread *thread; - static int thread_runner(void *data); - Mutex mutex; - public: + Thread(Threadable *t); ~Thread(); bool start(); - void kill(); void wait(); + bool isRunning(); + +private: + + Threadable *t; + bool running; + SDL_Thread *thread; + Mutex mutex; + + static int thread_runner(void *data); + }; // Thread + } // sdl } // thread } // love diff --git a/src/modules/thread/sdl/threads.cpp b/src/modules/thread/sdl/threads.cpp index e5881f5a9..80bec15f4 100644 --- a/src/modules/thread/sdl/threads.cpp +++ b/src/modules/thread/sdl/threads.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -39,12 +39,12 @@ Mutex::~Mutex() void Mutex::lock() { - SDL_mutexP(mutex); + SDL_LockMutex(mutex); } void Mutex::unlock() { - SDL_mutexV(mutex); + SDL_UnlockMutex(mutex); } Conditional::Conditional() diff --git a/src/modules/thread/sdl/threads.h b/src/modules/thread/sdl/threads.h index d80478a8e..9521196c0 100644 --- a/src/modules/thread/sdl/threads.h +++ b/src/modules/thread/sdl/threads.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 diff --git a/src/modules/thread/threads.cpp b/src/modules/thread/threads.cpp index 0dd6dc602..631b75b53 100644 --- a/src/modules/thread/threads.cpp +++ b/src/modules/thread/threads.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -42,6 +42,38 @@ Lock::~Lock() mutex->unlock(); } +EmptyLock::EmptyLock() + : mutex(0) +{ +} + +EmptyLock::~EmptyLock() +{ + if (mutex) + mutex->unlock(); +} + +void EmptyLock::setLock(Mutex *m) +{ + if (m) + m->lock(); + + if (mutex) + mutex->unlock(); + + mutex = m; +} + +void EmptyLock::setLock(Mutex &m) +{ + m.lock(); + + if (mutex) + mutex->unlock(); + + mutex = &m; +} + Threadable::Threadable() { owner = newThread(this); @@ -62,9 +94,9 @@ void Threadable::wait() owner->wait(); } -void Threadable::kill() +bool Threadable::isRunning() const { - owner->kill(); + return owner->isRunning(); } } // thread diff --git a/src/modules/thread/threads.h b/src/modules/thread/threads.h index a978991ba..7c1a26c18 100644 --- a/src/modules/thread/threads.h +++ b/src/modules/thread/threads.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -59,6 +59,19 @@ private: Mutex *mutex; }; +class EmptyLock +{ +public: + EmptyLock(); + ~EmptyLock(); + + void setLock(Mutex *m); + void setLock(Mutex &m); + +private: + Mutex *mutex; +}; + class Threadable { public: @@ -69,7 +82,7 @@ public: bool start(); void wait(); - void kill(); + bool isRunning() const; protected: Thread *owner; diff --git a/src/modules/thread/wrap_Channel.cpp b/src/modules/thread/wrap_Channel.cpp index a7c6434cf..b0d632c84 100644 --- a/src/modules/thread/wrap_Channel.cpp +++ b/src/modules/thread/wrap_Channel.cpp @@ -46,7 +46,9 @@ Channel *luax_checkchannel(lua_State *L, int idx) int w_Channel_push(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = Variant::fromLua(L, 2); + Variant *var = lua_isnoneornil(L, 2) ? 0 : Variant::fromLua(L, 2); + if (!var) + return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected"); c->push(var); releaseVariant(c, var); return 0; @@ -55,7 +57,9 @@ int w_Channel_push(lua_State *L) int w_Channel_supply(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant *var = Variant::fromLua(L, 2); + Variant *var = lua_isnoneornil(L, 2) ? 0 : Variant::fromLua(L, 2); + if (!var) + return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected"); c->supply(var); releaseVariant(c, var); return 0; @@ -98,10 +102,10 @@ int w_Channel_peek(lua_State *L) return 1; } -int w_Channel_count(lua_State *L) +int w_Channel_getCount(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - lua_pushnumber(L, c->count()); + lua_pushnumber(L, c->getCount()); return 1; } @@ -118,7 +122,7 @@ static const luaL_Reg type_functions[] = { { "pop", w_Channel_pop }, { "demand", w_Channel_demand }, { "peek", w_Channel_peek }, - { "count", w_Channel_count }, + { "getCount", w_Channel_getCount }, { "clear", w_Channel_clear }, { 0, 0 } }; diff --git a/src/modules/thread/wrap_Channel.h b/src/modules/thread/wrap_Channel.h index 283cbce9f..14473ea63 100644 --- a/src/modules/thread/wrap_Channel.h +++ b/src/modules/thread/wrap_Channel.h @@ -1,22 +1,22 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #ifndef LOVE_THREAD_WRAP_CHANNEL_H #define LOVE_THREAD_WRAP_CHANNEL_H @@ -34,7 +34,7 @@ int w_Channel_supply(lua_State *L); int w_Channel_pop(lua_State *L); int w_Channel_demand(lua_State *L); int w_Channel_peek(lua_State *L); -int w_Channel_count(lua_State *L); +int w_Channel_getCount(lua_State *L); int w_Channel_clear(lua_State *L); extern "C" int luaopen_channel(lua_State *L); diff --git a/src/modules/thread/wrap_LuaThread.cpp b/src/modules/thread/wrap_LuaThread.cpp index 068810302..1629051c2 100644 --- a/src/modules/thread/wrap_LuaThread.cpp +++ b/src/modules/thread/wrap_LuaThread.cpp @@ -33,7 +33,26 @@ LuaThread *luax_checkthread(lua_State *L, int idx) int w_Thread_start(lua_State *L) { LuaThread *t = luax_checkthread(L, 1); - luax_pushboolean(L, t->start()); + int nargs = lua_gettop(L) - 1; + Variant **args = 0; + + if (nargs > 0) + { + args = new Variant*[nargs]; + for (int i = 0; i < nargs; ++i) + { + args[i] = Variant::fromLua(L, i+2); + if (!args[i]) + { + for (int j = i; j >= 0; j--) + delete args[j]; + delete[] args; + return luaL_argerror(L, i+2, "boolean, number, string, love type, or flat table expected"); + } + } + } + + luax_pushboolean(L, t->start(args, nargs)); return 1; } @@ -48,17 +67,25 @@ int w_Thread_getError(lua_State *L) { LuaThread *t = luax_checkthread(L, 1); std::string err = t->getError(); - if (err.length() == 0) + if (err.empty()) lua_pushnil(L); else luax_pushstring(L, err); return 1; } +int w_Thread_isRunning(lua_State *L) +{ + LuaThread *t = luax_checkthread(L, 1); + luax_pushboolean(L, t->isRunning()); + return 1; +} + static const luaL_Reg type_functions[] = { { "start", w_Thread_start }, { "wait", w_Thread_wait }, { "getError", w_Thread_getError }, + { "isRunning", w_Thread_isRunning }, { 0, 0 } }; diff --git a/src/modules/thread/wrap_LuaThread.h b/src/modules/thread/wrap_LuaThread.h index 8bfdf0731..6be1be722 100644 --- a/src/modules/thread/wrap_LuaThread.h +++ b/src/modules/thread/wrap_LuaThread.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2012 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -33,6 +33,7 @@ LuaThread *luax_checkthread(lua_State *L, int idx); int w_Thread_start(lua_State *L); int w_Thread_wait(lua_State *L); int w_Thread_getError(lua_State *L); +int w_Thread_isRunning(lua_State *L); extern "C" int luaopen_thread(lua_State *L); diff --git a/src/modules/thread/wrap_ThreadModule.cpp b/src/modules/thread/wrap_ThreadModule.cpp index f7d48aefa..c90fb9a6b 100644 --- a/src/modules/thread/wrap_ThreadModule.cpp +++ b/src/modules/thread/wrap_ThreadModule.cpp @@ -18,60 +18,50 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "wrap_ThreadModule.h" #include "wrap_LuaThread.h" #include "wrap_Channel.h" -#include -#include +#include "ThreadModule.h" + +#include "filesystem/File.h" +#include "filesystem/FileData.h" namespace love { namespace thread { + static ThreadModule *instance = 0; int w_newThread(lua_State *L) { std::string name = "Thread code"; - love::Data *data; - if (lua_isstring(L, 1)) - luax_convobj(L, 1, "filesystem", "newFile"); - if (luax_istype(L, 1, FILESYSTEM_FILE_T)) + love::Data *data = 0; + + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); + + if (luax_istype(L, 1, FILESYSTEM_FILE_DATA_T)) { - try - { - love::filesystem::File * file = luax_checktype(L, 1, "File", FILESYSTEM_FILE_T); - name = std::string("@") + file->getFilename(); - data = file->read(); - } - catch (love::Exception & e) - { - return luaL_error(L, "%s", e.what()); - } - } - else if (luax_istype(L, 1, FILESYSTEM_FILE_DATA_T)) - { - love::filesystem::FileData * fdata = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); + love::filesystem::FileData *fdata = luax_checktype(L, 1, "FileData", FILESYSTEM_FILE_DATA_T); name = std::string("@") + fdata->getFilename(); data = fdata; - data->retain(); } else { data = luax_checktype(L, 1, "Data", DATA_T); - data->retain(); } + LuaThread *t = instance->newThread(name, data); - // do not worry, file->read() returns retained data - data->release(); - luax_newtype(L, "Thread", THREAD_THREAD_T, (void *)t); + luax_pushtype(L, "Thread", THREAD_THREAD_T, t); return 1; } int w_newChannel(lua_State *L) { Channel *c = instance->newChannel(); - luax_newtype(L, "Channel", THREAD_CHANNEL_T, (void *)c); + luax_pushtype(L, "Channel", THREAD_CHANNEL_T, c); return 1; } @@ -79,7 +69,7 @@ int w_getChannel(lua_State *L) { std::string name = luax_checkstring(L, 1); Channel *c = instance->getChannel(name); - luax_newtype(L, "Channel", THREAD_CHANNEL_T, (void *)c); + luax_pushtype(L, "Channel", THREAD_CHANNEL_T, c); return 1; } @@ -101,14 +91,7 @@ extern "C" int luaopen_love_thread(lua_State *L) { if (instance == 0) { - try - { - instance = new ThreadModule(); - } - catch (Exception & e) - { - return luaL_error(L, "%s", e.what()); - } + EXCEPT_GUARD(instance = new love::thread::ThreadModule();) } else instance->retain(); @@ -122,5 +105,6 @@ extern "C" int luaopen_love_thread(lua_State *L) return luax_register_module(L, w); } -} -} + +} // thread +} // love diff --git a/src/modules/thread/wrap_ThreadModule.h b/src/modules/thread/wrap_ThreadModule.h index 00bca5e87..750b9fca9 100644 --- a/src/modules/thread/wrap_ThreadModule.h +++ b/src/modules/thread/wrap_ThreadModule.h @@ -1,28 +1,29 @@ /** -* 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. -**/ + * Copyright (c) 2006-2014 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. + **/ #ifndef LOVE_THREAD_WRAP_THREADMODULE_H #define LOVE_THREAD_WRAP_THREADMODULE_H // LOVE -#include "ThreadModule.h" +#include "common/config.h" +#include "common/runtime.h" namespace love { diff --git a/src/modules/timer/Timer.h b/src/modules/timer/Timer.h index 412d19f0f..576d514ce 100644 --- a/src/modules/timer/Timer.h +++ b/src/modules/timer/Timer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -49,7 +49,7 @@ public: * usually 1ms. * @param seconds The number of seconds to sleep for. **/ - virtual void sleep(double seconds) = 0; + virtual void sleep(double seconds) const = 0; /** * Gets the time between the last two frames, assuming step is called @@ -65,18 +65,17 @@ public: virtual int getFPS() const = 0; /** - * Gets the amount of time since the program started. Only useful for timing - * code or measuring intervals. - * @return The time (in seconds) since the program started. + * Gets the average delta time (seconds per frame) over the last second. **/ - virtual double getTime() const = 0; + virtual double getAverageDelta() const = 0; /** - * Gets the amount of time passed since an unspecified time. The time is accurate - * to the microsecond, and is limited to 24 hours. + * Gets the amount of time passed since an unspecified time. Useful for + * profiling code or measuring intervals. The time is microsecond-precise, + * and increases monotonically. * @return The time (in seconds) **/ - virtual double getMicroTime() const = 0; + virtual double getTime() const = 0; }; // Timer diff --git a/src/modules/timer/sdl/Timer.cpp b/src/modules/timer/sdl/Timer.cpp index 0e2ae1b34..1a25983ef 100644 --- a/src/modules/timer/sdl/Timer.cpp +++ b/src/modules/timer/sdl/Timer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,17 +18,38 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "common/config.h" -#include "common/delay.h" +#include "Timer.h" -#ifdef LOVE_WINDOWS -# include -# include -#else -# include +#include "common/delay.h" +#include "common/int.h" + +// SDL +#include + +#if defined(LOVE_WINDOWS) +#include +#elif defined(LOVE_MACOSX) +#include +#include +#elif defined(LOVE_LINUX) +#include +#include +#include #endif -#include "Timer.h" +namespace +{ +#if defined(LOVE_LINUX) +inline double getTimeOfDay() +{ + timeval t; + gettimeofday(&t, NULL); + return (double) t.tv_sec + (double) t.tv_usec / 1000000.0; +} +#endif +} namespace love { @@ -41,13 +62,17 @@ Timer::Timer() : currTime(0) , prevFpsUpdate(0) , fps(0) + , averageDelta(0) , fpsUpdateFrequency(1) , frames(0) , dt(0) + , timerPeriod(getTimerPeriod()) { - // Init the SDL timer system. + // Init the SDL timer system (needed for SDL_Delay.) if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0) - throw Exception(SDL_GetError()); + throw love::Exception("%s", SDL_GetError()); + + prevFpsUpdate = currTime = getTime(); } Timer::~Timer() @@ -69,26 +94,27 @@ void Timer::step() // "Current" time is previous time by now. prevTime = currTime; - // Get ticks from SDL - currTime = SDL_GetTicks(); + // Get time from system. + currTime = getTime(); - // Convert to number of seconds - dt = (currTime - prevTime)/1000.0; + // Convert to number of seconds. + dt = currTime - prevTime; - double timeSinceLast = (currTime - prevFpsUpdate)/1000.0; + double timeSinceLast = currTime - prevFpsUpdate; // Update FPS? if (timeSinceLast > fpsUpdateFrequency) { fps = int((frames/timeSinceLast) + 0.5); + averageDelta = timeSinceLast/frames; prevFpsUpdate = currTime; frames = 0; } } -void Timer::sleep(double seconds) +void Timer::sleep(double seconds) const { if (seconds > 0) - delay((int)(seconds*1000)); + delay((unsigned int)(seconds*1000)); } double Timer::getDelta() const @@ -101,35 +127,50 @@ int Timer::getFPS() const return fps; } -double Timer::getTime() const +double Timer::getAverageDelta() const { - return SDL_GetTicks()/1000.0; + return averageDelta; } -double Timer::getMicroTime() const +double Timer::getTimerPeriod() { -#ifdef LOVE_WINDOWS - static __int64 freq = 0; - - if (!freq) - { - LARGE_INTEGER temp; - QueryPerformanceFrequency(&temp); - - freq = (__int64) temp.QuadPart; - } +#if defined(LOVE_MACOSX) + mach_timebase_info_data_t info; + mach_timebase_info(&info); + return (double) info.numer / (double) info.denom / 1000000000.0; +#elif defined(LOVE_WINDOWS) + LARGE_INTEGER temp; + if (QueryPerformanceFrequency(&temp) != 0 && temp.QuadPart != 0) + return 1.0 / (double) temp.QuadPart; +#endif + return 0; +} +double Timer::getTime() const +{ +#if defined(LOVE_LINUX) + double mt; + // Check for POSIX timers and monotonic clocks. If not supported, use the gettimeofday fallback. +#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) \ +&& (defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)) + timespec t; +#ifdef CLOCK_MONOTONIC_RAW + clockid_t clk_id = CLOCK_MONOTONIC_RAW; +#else + clockid_t clk_id = CLOCK_MONOTONIC; +#endif + if (clock_gettime(clk_id, &t) == 0) + mt = (double) t.tv_sec + (double) t.tv_nsec / 1000000000.0; + else +#endif + mt = getTimeOfDay(); + return mt; +#elif defined(LOVE_MACOSX) + return (double) mach_absolute_time() * timerPeriod; +#elif defined(LOVE_WINDOWS) LARGE_INTEGER microTime; QueryPerformanceCounter(µTime); - - // The 64 to 32 bit integer conversion, assuming the fraction part down - // to microseconds takes 20 bits, should not be a problem unless the - // system has an uptime of a few decades. - return (double) microTime.QuadPart / (double) freq; -#else - timeval t; - gettimeofday(&t, NULL); - return t.tv_sec + t.tv_usec/1000000.0; + return (double) microTime.QuadPart * timerPeriod; #endif } diff --git a/src/modules/timer/sdl/Timer.h b/src/modules/timer/sdl/Timer.h index c4d138d55..3805899a8 100644 --- a/src/modules/timer/sdl/Timer.h +++ b/src/modules/timer/sdl/Timer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,11 +21,8 @@ #ifndef LOVE_TIMER_SDL_TIMER_H #define LOVE_TIMER_SDL_TIMER_H -// SDL -#include - // LOVE -#include +#include "timer/Timer.h" namespace love { @@ -54,21 +51,22 @@ public: const char *getName() const; void step(); - void sleep(double seconds); + void sleep(double seconds) const; double getDelta() const; int getFPS() const; + double getAverageDelta() const; double getTime() const; - double getMicroTime() const; private: // Frame delta vars. - Uint32 currTime; - Uint32 prevTime; - Uint32 prevFpsUpdate; + double currTime; + double prevTime; + double prevFpsUpdate; // Updated with a certain frequency. int fps; + double averageDelta; // The frequency by which to update the FPS. double fpsUpdateFrequency; @@ -79,6 +77,12 @@ private: // The current timestep. double dt; + // The timer period (reciprocal of the frequency.) + const double timerPeriod; + + // Returns the timer period on some platforms. + static double getTimerPeriod(); + }; // Timer } // sdl diff --git a/src/modules/timer/wrap_Timer.cpp b/src/modules/timer/wrap_Timer.cpp index f95af3978..247ae1922 100644 --- a/src/modules/timer/wrap_Timer.cpp +++ b/src/modules/timer/wrap_Timer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -46,13 +46,19 @@ int w_getDelta(lua_State *L) int w_getFPS(lua_State *L) { - lua_pushnumber(L, instance->getFPS()); + lua_pushinteger(L, instance->getFPS()); + return 1; +} + +int w_getAverageDelta(lua_State *L) +{ + lua_pushnumber(L, instance->getAverageDelta()); return 1; } int w_sleep(lua_State *L) { - instance->sleep((float) luaL_checknumber(L, 1)); + instance->sleep(luaL_checknumber(L, 1)); return 0; } @@ -62,21 +68,15 @@ int w_getTime(lua_State *L) return 1; } -int w_getMicroTime(lua_State *L) -{ - lua_pushnumber(L, instance->getMicroTime()); - return 1; -} - // List of functions to wrap. static const luaL_Reg functions[] = { { "step", w_step }, { "getDelta", w_getDelta }, { "getFPS", w_getFPS }, + { "getAverageDelta", w_getAverageDelta }, { "sleep", w_sleep }, { "getTime", w_getTime }, - { "getMicroTime", w_getMicroTime }, { 0, 0 } }; @@ -85,15 +85,7 @@ extern "C" int luaopen_love_timer(lua_State *L) { if (instance == 0) { - try - { - instance = new love::timer::sdl::Timer(); - - } - catch(Exception &e) - { - return luaL_error(L, e.what()); - } + EXCEPT_GUARD(instance = new love::timer::sdl::Timer();) } else instance->retain(); diff --git a/src/modules/timer/wrap_Timer.h b/src/modules/timer/wrap_Timer.h index 86234daf7..698d3864f 100644 --- a/src/modules/timer/wrap_Timer.h +++ b/src/modules/timer/wrap_Timer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,6 +22,7 @@ #define LOVE_TIMER_WRAP_TIMER_H // LOVE +#include "common/runtime.h" #include "Timer.h" namespace love @@ -32,9 +33,9 @@ namespace timer int w_step(lua_State *L); int w_getDelta(lua_State *L); int w_getFPS(lua_State *L); +int w_getAverageDelta(lua_State *L); int w_sleep(lua_State *L); int w_getTime(lua_State *L); -int w_getMicroTime(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_timer(lua_State *L); } // timer diff --git a/src/modules/window/Window.cpp b/src/modules/window/Window.cpp index eec6253cf..ac9c45a4e 100644 --- a/src/modules/window/Window.cpp +++ b/src/modules/window/Window.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -38,5 +38,63 @@ void Window::swapBuffers() { } +WindowAttributes::WindowAttributes() + : fullscreen(false) + , fstype(Window::FULLSCREEN_TYPE_NORMAL) + , vsync(true) + , fsaa(0) + , resizable(false) + , minwidth(1) + , minheight(1) + , borderless(false) + , centered(true) + , display(0) +{ +} + +bool Window::getConstant(const char *in, Window::FullscreenType &out) +{ + return fullscreenTypes.find(in, out); +} + +bool Window::getConstant(Window::FullscreenType in, const char *&out) +{ + return fullscreenTypes.find(in, out); +} + +bool Window::getConstant(const char *in, Window::Attribute &out) +{ + return attributes.find(in, out); +} + +bool Window::getConstant(Window::Attribute in, const char *&out) +{ + return attributes.find(in, out); +} + +StringMap::Entry Window::attributeEntries[] = +{ + {"fullscreen", ATTRIB_FULLSCREEN}, + {"fullscreentype", ATTRIB_FULLSCREEN_TYPE}, + {"vsync", ATTRIB_VSYNC}, + {"fsaa", ATTRIB_FSAA}, + {"resizable", ATTRIB_RESIZABLE}, + {"minwidth", ATTRIB_MIN_WIDTH}, + {"minheight", ATTRIB_MIN_HEIGHT}, + {"borderless", ATTRIB_BORDERLESS}, + {"centered", ATTRIB_CENTERED}, + {"display", ATTRIB_DISPLAY} +}; + +StringMap Window::attributes(Window::attributeEntries, sizeof(Window::attributeEntries)); + +StringMap::Entry Window::fullscreenTypeEntries[] = +{ + {"normal", Window::FULLSCREEN_TYPE_NORMAL}, + {"desktop", Window::FULLSCREEN_TYPE_DESKTOP}, +}; + +StringMap Window::fullscreenTypes(Window::fullscreenTypeEntries, sizeof(Window::fullscreenTypeEntries)); + } // window } // love diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index a4d8c90f8..0f84c7c51 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -21,30 +21,51 @@ #ifndef LOVE_WINDOW_WINDOW_H #define LOVE_WINDOW_WINDOW_H -// STL -#include - // LOVE #include "common/Module.h" -#include +#include "common/StringMap.h" +#include "image/ImageData.h" + +// C++ +#include +#include namespace love { namespace window { -struct WindowFlags -{ - bool fullscreen; // = false - bool vsync; // = true - int fsaa; // = 0 - bool resizable; // = false - bool borderless; // = false -}; // WindowFlags +// Forward-declared so it can be used in the class methods. We can't define the +// whole thing here because it uses the Window::Type enum. +struct WindowAttributes; class Window : public Module { public: + + // Types of window attributes. + enum Attribute + { + ATTRIB_FULLSCREEN, + ATTRIB_FULLSCREEN_TYPE, + ATTRIB_VSYNC, + ATTRIB_FSAA, + ATTRIB_RESIZABLE, + ATTRIB_MIN_WIDTH, + ATTRIB_MIN_HEIGHT, + ATTRIB_BORDERLESS, + ATTRIB_CENTERED, + ATTRIB_DISPLAY, + ATTRIB_MAX_ENUM + }; + + enum FullscreenType + { + FULLSCREEN_TYPE_NORMAL, + FULLSCREEN_TYPE_DESKTOP, + FULLSCREEN_TYPE_MAX_ENUM + }; + struct WindowSize { int width; @@ -53,36 +74,86 @@ public: virtual ~Window(); - virtual bool setWindow(int width = 800, int height = 600, WindowFlags *flags = 0) = 0; - virtual void getWindow(int &width, int &height, WindowFlags &flags) const = 0; + virtual bool setWindow(int width = 800, int height = 600, WindowAttributes *attribs = 0) = 0; + virtual void getWindow(int &width, int &height, WindowAttributes &attribs) = 0; - virtual bool checkWindowSize(int width, int height, bool fullscreen) const = 0; - virtual WindowSize **getFullscreenSizes(int &n) const = 0; + virtual bool setFullscreen(bool fullscreen, FullscreenType fstype) = 0; + virtual bool setFullscreen(bool fullscreen) = 0; + + virtual bool onWindowResize(int width, int height) = 0; + + virtual int getDisplayCount() const = 0; + + virtual std::vector getFullscreenSizes(int displayindex) const = 0; virtual int getWidth() const = 0; virtual int getHeight() const = 0; + virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0; + virtual bool isCreated() const = 0; - virtual void setWindowTitle(std::string &title) = 0; - virtual std::string getWindowTitle() const = 0; + virtual void setWindowTitle(const std::string &title) = 0; + virtual const std::string &getWindowTitle() const = 0; virtual bool setIcon(love::image::ImageData *imgd) = 0; + virtual love::image::ImageData *getIcon() = 0; // default no-op implementation virtual void swapBuffers(); virtual bool hasFocus() const = 0; + virtual bool hasMouseFocus() const = 0; + + virtual bool isVisible() const = 0; + virtual void setMouseVisible(bool visible) = 0; virtual bool getMouseVisible() const = 0; + virtual void setMouseGrab(bool grab) = 0; + virtual bool isMouseGrabbed() const = 0; + + virtual const void *getHandle() const = 0; + + //virtual static Window *createSingleton() = 0; //virtual static Window *getSingleton() = 0; - // No virtual statics, of course, but you are supposed to implement this static. + // No virtual statics, of course, but you are supposed to implement these statics. + + static bool getConstant(const char *in, Attribute &out); + static bool getConstant(Attribute in, const char *&out); + + static bool getConstant(const char *in, FullscreenType &out); + static bool getConstant(FullscreenType in, const char *&out); protected: + static Window *singleton; +private: + + static StringMap::Entry attributeEntries[]; + static StringMap attributes; + + static StringMap::Entry fullscreenTypeEntries[]; + static StringMap fullscreenTypes; + }; // Window + +struct WindowAttributes +{ + WindowAttributes(); + bool fullscreen; // = false + Window::FullscreenType fstype; // = FULLSCREEN_TYPE_NORMAL + bool vsync; // = true + int fsaa; // = 0 + bool resizable; // = false + int minwidth; // = 1 + int minheight; // = 1 + bool borderless; // = false + bool centered; // = true + int display; // = 0 +}; // WindowFlags + } // window } // love diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index dea7f3527..400706687 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -18,16 +18,16 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -// STL -#include - -// SDL -#include - // LOVE #include "common/config.h" +#include "graphics/Graphics.h" #include "Window.h" +// C++ +#include +#include +#include + namespace love { namespace window @@ -38,123 +38,208 @@ namespace sdl Window::Window() : windowTitle("") , created(false) + , mouseGrabbed(false) + , window(0) + , context(0) { - // Window should be centered. - SDL_putenv(const_cast("SDL_VIDEO_CENTERED=center")); - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) - throw love::Exception(SDL_GetError()); + throw love::Exception("%s", SDL_GetError()); } Window::~Window() { + if (curMode.icon) + curMode.icon->release(); + + if (window) + SDL_DestroyWindow(window); + + if (context) + SDL_GL_DeleteContext(context); + SDL_QuitSubSystem(SDL_INIT_VIDEO); } Window::_currentMode::_currentMode() - : width(800), height(600), fullscreen(false), vsync(true), fsaa(0) + : width(800) + , height(600) + , attribs() + , icon(0) { } -bool Window::setWindow(int width, int height, WindowFlags *flags) +bool Window::setWindow(int width, int height, WindowAttributes *attribs) { - bool fullscreen = false; - bool vsync = true; - int fsaa = 0; - bool resizable = false; - bool borderless = false; + graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics."); + if (gfx) + gfx->unSetMode(); - if (flags) + WindowAttributes f; + + if (attribs) + f = *attribs; + + f.minwidth = std::max(f.minwidth, 1); + f.minheight = std::max(f.minheight, 1); + + f.display = std::min(std::max(f.display, 0), getDisplayCount()); + + // Use the desktop resolution if a width or height of 0 is specified. + if (width == 0 || height == 0) { - fullscreen = flags->fullscreen; - vsync = flags->vsync; - fsaa = flags->fsaa; - resizable = flags->resizable; - borderless = flags->borderless; + SDL_DisplayMode mode = {}; + SDL_GetDesktopDisplayMode(f.display, &mode); + width = mode.w; + height = mode.h; } - bool mouseVisible = getMouseVisible(); - int keyrepeatDelay, keyrepeatInterval; - SDL_GetKeyRepeat(&keyrepeatDelay, &keyrepeatInterval); + Uint32 sdlflags = SDL_WINDOW_OPENGL; - // We need to restart the subsystem for two reasons: - // 1) Special case for fullscreen -> windowed. Windows XP did not - // work well with "normal" display mode change in this case. - // The application window does leave fullscreen, but the desktop - // resolution does not revert to the correct one. Restarting the - // SDL video subsystem does the trick, though. - // 2) Restart the event system (for whatever reason the event system - // started and stopped with SDL_INIT_VIDEO, see: - // http://sdl.beuc.net/sdl.wiki/Introduction_to_Events) - // because the mouse position will not be able to exceed - // the previous' video mode window size (i.e. alway - // love.mouse.getX() < 800 when switching from 800x600 to a - // higher resolution) - SDL_QuitSubSystem(SDL_INIT_VIDEO); - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + if (f.fullscreen) { - std::cout << "Could not init SDL_VIDEO: " << SDL_GetError() << std::endl; + if (f.fstype == FULLSCREEN_TYPE_DESKTOP) + sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + else + { + sdlflags |= SDL_WINDOW_FULLSCREEN; + + // Fullscreen window creation will bug out if no mode can be used. + SDL_DisplayMode mode = {0, width, height, 0, 0}; + if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == 0) + return false; + } + } + + if (f.resizable) + sdlflags |= SDL_WINDOW_RESIZABLE; + + if (f.borderless) + sdlflags |= SDL_WINDOW_BORDERLESS; + + // Destroy and recreate the window if the dimensions or flags have changed. + if (window) + { + int curdisplay = SDL_GetWindowDisplayIndex(window); + Uint32 wflags = SDL_GetWindowFlags(window); + wflags &= (SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS); + + if (sdlflags != wflags || width != curMode.width || height != curMode.height + || f.display != curdisplay || f.fsaa != curMode.attribs.fsaa) + { + SDL_DestroyWindow(window); + window = 0; + + // The old window may have generated pending events which are no + // longer relevant. Destroy them all! + SDL_FlushEvent(SDL_WINDOWEVENT); + } + } + + int centeredpos = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display); + int uncenteredpos = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display); + + if (!window) + { + // In Windows and Linux, some GL attributes are set on window creation. + setWindowGLAttributes(f.fsaa); + + const char *title = windowTitle.c_str(); + int pos = f.centered ? centeredpos : uncenteredpos; + + window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags); + + if (!window && f.fsaa > 0) + { + // FSAA might have caused the failure, disable it and try again. + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + + window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags); + f.fsaa = 0; + } + + // Make sure the window keeps any previously set icon. + if (window && curMode.icon) + setIcon(curMode.icon); + } + + if (!window) + { + std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl; return false; } - // Set caption. - setWindowTitle(windowTitle); - setMouseVisible(mouseVisible); - SDL_EnableKeyRepeat(keyrepeatDelay, keyrepeatInterval); + // Enforce minimum window dimensions. + SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight); - // Set GL attributes - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vsync ? 1 : 0)); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); + if (f.centered && !f.fullscreen) + SDL_SetWindowPosition(window, centeredpos, centeredpos); - // FSAA - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0); + SDL_RaiseWindow(window); - Uint32 sdlflags = SDL_OPENGL; - // Flags - if (fullscreen) - sdlflags |= SDL_FULLSCREEN; - if (resizable) - sdlflags |= SDL_RESIZABLE; - if (borderless) - sdlflags |= SDL_NOFRAME; - - // Have SDL set the video mode. - SDL_Surface *surface; - if ((surface = SDL_SetVideoMode(width, height, 32, sdlflags)) == 0) - { - bool failed = true; - if (fsaa > 0) - { - // FSAA might have caused the failure, disable it and try again - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); - failed = SDL_SetVideoMode(width, height, 32, sdlflags) == 0; - } - if (failed) - { - std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl; - return false; - } - } + if (!setContext(f.fsaa, f.vsync)) + return false; created = true; - if (width == 0 || height == 0) + updateAttributes(f); + + if (gfx) + gfx->setMode(curMode.width, curMode.height); + + // Make sure the mouse keeps its previous grab setting. + setMouseGrab(mouseGrabbed); + + return true; +} + +bool Window::onWindowResize(int width, int height) +{ + if (!window) + return false; + + curMode.width = width; + curMode.height = height; + + return true; +} + +bool Window::setContext(int fsaa, bool vsync) +{ + // We would normally only need to recreate the context if FSAA changes or + // SDL_GL_MakeCurrent is unsuccessful, but in Windows MakeCurrent can + // sometimes claim success but the context will actually be trashed. + if (context) { - const SDL_VideoInfo *videoinfo = SDL_GetVideoInfo(); - width = videoinfo->current_w; - height = videoinfo->current_h; + SDL_GL_DeleteContext(context); + context = 0; } + // Make sure the proper attributes are set. + setWindowGLAttributes(fsaa); + + context = SDL_GL_CreateContext(window); + + if (!context && fsaa > 0) + { + // FSAA might have caused the failure, disable it and try again. + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + context = SDL_GL_CreateContext(window); + } + + if (!context) + { + std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl; + return false; + } + + // Set vertical synchronization. + SDL_GL_SetSwapInterval(vsync ? 1 : 0); + + // Verify FSAA setting. int buffers; int samples; - SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples); @@ -165,78 +250,198 @@ bool Window::setWindow(int width, int height, WindowFlags *flags) fsaa = (buffers > 0) ? samples : 0; } - // Get the actual vsync status - int real_vsync; - SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &real_vsync); - - // Set the new display mode as the current display mode. - currentMode.width = width; - currentMode.height = height; - currentMode.fsaa = fsaa; - currentMode.fullscreen = fullscreen; - currentMode.vsync = (real_vsync != 0); - currentMode.resizable = ((surface->flags & SDL_RESIZABLE) != 0); - currentMode.borderless = ((surface->flags & SDL_NOFRAME) != 0); + curMode.attribs.fsaa = fsaa; + curMode.attribs.vsync = SDL_GL_GetSwapInterval() != 0; return true; } -void Window::getWindow(int &width, int &height, WindowFlags &flags) const +void Window::setWindowGLAttributes(int fsaa) const { - width = currentMode.width; - height = currentMode.height; - flags.fullscreen = currentMode.fullscreen; - flags.vsync = currentMode.vsync; - flags.fsaa = currentMode.fsaa; - flags.resizable = currentMode.resizable; - flags.borderless = currentMode.borderless; + // Set GL window attributes. + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); + + // FSAA. + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0); } -bool Window::checkWindowSize(int width, int height, bool fullscreen) const +void Window::updateAttributes(const WindowAttributes &newattribs) { - Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL; + Uint32 wflags = SDL_GetWindowFlags(window); - // Check if mode is supported - int bpp = SDL_VideoModeOK(width, height, 32, sdlflags); + // Set the new display mode as the current display mode. + SDL_GetWindowSize(window, &curMode.width, &curMode.height); - return (bpp >= 16); + if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) + { + curMode.attribs.fullscreen = true; + curMode.attribs.fstype = FULLSCREEN_TYPE_DESKTOP; + } + else if ((wflags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) + { + curMode.attribs.fullscreen = true; + curMode.attribs.fstype = FULLSCREEN_TYPE_NORMAL; + } + else + { + curMode.attribs.fullscreen = false; + curMode.attribs.fstype = newattribs.fstype; + } + + // The min width/height is set to 0 internally in SDL when in fullscreen. + if (curMode.attribs.fullscreen) + { + curMode.attribs.minwidth = newattribs.minwidth; + curMode.attribs.minheight = newattribs.minheight; + } + else + SDL_GetWindowMinimumSize(window, &curMode.attribs.minwidth, &curMode.attribs.minheight); + + curMode.attribs.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0; + curMode.attribs.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0; + curMode.attribs.centered = newattribs.centered; + curMode.attribs.display = std::max(SDL_GetWindowDisplayIndex(window), 0); + + // Only minimize on focus loss if the window is in exclusive-fullscreen + // mode (mimics behaviour of SDL 2.0.2+). + // In OS X we always disable this to prevent dock minimization weirdness. +#ifndef LOVE_MACOSX + if (curMode.attribs.fullscreen && curMode.attribs.fstype == FULLSCREEN_TYPE_NORMAL) + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1"); + else +#endif + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); +} + +void Window::getWindow(int &width, int &height, WindowAttributes &attribs) +{ + // Window position may be different from creation - update display index. + if (window) + curMode.attribs.display = std::max(SDL_GetWindowDisplayIndex(window), 0); + + width = curMode.width; + height = curMode.height; + attribs = curMode.attribs; +} + +bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype) +{ + if (!window) + return false; + + WindowAttributes newattribs = curMode.attribs; + newattribs.fullscreen = fullscreen; + newattribs.fstype = fstype; + + Uint32 sdlflags = 0; + + if (fullscreen) + { + if (fstype == FULLSCREEN_TYPE_DESKTOP) + sdlflags = SDL_WINDOW_FULLSCREEN_DESKTOP; + else + { + sdlflags = SDL_WINDOW_FULLSCREEN; + + SDL_DisplayMode mode = {}; + mode.w = curMode.width; + mode.h = curMode.height; + + SDL_GetClosestDisplayMode(SDL_GetWindowDisplayIndex(window), &mode, &mode); + SDL_SetWindowDisplayMode(window, &mode); + } + } + + if (SDL_SetWindowFullscreen(window, sdlflags) == 0) + { + SDL_GL_MakeCurrent(window, context); + updateAttributes(newattribs); + + // Update the viewport size now instead of waiting for event polling. + graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics."); + if (gfx) + gfx->setViewportSize(curMode.width, curMode.height); + + return true; + } + + return false; +} + +bool Window::setFullscreen(bool fullscreen) +{ + return setFullscreen(fullscreen, curMode.attribs.fstype); +} + +int Window::getDisplayCount() const +{ + return SDL_GetNumVideoDisplays(); } typedef Window::WindowSize WindowSize; -WindowSize **Window::getFullscreenSizes(int &n) const +std::vector Window::getFullscreenSizes(int displayindex) const { - SDL_Rect **modes = SDL_ListModes(0, SDL_OPENGL | SDL_FULLSCREEN); + std::vector sizes; - if (modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1) + SDL_DisplayMode mode = {}; + std::vector::const_iterator it; + for (int i = 0; i < SDL_GetNumDisplayModes(displayindex); i++) { - n = 0; - return NULL; + SDL_GetDisplayMode(displayindex, i, &mode); + + // SDL2's display mode list has multiple entries for modes of the same + // size with different bits per pixel, so we need to filter those out. + bool alreadyhassize = false; + for (it = sizes.begin(); it != sizes.end(); ++it) + { + if (it->width == mode.w && it->height == mode.h) + { + alreadyhassize = true; + break; + } + } + + if (!alreadyhassize) + { + WindowSize w = {mode.w, mode.h}; + sizes.push_back(w); + } } - n = 0; - for (int i = 0; modes[i]; i++) - n++; - - WindowSize **sizes = new WindowSize*[n]; - - for (int i = 0; i < n; i++) - { - sizes[i] = new WindowSize; - sizes[i]->width = modes[i]->w; - sizes[i]->height = modes[i]->h; - } return sizes; } int Window::getWidth() const { - return currentMode.width; + return curMode.width; } int Window::getHeight() const { - return currentMode.height; + return curMode.height; +} + +void Window::getDesktopDimensions(int displayindex, int &width, int &height) const +{ + if (displayindex >= 0 && displayindex < getDisplayCount()) + { + SDL_DisplayMode mode = {}; + SDL_GetDesktopDisplayMode(displayindex, &mode); + width = mode.w; + height = mode.h; + } + else + { + width = 0; + height = 0; + } } bool Window::isCreated() const @@ -244,22 +449,32 @@ bool Window::isCreated() const return created; } -void Window::setWindowTitle(std::string &title) +void Window::setWindowTitle(const std::string &title) { windowTitle = title; - SDL_WM_SetCaption(windowTitle.c_str(), 0); + + if (window) + SDL_SetWindowTitle(window, title.c_str()); } -std::string Window::getWindowTitle() const +const std::string &Window::getWindowTitle() const { - // not a reference - // because we want this untouched - // const std::string& might be an option return windowTitle; } bool Window::setIcon(love::image::ImageData *imgd) { + if (!imgd) + return false; + + imgd->retain(); + if (curMode.icon) + curMode.icon->release(); + curMode.icon = imgd; + + if (!window) + return false; + Uint32 rmask, gmask, bmask, amask; #ifdef LOVE_BIG_ENDIAN rmask = 0xFF000000; @@ -273,24 +488,50 @@ bool Window::setIcon(love::image::ImageData *imgd) amask = 0xFF000000; #endif - int w = static_cast(imgd->getWidth()); - int h = static_cast(imgd->getHeight()); - int pitch = static_cast(imgd->getWidth() * 4); + int w = imgd->getWidth(); + int h = imgd->getHeight(); + int pitch = imgd->getWidth() * 4; + + SDL_Surface *sdlicon = 0; + + { + // We don't want another thread modifying the ImageData mid-copy. + love::thread::Lock lock(imgd->getMutex()); + sdlicon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask); + } + + if (!sdlicon) + return false; + + SDL_SetWindowIcon(window, sdlicon); + SDL_FreeSurface(sdlicon); - SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask); - SDL_WM_SetIcon(icon, NULL); - SDL_FreeSurface(icon); return true; } +love::image::ImageData *Window::getIcon() +{ + return curMode.icon; +} + void Window::swapBuffers() { - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(window); } bool Window::hasFocus() const { - return (SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0; + return (window && SDL_GetKeyboardFocus() == window); +} + +bool Window::hasMouseFocus() const +{ + return (window && SDL_GetMouseFocus() == window); +} + +bool Window::isVisible() const +{ + return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_SHOWN) != 0; } void Window::setMouseVisible(bool visible) @@ -300,10 +541,30 @@ void Window::setMouseVisible(bool visible) bool Window::getMouseVisible() const { - return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) ? true : false; + return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE); } -love::window::Window *Window::getSingleton() +void Window::setMouseGrab(bool grab) +{ + mouseGrabbed = grab; + if (window) + SDL_SetWindowGrab(window, (SDL_bool) grab); +} + +bool Window::isMouseGrabbed() const +{ + if (window) + return (bool) SDL_GetWindowGrab(window); + else + return mouseGrabbed; +} + +const void *Window::getHandle() const +{ + return window; +} + +love::window::Window *Window::createSingleton() { if (!singleton) singleton = new Window(); @@ -313,6 +574,11 @@ love::window::Window *Window::getSingleton() return singleton; } +love::window::Window *Window::getSingleton() +{ + return singleton; +} + const char *Window::getName() const { return "love.window.sdl"; diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index b6857c48f..b6e7ca953 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -22,7 +22,10 @@ #define LOVE_WINDOW_SDL_WINDOW_H // LOVE -#include +#include "window/Window.h" + +// SDL +#include namespace love { @@ -34,48 +37,83 @@ namespace sdl class Window : public love::window::Window { public: + Window(); ~Window(); - bool setWindow(int width = 800, int height = 600, WindowFlags *flags = 0); - void getWindow(int &width, int &height, WindowFlags &flags) const; + bool setWindow(int width = 800, int height = 600, WindowAttributes *attribs = 0); + void getWindow(int &width, int &height, WindowAttributes &attribs); - bool checkWindowSize(int width, int height, bool fullscreen) const; - WindowSize **getFullscreenSizes(int &n) const; + bool setFullscreen(bool fullscreen, FullscreenType fstype); + bool setFullscreen(bool fullscreen); + + bool onWindowResize(int width, int height); + + int getDisplayCount() const; + + std::vector getFullscreenSizes(int displayindex) const; int getWidth() const; int getHeight() const; + void getDesktopDimensions(int displayindex, int &width, int &height) const; + bool isCreated() const; - void setWindowTitle(std::string &title); - std::string getWindowTitle() const; + void setWindowTitle(const std::string &title); + const std::string &getWindowTitle() const; bool setIcon(love::image::ImageData *imgd); + love::image::ImageData *getIcon(); void swapBuffers(); bool hasFocus() const; + bool hasMouseFocus() const; + + bool isVisible() const; + void setMouseVisible(bool visible); bool getMouseVisible() const; + void setMouseGrab(bool grab); + bool isMouseGrabbed() const; + + const void *getHandle() const; + + static love::window::Window *createSingleton(); static love::window::Window *getSingleton(); const char *getName() const; + private: + + bool setContext(int fsaa, bool vsync); + void setWindowGLAttributes(int fsaa) const; + + // Update the saved window attribs based on the window's actual state. + void updateAttributes(const WindowAttributes &newattribs); + std::string windowTitle; + struct _currentMode { _currentMode(); + int width; int height; - bool fullscreen; - bool vsync; - int fsaa; - bool resizable; - bool borderless; - } currentMode; + WindowAttributes attribs; + love::image::ImageData *icon; + + } curMode; + bool created; + + bool mouseGrabbed; + + SDL_Window *window; + SDL_GLContext context; + }; // Window } // sdl diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp new file mode 100644 index 000000000..799c5e93d --- /dev/null +++ b/src/modules/window/wrap_Window.cpp @@ -0,0 +1,341 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#include "wrap_Window.h" +#include "sdl/Window.h" + +namespace love +{ +namespace window +{ + +static Window *instance = 0; + +int w_getDisplayCount(lua_State *L) +{ + lua_pushinteger(L, instance->getDisplayCount()); + return 1; +} + +static const char *attribName(Window::Attribute attrib) +{ + const char *name = nullptr; + Window::getConstant(attrib, name); + return name; +} + +int w_setMode(lua_State *L) +{ + int w = luaL_checkint(L, 1); + int h = luaL_checkint(L, 2); + + if (lua_isnoneornil(L, 3)) + { + luax_pushboolean(L, instance->setWindow(w, h, 0)); + return 1; + } + + luaL_checktype(L, 3, LUA_TTABLE); + + // We want to error for invalid / misspelled window attributes. + lua_pushnil(L); + while (lua_next(L, 3)) + { + if (lua_type(L, -2) != LUA_TSTRING) + return luax_typerror(L, -2, "string"); + + const char *key = luaL_checkstring(L, -2); + Window::Attribute attrib; + + if (!Window::getConstant(key, attrib)) + return luaL_error(L, "Invalid window attribute: %s", key); + + lua_pop(L, 1); + } + + WindowAttributes attribs; + + lua_getfield(L, 3, attribName(Window::ATTRIB_FULLSCREEN_TYPE)); + if (!lua_isnoneornil(L, -1)) + { + const char *typestr = luaL_checkstring(L, -1); + + if (!Window::getConstant(typestr, attribs.fstype)) + return luaL_error(L, "Invalid fullscreen type: %s", typestr); + } + else + { + // Default to "normal" fullscreen. + attribs.fstype = Window::FULLSCREEN_TYPE_NORMAL; + } + lua_pop(L, 1); + + attribs.fullscreen = luax_boolflag(L, 3, attribName(Window::ATTRIB_FULLSCREEN), false); + attribs.vsync = luax_boolflag(L, 3, attribName(Window::ATTRIB_VSYNC), true); + attribs.fsaa = luax_intflag(L, 3, attribName(Window::ATTRIB_FSAA), 0); + attribs.resizable = luax_boolflag(L, 3, attribName(Window::ATTRIB_RESIZABLE), false); + attribs.minwidth = luax_intflag(L, 3, attribName(Window::ATTRIB_MIN_WIDTH), 1); + attribs.minheight = luax_intflag(L, 3, attribName(Window::ATTRIB_MIN_HEIGHT), 1); + attribs.borderless = luax_boolflag(L, 3, attribName(Window::ATTRIB_BORDERLESS), false); + attribs.centered = luax_boolflag(L, 3, attribName(Window::ATTRIB_CENTERED), true); + attribs.display = luax_intflag(L, 3, attribName(Window::ATTRIB_DISPLAY), 1); + + // Display index is 1-based in Lua and 0-based internally. + attribs.display--; + + EXCEPT_GUARD(luax_pushboolean(L, instance->setWindow(w, h, &attribs));) + return 1; +} + +int w_getMode(lua_State *L) +{ + int w, h; + WindowAttributes attribs; + instance->getWindow(w, h, attribs); + lua_pushnumber(L, w); + lua_pushnumber(L, h); + + lua_newtable(L); + + const char *fstypestr = "normal"; + Window::getConstant(attribs.fstype, fstypestr); + + lua_pushstring(L, fstypestr); + lua_setfield(L, -2, attribName(Window::ATTRIB_FULLSCREEN_TYPE)); + + luax_pushboolean(L, attribs.fullscreen); + lua_setfield(L, -2, attribName(Window::ATTRIB_FULLSCREEN)); + + luax_pushboolean(L, attribs.vsync); + lua_setfield(L, -2, attribName(Window::ATTRIB_VSYNC)); + + lua_pushinteger(L, attribs.fsaa); + lua_setfield(L, -2, attribName(Window::ATTRIB_FSAA)); + + luax_pushboolean(L, attribs.resizable); + lua_setfield(L, -2, attribName(Window::ATTRIB_RESIZABLE)); + + lua_pushinteger(L, attribs.minwidth); + lua_setfield(L, -2, attribName(Window::ATTRIB_MIN_WIDTH)); + + lua_pushinteger(L, attribs.minheight); + lua_setfield(L, -2, attribName(Window::ATTRIB_MIN_HEIGHT)); + + luax_pushboolean(L, attribs.borderless); + lua_setfield(L, -2, attribName(Window::ATTRIB_BORDERLESS)); + + luax_pushboolean(L, attribs.centered); + lua_setfield(L, -2, attribName(Window::ATTRIB_CENTERED)); + + // Display index is 0-based internally and 1-based in Lua. + lua_pushinteger(L, attribs.display + 1); + lua_setfield(L, -2, attribName(Window::ATTRIB_DISPLAY)); + + return 3; +} + +int w_getFullscreenModes(lua_State *L) +{ + int displayindex = luaL_optint(L, 1, 1) - 1; + + std::vector modes = instance->getFullscreenSizes(displayindex); + + lua_createtable(L, modes.size(), 0); + + for (size_t i = 0; i < modes.size(); i++) + { + lua_pushinteger(L, i+1); + lua_createtable(L, 0, 2); + + // Inner table attribs. + + lua_pushinteger(L, modes[i].width); + lua_setfield(L, -2, "width"); + + lua_pushinteger(L, modes[i].height); + lua_setfield(L, -2, "height"); + + // Inner table attribs end. + + lua_settable(L, -3); + } + + return 1; +} + +int w_setFullscreen(lua_State *L) +{ + bool fullscreen = luax_toboolean(L, 1); + Window::FullscreenType fstype = Window::FULLSCREEN_TYPE_MAX_ENUM; + + const char *typestr = lua_isnoneornil(L, 2) ? 0 : luaL_checkstring(L, 2); + if (typestr && !Window::getConstant(typestr, fstype)) + return luaL_error(L, "Invalid fullscreen type: %s", typestr); + + bool success = false; + if (fstype == Window::FULLSCREEN_TYPE_MAX_ENUM) + success = instance->setFullscreen(fullscreen); + else + success = instance->setFullscreen(fullscreen, fstype); + + luax_pushboolean(L, success); + return 1; +} + +int w_getFullscreen(lua_State *L) +{ + int w, h; + WindowAttributes attribs; + instance->getWindow(w, h, attribs); + + const char *typestr; + if (!Window::getConstant(attribs.fstype, typestr)) + luaL_error(L, "Unknown fullscreen type."); + + luax_pushboolean(L, attribs.fullscreen); + lua_pushstring(L, typestr); + return 2; +} + +int w_isCreated(lua_State *L) +{ + luax_pushboolean(L, instance->isCreated()); + return 1; +} + +int w_getWidth(lua_State *L) +{ + lua_pushinteger(L, instance->getWidth()); + return 1; +} + +int w_getHeight(lua_State *L) +{ + lua_pushinteger(L, instance->getHeight()); + return 1; +} + +int w_getDimensions(lua_State *L) +{ + lua_pushinteger(L, instance->getWidth()); + lua_pushinteger(L, instance->getHeight()); + return 2; +} + +int w_getDesktopDimensions(lua_State *L) +{ + int width = 0, height = 0; + int displayindex = luaL_optint(L, 1, 1) - 1; + instance->getDesktopDimensions(displayindex, width, height); + lua_pushinteger(L, width); + lua_pushinteger(L, height); + return 2; +} + +int w_setIcon(lua_State *L) +{ + image::ImageData *i = luax_checktype(L, 1, "ImageData", IMAGE_IMAGE_DATA_T); + luax_pushboolean(L, instance->setIcon(i)); + return 1; +} + +int w_getIcon(lua_State *L) +{ + image::ImageData *i = instance->getIcon(); + if (i) + { + i->retain(); + luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, i); + } + else + lua_pushnil(L); + return 1; +} + +int w_setTitle(lua_State *L) +{ + std::string title = luax_checkstring(L, 1); + instance->setWindowTitle(title); + return 0; +} + +int w_getTitle(lua_State *L) +{ + luax_pushstring(L, instance->getWindowTitle()); + return 1; +} + +int w_hasFocus(lua_State *L) +{ + luax_pushboolean(L, instance->hasFocus()); + return 1; +} + +int w_hasMouseFocus(lua_State *L) +{ + luax_pushboolean(L, instance->hasMouseFocus()); + return 1; +} + +int w_isVisible(lua_State *L) +{ + luax_pushboolean(L, instance->isVisible()); + return 1; +} + +static const luaL_Reg functions[] = +{ + { "getDisplayCount", w_getDisplayCount }, + { "setMode", w_setMode }, + { "getMode", w_getMode }, + { "getFullscreenModes", w_getFullscreenModes }, + { "setFullscreen", w_setFullscreen }, + { "getFullscreen", w_getFullscreen }, + { "isCreated", w_isCreated }, + { "getWidth", w_getWidth }, + { "getHeight", w_getHeight }, + { "getDimensions", w_getDimensions }, + { "getDesktopDimensions", w_getDesktopDimensions }, + { "setIcon", w_setIcon }, + { "getIcon", w_getIcon }, + { "setTitle", w_setTitle }, + { "getTitle", w_getTitle }, + { "hasFocus", w_hasFocus }, + { "hasMouseFocus", w_hasMouseFocus }, + { "isVisible", w_isVisible }, + { 0, 0 } +}; + +extern "C" int luaopen_love_window(lua_State *L) +{ + EXCEPT_GUARD(instance = sdl::Window::createSingleton();) + + WrappedModule w; + w.module = instance; + w.name = "window"; + w.flags = MODULE_T; + w.functions = functions; + w.types = 0; + + return luax_register_module(L, w); +} + +} // window +} // love diff --git a/src/modules/window/wrap_Window.h b/src/modules/window/wrap_Window.h new file mode 100644 index 000000000..6bba9a574 --- /dev/null +++ b/src/modules/window/wrap_Window.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2006-2014 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. + **/ + +#ifndef LOVE_WINDOW_WRAP_WINDOW_H +#define LOVE_WINDOW_WRAP_WINDOW_H + +#include "common/config.h" +#include "common/runtime.h" + +namespace love +{ +namespace window +{ + +int w_getDisplayCount(lua_State *L); +int w_setMode(lua_State *L); +int w_getMode(lua_State *L); +int w_getFullscreenModes(lua_State *L); +int w_setFullscreen(lua_State *L); +int w_getFullscreen(lua_State *L); +int w_isCreated(lua_State *L); +int w_getWidth(lua_State *L); +int w_getHeight(lua_State *L); +int w_getDimensions(lua_State *L); +int w_getDesktopDimensions(lua_State *L); +int w_setIcon(lua_State *L); +int w_getIcon(lua_State *L); +int w_setTitle(lua_State *L); +int w_getTitle(lua_State *L); +int w_hasFocus(lua_State *L); +int w_hasMouseFocus(lua_State *L); +int w_isVisible(lua_State *L); +extern "C" LOVE_EXPORT int luaopen_love_window(lua_State *L); + +} // window +} // love + +#endif // LOVE_WINDOW_WRAP_WINDOW_H diff --git a/src/scripts/audio.lua b/src/scripts/audio.lua deleted file mode 100644 index c2946bac7..000000000 --- a/src/scripts/audio.lua +++ /dev/null @@ -1,41 +0,0 @@ ---[[ -Copyright (c) 2006-2013 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. ---]] - -function love.audio.newSource(a, b) - if type(a) == "string" then - a = love.filesystem.newFile(a) - end - if type(a) == "userdata" then - if a:typeOf("File") then - a = love.sound.newDecoder(a) - end - - if a:typeOf("Decoder") then - if b == "static" then - a = love.sound.newSoundData(a) - end - return love.audio.newSource1(a) - end - if a:typeOf("SoundData") then - return love.audio.newSource1(a) - end - end - error("No matching overload") -end \ No newline at end of file diff --git a/src/scripts/audio.lua.h b/src/scripts/audio.lua.h deleted file mode 100644 index 1350c64e6..000000000 --- a/src/scripts/audio.lua.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2006-2013 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. - **/ - -namespace love -{ - -// [audio.lua] -const unsigned char audio_lua[] = -{ - - 0x2d, 0x2d, 0x5b, 0x5b, 0x0a, - 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, - 0x2d, 0x32, 0x30, 0x31, 0x33, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, - 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x0a, - 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x27, 0x61, 0x73, 0x2d, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x0a, - 0x77, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x74, 0x79, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x6e, 0x6f, 0x20, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x73, 0x20, 0x62, 0x65, 0x20, 0x68, 0x65, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x0a, - 0x61, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, - 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, - 0x65, 0x2e, 0x0a, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, - 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x2c, 0x0a, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, - 0x61, 0x6c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x0a, - 0x66, 0x72, 0x65, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x73, - 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x0a, - 0x31, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, - 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x69, 0x73, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, - 0x74, 0x65, 0x64, 0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x0a, - 0x20, 0x20, 0x20, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, 0x20, - 0x77, 0x72, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, - 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20, - 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2c, 0x20, 0x61, - 0x6e, 0x20, 0x61, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, - 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x64, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x61, 0x70, 0x70, 0x72, 0x65, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x75, 0x74, - 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, - 0x32, 0x2e, 0x20, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x6c, 0x79, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x73, - 0x75, 0x63, 0x68, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x62, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x6d, 0x69, 0x73, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, - 0x61, 0x73, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x0a, - 0x33, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x79, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x6f, 0x72, - 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6e, 0x79, 0x20, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x0a, - 0x2d, 0x2d, 0x5d, 0x5d, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, - 0x6f, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x28, 0x61, 0x2c, 0x20, 0x62, 0x29, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x61, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x28, 0x61, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x61, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x75, 0x73, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x61, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x66, 0x28, 0x22, 0x46, 0x69, 0x6c, - 0x65, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x2e, - 0x6e, 0x65, 0x77, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x61, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x61, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x66, 0x28, 0x22, 0x44, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x73, 0x6f, 0x75, 0x6e, 0x64, - 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x61, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, - 0x69, 0x6f, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x31, 0x28, 0x61, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x61, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x66, 0x28, 0x22, 0x53, 0x6f, 0x75, - 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, - 0x69, 0x6f, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x31, 0x28, 0x61, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x4e, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, - 0x67, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x29, 0x0a, - 0x65, 0x6e, 0x64, 0x0a, -}; // [audio.lua] -} // love \ No newline at end of file diff --git a/src/scripts/auto.lua b/src/scripts/auto.lua index fdaa90212..5d027e339 100644 --- a/src/scripts/auto.lua +++ b/src/scripts/auto.lua @@ -7,7 +7,7 @@ local max_width = 18 local pattern = [[ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -107,7 +107,8 @@ end for i, v in ipairs(arg) do --run the auto function for every argument --but do it with pcall, to catch errors - local ok, err = pcall(auto, v:gsub("%.lua$","")) + v = v:gsub("%.lua$", ""):gsub("^(.+)/", "") -- normalize input + local ok, err = pcall(auto, v) if not ok then --inform people we've failed print(v .. ": " .. err) diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index 536ece438..a02e698b8 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -1,5 +1,5 @@ --[[ -Copyright (c) 2006-2013 LOVE Development Team +Copyright (c) 2006-2014 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 @@ -18,16 +18,13 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. --]] --- Make sure love table exists. -if not love then love = {} end +-- Make sure love exists. +local love = require("love") -- Used for setup: love.path = {} love.arg = {} --- Unparsed arguments: -argv = {} - -- Replace any \ with /. function love.path.normalslashes(p) return string.gsub(p, "\\", "/") @@ -156,33 +153,67 @@ function love.createhandlers() -- Standard callback handlers. love.handlers = setmetatable({ keypressed = function (b, u) - if love.keypressed then love.keypressed(b, u) end + if love.keypressed then return love.keypressed(b, u) end end, keyreleased = function (b) - if love.keyreleased then love.keyreleased(b) end + if love.keyreleased then return love.keyreleased(b) end + end, + textinput = function (t) + if love.textinput then return love.textinput(t) end + end, + textedit = function (t,s,l) + if love.textedit then return love.textedit(t,s,l) end end, mousepressed = function (x,y,b) - if love.mousepressed then love.mousepressed(x,y,b) end + if love.mousepressed then return love.mousepressed(x,y,b) end end, mousereleased = function (x,y,b) - if love.mousereleased then love.mousereleased(x,y,b) end + if love.mousereleased then return love.mousereleased(x,y,b) end end, joystickpressed = function (j,b) - if love.joystickpressed then love.joystickpressed(j,b) end + if love.joystickpressed then return love.joystickpressed(j,b) end end, joystickreleased = function (j,b) - if love.joystickreleased then love.joystickreleased(j,b) end + if love.joystickreleased then return love.joystickreleased(j,b) end + end, + joystickaxis = function (j,a,v) + if love.joystickaxis then return love.joystickaxis(j,a,v) end + end, + joystickhat = function (j,h,v) + if love.joystickhat then return love.joystickhat(j,h,v) end + end, + gamepadpressed = function (j,b) + if love.gamepadpressed then return love.gamepadpressed(j,b) end + end, + gamepadreleased = function (j,b) + if love.gamepadreleased then return love.gamepadreleased(j,b) end + end, + gamepadaxis = function (j,a,v) + if love.gamepadaxis then return love.gamepadaxis(j,a,v) end + end, + joystickadded = function (j) + if love.joystickadded then return love.joystickadded(j) end + end, + joystickremoved = function(j) + if love.joystickremoved then return love.joystickremoved(j) end end, focus = function (f) - if love.focus then love.focus(f) end + if love.focus then return love.focus(f) end + end, + mousefocus = function (f) + if love.mousefocus then return love.mousefocus(f) end + end, + visible = function (v) + if love.visible then return love.visible(v) end end, quit = function () return end, + threaderror = function (t, err) + if love.threaderror then return love.threaderror(t, err) end + end, resize = function(w, h) - local ow, oh, flags = love.graphics.getMode() - love.graphics.setMode(w, h, flags) - if love.resize then love.resize(w, h) end + if love.resize then return love.resize(w, h) end end, }, { __index = function(self, name) @@ -195,6 +226,12 @@ end local is_fused_game = false local no_game_code = false +local function uridecode(s) + return s:gsub("%%%x%x", function(str) + return string.char(tonumber(str:sub(2), 16)) + end) +end + -- This can't be overriden. function love.boot() @@ -219,10 +256,13 @@ function love.boot() if not can_has_game and o.game.set and o.game.arg[1] then local nouri = o.game.arg[1] if nouri:sub(1, 7) == "file://" then - nouri = nouri:sub(8) + nouri = uridecode(nouri:sub(8)) end local full_source = love.path.getfull(nouri) local leaf = love.path.leaf(full_source) + leaf = leaf:gsub("^([%.]+)", "") -- strip leading "."'s + leaf = leaf:gsub("%.([^%.]+)$", "") -- strip extension + leaf = leaf:gsub("%.", "_") -- replace remaining "."'s with "_" love.filesystem.setIdentity(leaf) can_has_game = pcall(love.filesystem.setSource, full_source) end @@ -231,6 +271,8 @@ function love.boot() no_game_code = true end + love.filesystem.setFused(is_fused_game) + if not can_has_game then love.nogame() end @@ -244,14 +286,20 @@ function love.init() -- will NOT make it load, see below. local c = { title = "Untitled", - author = "Unnamed", version = love._version, - screen = { + window = { width = 800, height = 600, + minwidth = 1, + minheight = 1, fullscreen = false, + fullscreentype = "normal", + display = 1, vsync = true, fsaa = 0, + borderless = false, + resizable = false, + centered = true, }, modules = { event = true, @@ -265,12 +313,14 @@ function love.init() math = true, physics = true, sound = true, + system = true, font = true, thread = true, + window = true, }, console = false, -- Only relevant for windows. identity = false, - release = false, + appendidentity = false, } -- If config file exists, load it and allow it to update config table. @@ -288,14 +338,6 @@ function love.init() end end - if c.release then - love._release = { - title = c.title ~= "Untitled" and c.title or nil, - author = c.author ~= "Unnamed" and c.author or nil, - url = c.url - } - end - if love.arg.options.console.set then c.console = true end @@ -309,9 +351,11 @@ function love.init() "joystick", "mouse", "sound", + "system", "audio", "image", "font", + "window", "graphics", "math", "physics", @@ -325,44 +369,49 @@ function love.init() love.createhandlers() end - -- Setup screen here. - local has_window = false - if c.screen and c.modules.graphics then - if love.graphics.checkMode(c.screen.width, c.screen.height, c.screen.fullscreen) or (c.screen.width == 0 and c.screen.height == 0) then - assert(love.graphics.setMode(c.screen.width, c.screen.height, - { - fullscreen = c.screen.fullscreen, - vsync = c.screen.vsync, - fsaa = c.screen.fsaa, - resizable = c.screen.resizable, - borderless = c.screen.borderless, - }), "Could not set screen mode") - else - error("Could not set screen mode") - end - love.graphics.setCaption(c.title) + -- Console hack + if c.console and love._openConsole then + love._openConsole() end - -- Our first timestep, because screen creation can take some time + -- Setup window here. + if c.window and c.modules.window then + assert(love.window.setMode(c.window.width, c.window.height, + { + fullscreen = c.window.fullscreen, + fullscreentype = c.window.fullscreentype, + vsync = c.window.vsync, + fsaa = c.window.fsaa, + resizable = c.window.resizable, + minwidth = c.window.minwidth, + minheight = c.window.minheight, + borderless = c.window.borderless, + centered = c.window.centered, + display = c.window.display, + }), "Could not set window mode") + love.window.setTitle(c.window.title or c.title) + if c.window.icon then + assert(love.image, "If an icon is set in love.conf, love.image has to be loaded!") + love.window.setIcon(love.image.newImageData(c.window.icon)) + end + end + + -- Our first timestep, because window creation can take some time if love.timer then love.timer.step() end if love.filesystem then - love.filesystem.setRelease(c.release and is_fused_game) - if c.identity then love.filesystem.setIdentity(c.identity) end - if love.filesystem.exists("main.lua") then require("main") end + love.filesystem.setIdentity(c.identity or love.filesystem.getIdentity(), c.appendidentity) + if love.filesystem.exists("main.lua") then + require("main") + end end if no_game_code then error("No code to run\nYour game might be packaged incorrectly\nMake sure main.lua is at the top level of the zip") end - -- Console hack - if c.console and love._openConsole then - love._openConsole() - end - -- Check the version local compat = false c.version = tostring(c.version) @@ -375,18 +424,27 @@ function love.init() if not compat then local major, minor, revision = c.version:match("^(%d+)%.(%d+)%.(%d+)$") if (not major or not minor or not revision) or (major ~= love._version_major and minor ~= love._version_minor) then - local msg = "This game was made for a version that is probably incompatible.\n".. - "The game might still work, but it is not guaranteed.\n" .. - "Furthermore, this means one should not judge this game or the engine if not." + local msg = "This game was made for a different version of LÖVE.\n".. + "It may not be not be compatible with the running version ("..love._version..")." + print(msg) - if has_window and love.timer and love.event then - love.event.pump() + + local can_display = love.window and love.window.isCreated() + can_display = can_display and love.graphics and love.graphics.isCreated() + + if can_display and love.timer and love.event then love.graphics.setBackgroundColor(89, 157, 220) - love.graphics.clear() - love.graphics.print(msg, 70, 70) - love.graphics.present() + love.graphics.origin() + + local start = love.timer.getTime() + while love.timer.getTime() < start + 4 do + love.event.pump() + love.graphics.clear() + love.graphics.print(msg, 70, 70) + love.graphics.present() + love.timer.sleep(1/20) + end love.graphics.setBackgroundColor(0, 0, 0) - love.timer.sleep(3) end end end @@ -395,11 +453,19 @@ end function love.run() - math.randomseed(os.time()) - math.random() math.random() + if love.math then + love.math.setRandomSeed(os.time()) + end + + if love.event then + love.event.pump() + end if love.load then love.load(arg) end + -- We don't want the first frame's dt to include time taken by love.load. + if love.timer then love.timer.step() end + local dt = 0 -- Main loop time. @@ -428,12 +494,14 @@ function love.run() -- Call update and draw if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled - if love.graphics then + + if love.window and love.graphics and love.window.isCreated() then love.graphics.clear() + love.graphics.origin() if love.draw then love.draw() end + love.graphics.present() end - if love.graphics then love.graphics.present() end if love.timer then love.timer.sleep(0.001) end end @@ -445,236 +513,976 @@ end ----------------------------------------------------------- function love.nogame() - local pig_png = - "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\ - bWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp\ - bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6\ - eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz\ - NDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo\ - dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw\ - dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv\ - IiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RS\ - ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD\ - cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlE\ - PSJ4bXAuaWlkOjdCQTYxREYxOUQ5RDExRTBBNjY4RTc1NEVEQTU1MERDIiB4bXBNTTpEb2N1bWVu\ - dElEPSJ4bXAuZGlkOjdCQTYxREYyOUQ5RDExRTBBNjY4RTc1NEVEQTU1MERDIj4gPHhtcE1NOkRl\ - cml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6N0JBNjFERUY5RDlEMTFFMEE2NjhF\ - NzU0RURBNTUwREMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6N0JBNjFERjA5RDlEMTFFMEE2\ - NjhFNzU0RURBNTUwREMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1l\ - dGE+IDw/eHBhY2tldCBlbmQ9InIiPz6gRGuzAAAYXklEQVR42uydX2hcV37Hz4xkeTdxNrITkpBk\ - 0/EmgWxLbKlhyZZCPYJtSw3FUpe+FTzzsG9LLdFCH2W9FzwufeuDRtDX4tGLS0tBo0IpS1s8Tmk3\ - S9x4kniXeMnKk7/eWLLU87vzu9LV/L/3nnPv79z7/cBlFEcjjc45v+/5/s7fwsHBgQIA5JMiigAA\ - CAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAg\ - AAAACAAAAAIAAIAAAAAgAAAACAAAAAIAAIAAAAAgAAAACAAAAAIAADDBdNg3FAoFax+m89f/XNYv\ - 9JzXz6x+5viVaPJrSz8f0OvsX/5BE1UIQD+T3vlZCHs5qGkB0EFPAb6sn8v6KYV9OwvDpn4aWhA6\ - qHoAHBEAHfwU+KuBXj4uDf1saCFooAkACIBQAeBe/wbbfRu09XNdP3W4AgABECQAHPxbnN/bpsNC\ - UIMQAAhAP4nOAiQc/IpTC0ox7urffRXNAoAUHYAOwi2Ltn/S1GAFYwQgLXimi2jZdKXiUgDugVeF\ - 1ENTP1VdAW00SWAgqMnRltjZPh1wuMFp7HG0OGX1p7mbun22MiEArHpbAutuTRcyUgMQJoWdU0dr\ - VUqW09nI09zSBOBWgnl/WFrsBlpo4qCn3ZY42C9w+02zDVPwN7jTajsjALoQK/pl3YH6hhtAwFMP\ - v8gBX1bhF6YlRY3ba8cFAbgruCAHuYEll8cGdi7WZgf0VOWYPU/QHXXO3FxuZSjo5zjoLwl2qYNo\ - s3NtihUAh3r/3gZflThToIPbH1TyX/09E7MpNd6gONDrpyowmKWFoiM46C9z4JeU21BbrUsVgLsO\ - FzAtHlpJKdB9+1liO1pyuBybLAi3WRxIGNoIersikLoACB75D5sSLNicr+Vgn+PePO2BpqSFoeUL\ - g420ggfxrmQ06HuZDw5kSxAAsv6VLKSJLAItA8E+q45Glcs5CvYw6cQ2iYMWhGbEoPcH8q7krHzb\ - uo2elSQAD5S5XX4SGufKoFwLAW/dJWyyILQmDH6bm8ykcziTlaoA6IpY5IrIVGPUhbswQdD7C0Uu\ - 5bgh2hLhBjuExqgBxoD1r2SoE5qojHQbPS1BALJi/4m6GrP4goM+qwNMUmkE3EF7RFuscN3kRYy9\ - AcG0BcB1++9vI64PC3wEvbhUYWOUM+BZgCsZ6piGCqNus0upCQAX9C3HA3/g+QE66EvqaIAJQS/X\ - GWxoIWiMSA8qXIeZTA902y2kKQB0zNe1jAX+YqC3B+7UKaVv1welCDHPopTOwtN/8fvNtATApfx/\ - aOBzb1/JaAPJZYqghaA+YpxgNUP1vKIFoJaWAEje+TdJ4Jc56CuIm8zR5rGC2qCxggwJQU0LwEpa\ - AnDgcOBT5ZcRJ7lID7yttUPSgwqnsa6OETS1ACwkLgDCl/8O3EKpAz9r9g+Eoz5ICAJjBC4OFqYm\ - ABRM6xIruHc6D4EPQgrBahYFYNrwL5YUTE3VXb7bGmD1ryksywXHoQ6hotvHMSFgx3hVC0GdRaCS\ - pT/atANI+9Rfgiqu76AE5PggJGtqwGAhp7nSO5CJHUCWbgf2N+ycDQY/TefpZ53HJhD8YFK8+yQ4\ - VTyE2pZ+5qmT4TbnNKYFIK0AI3tGgV/r6fWvqu6qxAraM4gA5f/ruh3dYgcZFAKvzanu4LKzTDte\ - QaPs/rrCAB8wA9n9LR4fWPHTAh4fWNFpwaawtKCduAPgNdZJUhtg92f1c43tPoIfmKbCacHikLRg\ - Tcjn/CCNFCCpgPNP6Fnp6fWpUugMwmW0U2A5Lbih29sNPvAlKASUcs6H6YEz4wASgqb05of0+jdU\ - vg5/AOmyOMQNtFgEGhAAs9S552/35Pq30OsDSW6AxgZoT35aKcGwuwJsC0DZ4t9E03vV4DJeHuFH\ - rg+kuIFbfEhMb0qQ9HRhqPRDugPw8/1aj+WnwF9FuwOCKLEILPeIgOdcExSBVlYEwD+TP5jvk8Le\ - VVjQA+RyjRae9aQELRaBdgK/fzsLAuAHfysQ/BXO9zHQB6RDbXWLD5UJisB82B46Ak3XBYAO4pzv\ - yfdpUc862hVwiDlOCcoBEeiwE7AlAp2wF9gUBQZ/tSffv6GwlBe4ySw7gUpCItAM+wZJArDWG/yq\ - O8qPgziB66zzrJVtEdh2VQCq/pVGHPxzHPzYsw+ywiqnsjZFoOGiABy72hjBDzJMxaIItEbdXiVV\ - AIYFP0b6AUQgHBtR3lRE8AOQCRFouCQAdQQ/gAgYE4FI9j8tAeid6kPwA4jAkQjQJqKwy4Y3on6A\ - pAWgOWCqD9t4AUTgSATaKvzegYYEARhnQVqsbsHgx24+ALoisBwQgWOxMi74o9r/JAWA1KzacysP\ - 9fyY6gOgy7WeFYNN1d1KbM3+J5kCVHs29pDlKaPOAegTgbmACNTV6FOH2/p7GtIFoBb8kKxyFdQ1\ - AH34eweCW4np7Mumjd4/iRSgFTy8k9UNu/oAGCMCPf+2NCS+amIEYMBARCeYwwRG/AEAo5njg279\ - 2PKnB4PUe2+6lpYCrPXsTcZFHQBMznLwxGGOpeBR+EYOHDUtAO2A9Q+e40dTHNjWC0A4eo8Wq/F4\ - QD3O1F+QaQsCUAoqFR+LhAM8AYg2HkBpc/Cm36rJX2DaAXRYnZqBf8NKPwCiU+5ZJNQ21fvbEIDb\ - wdyEPzgW+wAQj9XgAaMmKRwcHIR7Q6Ew0ffxB8YpvgCYoXHm5vKky4PVpHFtcxbgGoIfAGMsBk8Y\ - lpoC+L0/fVCM+gNglnUnBEBhtR8ANigFTxcWKQC81r+EugLACleCawMkOgDM+QNgDwr+ZZECgN4f\ - ALdcgGkHgN4fAIdcgDEBQO8PgHsuwKQDQO8PQLIuoCJCAHjeH70/AAm7ACkO4ArqAoDEKQXPDEhF\ - AHjNP1b9AZAOl9N2AAh+ANJjMc5goAkBuIw6ACBVKqkIANt/7PcHwNE0IK4DgP0HIH3moh4YElcA\ - YP8BkEE5UQHggQfYfwBkcClpBwD7D0BeHYDmAsocADHMRjkyLI4AlFHmALjtAiIJAOf/JZQ3AKI4\ - n5QDwOAfAPKYS0oAYP8BkEcp7LLgqAJwHmUNgPsuIKoA4MIPAHIsAEgBAJCJ3RTA5JnkAADjXLAq\ - AAozAABkhiKKAACMAYShhDIGIKdjABAAAJACAAAgAAAACAAAQAxhtgVDAACAAwAAZIgWBACAnHLm\ - 5nIHAgAAsCIAHRQbAPkVgBaKDYD8CgAAQC5N2wLQRhkDkFMHcObmMgQAALmEStGnI/4SEoESytod\ - CqefUIWZqeP/9uRJVTh1cuh79u9/1v9vD75S6tFjFKhcPoUA5M3GPf+UUiemVfHME/p1ygt279/p\ - tSfowzD15osj//+BFoMDEoPdPf31Q/31XvffvnikDr78GhXjwBhAVAHYVjgXMJVA93pt6s31EzfA\ - jbgK/z9ePj1YILQQkDiQm4B7SIR2EgKAcQDbwcWB7gU9vzqZdpBIaXHw3URXEL7SgvC599DXwBxh\ - x+iiCgDWAtjo4XWgUKD7QZ9ZYdNP0XcM2hHs//KzriB81EHqkKD9jywAWmVaOxdrtCLQ6gnBD/cf\ - qZ98eUc//6fuPdo5/hmmT6lz33xFvf3kq+rlmTNuVpe271MU9N+ePQqIvKHLwBM++vvfesUTABKC\ - x+9/4qQ7oDb7zsMPvTb73q8/7muzr598Qb196lXv1QLbiQhAQG0WbRXkP356W219/r9egQ5iZ+8L\ - 1dT/n563n3xN/fD099Q3izMI+gw4hKk3nveeQzF4974TzoAC/+9/9W8j2+xP9u54ndrr33hB/cns\ - 90x3Xq0kBWDbhgBQ4f3NL/+pr8cfBRUoFf6fP/eHYt0AWXqvYVPQpzhw56wYaDdAQkDOQCIU+NQO\ - J4XcAbVz6rioA0srBSgm+csmIWzw9woHqawkpr7zrDrxgzfUzMXf8r5G8EcX0OnfOatO/ulvq+lz\ - L3ni4GrwB9ssvZc6LxO9f5htwLEFgMYBlOHZgH948B+Rgj9YoH/3yZaYwJ9ZPOc1WhdH8EWnUG++\ - eFi2aQtBN9+/E1tAhqUNIdiM8qa4m4GMuQA/p48LCUjcCjEV+JJ6qSwSLOu0nBV1WibSXgM/p5GG\ - AGyaKsitz39qrFKaBn9WGItKVh+Bn44QnLx03ksNkoQ6GlMpJ/2sGC6gzY48WQHQv5RUx8gBIYby\ - oEMXkNhYgO55pt96xcvxYfVlpAZJ1cN7v75vPJ1Isvc34QCIuqkUwCT3dnesNwBqaN7g3hvPIwCF\ - QO7Lc2JalK0LwNcfG/15O3tfRn3rRpoCsCGtIImfP3pgtfLJblJDg90XmhZoUSZxtlk/xjutaAPg\ - raj234gA8C/Pz9JgbTVPXHht7E45IMANnH7CqdTs4UGkMYDrsVysoc8e60O8fML84p0z009aCf4Z\ - 3etjBZ9jgq3rzFuDYbyNnTL68yIsD+7Eyf9NCkCswUBawmt6Ge9LpkWFgz+rm3SyDs3OmBYB0x1X\ - hE6rEWXxj3EB4A8RywXQxh6Tymx0STCCHyIwqMf+htnB3wgOYC3u7zR5KnA9zptph5Qpvm9ubbXH\ - CZrbR/BnQwTeesVYXdIaflPOlTYHhUwp6ibO5zQmAPxhIosAqZ8JF0CFWH7qu+YazLmXkPNnbUzg\ - wmtGVg5S8C889ZtGPhbtDAzJhonfa/pegFiW5M+e+d3YimriZ/h4O/gw2p85aGpw+k0zqwb/6Onz\ - Xu8dB9oRGDJlpdy/KU4A2AXU4igqbemNGsAU/CYPWkhiMQlIB1onYGp68EfPLkQec6I0ohzeRayY\ - KgcbNwORC4g8MkkFufbiD0OpKtn+v3rhj03uqz48mgtkWAQMuQC/4woTyPQe6rDoCUnd5N0chYOD\ - g3BvKBTGfs/OxdpV/bIa98PRCsHmZz8dukaaxILy/bcND/oRlCci988+jxrvGD1tiFYH3vz0ttdm\ - B23uoc7q+16v/90oTpc61vlJBGDSuLYiACwCd5XBuwN6lwvTHKy1I8BmpryDJ0D2oVOG9v7rQys/\ - m5b2Blf3PTN1Ku7ioTUd/Fcn+cZJ43raYtlW9WPsdA5LhygOtobo+XODzTTP8PF07UmDP+0xgK7V\ - 6Y5SNlxsFJjzzw8O1XXVigAm8KE7aBQgry7AEDVT036JCgAvEa6iiQEQ3forA0t+03IA/qlBDdRj\ - 91os72jr//6F99BtOGAy6Dhwv9y8o8Hzc8dgNe6Gn1FMJ/VH6GdO5fhGYWq4e+/8fKD9PPF7r+O4\ - 8GGi+eArtbt9p2+qbm/mQ6/cMr5Ww5r1T8wBBFKBJWeKfXcvkeAnyAU8+pd3EelDHBOVzcB5eu0A\ - dun/Gbg+jK4zFwid9LNi+5cUk/pr+OSgFSca3oOHRhvxsOAP9nJSb7xJk73//Gis1Y89h69/vsBr\ - xxLrMItJ/lVaBGifQF28Xf/I3HmCdLfdRN8HAegvk3vj68G7YjxGANPNxAJZMrncV4wAMOQCRJ8h\ - SD2ysV5h9zEiOUpghhggjWPhJxXoJOPDdt6fqgDweMCCEr4+YP/9X5n5QScwuBepYYZYi1E4FXFJ\ - uLb/j+89kPRn19klq8wKgCsisPfux0ammuga8Im+D8uPjzMzNdEIPy3ainr09+Of3Zc0ndjUcZH4\ - mpliWn8tDwrKXSREvcPP4t/84l9xPa4R43KRfrzzGMZMj0Y9s8EbnH33Yyl/KsVCKrNkxTT/al4k\ - JFYEaPTexDQTNdJhAe6dXf+DNxDtQ8pm6BoJupItxs3Lk8wwJBj8CzYX+4wsY1vbgcOwc7FW0S/r\ - UhuhF6AGFuqQmOzf66j9+595zqCgG6+N8+ozB7mx9z85HBgs+uUWsU5sbgEOSYeD3/igeOrnAWRJ\ - BCg/9w6SBM5DIrIrY+GVteAPIwBFKRWjC6IuNR2g+ei9f7+L6HEcb1nxv76X+eB3ZgzAJREgCwoR\ - cDv4vSXX6ef9YoJfnABABIAt2y8k+Cnoz0oJfpECEBCBJSVwnQCJwKOb/5On7ahOQwN+u3KCP7XR\ - fqcEgEWApghFLhYiO/n15m3s55cM7RbcviNltL8uMfgJMbMAw9i5WCvplxuqe56AOGh+37tlBvv5\ - RVl+StWE7PKrJbGtt6+Tcm0acIwI0HpamiJclNjgvKumYixKAeZ6ferxBW2trnI6qyAAZoTgqjJw\ - 4Yi1fEoLAAlB1LXpIEauT4euGNq/YYDUR/ozKQAsAovsBmalNkZapTZ17kUIQRKBT2cFvvMLSYd6\ - NFV3P3+q+X5mBcCFcQEIgX2rT9t4hQU+sWbj8g4IwHAhuKZflqW3V2/tOt1Giy2/8Rq1DnY6p0GQ\ - 1Q9a/qUkD/KAAByJQJlTgpL0BuxtDX71WVX8zjNwBSFtPp3csy/r8A4fb0ertCm+3AgAiwCNB6y6\ - 4AYOy5HOANApAh0YAjHoh4Kdgt47sUfmoqsOB77IOy9yJQAuuoE+Mfj2aZ0izOb3WjLO6w/ufy45\ - 6EX3+rkXAFfdwDFmprzbiemsABo7yKw70AFOJ/LSoh3vZF8DB68kQFt1D+0Uf9NVbgUgIAQ0Q0CD\ - hGWnA4XOxnvuW6p45glVeO6p7mGZDq469I/vph5+n05ddiPgg9D9fDXJvT4EYLAQVFgIZlVWIFGg\ - wzD5QEzv9dRM+m6BenUK7N0973KV/Z3u8eoOBnuQJtv99jEr8LdNak/l0o/LGANwQARmOSW4kikh\ - GCEORPH5bx3V23P9y5THLV327kfoycW9YOa7Dg6++Lob4HS7jttBPszuVwdN7engr3CaWdLPvBaB\ - FgTADSEoccVVFADDA39t0Br+nsA/dAhaABYgABAC4DaU218flOfrwC9zeykPee+CFoEmBABCAPIV\ - +GJdAAQAQgAmsPr6acQI/CCixgIgAP35Gw0CtkZZNRYCEoHsDxbmFwrS60Ny/CiB71PXbasKAZAr\ - AA84qEkANnRl1UcIAX3fouof8AHuQvW9MWRUP07gB1OJs7pddSAAMgXgYJgFHFVpvLz4MtIDZ23+\ - hureutse0CZ8t2dqW3l1VMcCAZAlAEHlpkq7riuvPYErMNlgQPK9vb8m5LIFd0edyRIEwC0BOFaB\ - LATNUd/EYwVXWBCQIsiA6m5TDRjU4/qf4zqz6eQ6uu2chgDIC36y8VshrePY9IDFYI57E4iBvKCf\ - VUeDuknVjYjZAAhAv/rfiqLoAVcwtlJZDPwxA6QJFnpY1R3EHRr0XN+LAVFOGhHjABCAaCnAKLzp\ - o0lcQc+YwQUWBbiD6OXuBf2oI7dY5P3B2jSncNd0+7gKAcieAAy0npNO+wTcwQV2BxCE0QG/Ta+j\ - tt8Ggl5S+gUByIEABPEbayNM7scDiSQI51kQyjkM9jYH/G0O9uYE9VjigJeaZkEAhArA3QR6CT9H\ - 9Rp02A0i7BJ8d3CBX7PiFJoc8B/w162wh2voOtxyQCidEoDpnPU2toPJz/u9VYS6wQYdQotFYWij\ - 55tkWgOEocw/m8ThaX6dFdYDdgKffTvw3+1Bi3Aisp1Tp2SNPDkAKXcItAMuoWViGykLhE/w698Y\ - IXqDBKQ5JvgGBbvJAJfi5OLg1CxAnhzAB0I+BzXeSqBB+4G3qRtOLcoP7MmdmxmvR9pwsyX487Vc\ - KsxijgRAcmD4Fh+MU8+uY6oJ/XhticeDQQC6DafF1hUC5X5drgjtaTdcK8tiztpOQ3CjhgCEY0mY\ - oHcEOxMIALOJ3j8zLqCtXxYEicCalLMAIADDG01DaBqwiZCOnNatSHCWUQdwIQDJcx2pSaZEoK66\ - MwNp0Ur590MAQlIT5gJaow4iAROLwHwK9Uqp24KL1j+3AsCVJckFXEcIG0sHFlRyswM1Ogrc5eDP\ - qwPwXYCEXrcD+29FBGzm4y3u9VeyUGa5vRcgwilBNhCxcSSLGDrp99iP5Pqqu/D3YzfgZI3kKjeS\ - tHr/s65bSEeEwD+/MQrk0Dak3gIMAYjfQNZVOkd+V13pTTJSzyV2A5dUdz/GsJ2UTbb53oEkrgo0\ - BEC2CIg5Phpkk0njuoii8gaPaB43qd6YcskqSh1IAAJwXASqyu5cMv3sJeT9AAIgUwTIBdCCEhsD\ - PtTzL7i2XRRkG4wBDB8XKCtz00gkKFX0/EDaGAAEYLwQlFT0a8Cot19zbQoJQAAgAIPFwD+++zyL\ - QXlAju9PITVg90HmBAAAkB0wCAgABAAAAAEAAEAAAAAQAAAABAAAAAEAAEAAAAAQAAAABAAAAAEA\ - AEAAAAAQAAAABAAAAAEAAEAAAAAQAAAABAAAAAEAAEAAAAAQAAAABAAAAAEAAEAAAAD2+H8BBgCz\ - 4xkvbY9d6gAAAABJRU5ErkJggg==" - local heart_png = - "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ\ - bWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp\ - bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6\ - eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz\ - NDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo\ - dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw\ - dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv\ - IiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RS\ - ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD\ - cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlE\ - PSJ4bXAuaWlkOjk3NUYxN0NGOUQ5RDExRTA5MTgyQjc4MkNEQkY5RkI1IiB4bXBNTTpEb2N1bWVu\ - dElEPSJ4bXAuZGlkOjk3NUYxN0QwOUQ5RDExRTA5MTgyQjc4MkNEQkY5RkI1Ij4gPHhtcE1NOkRl\ - cml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTc1RjE3Q0Q5RDlEMTFFMDkxODJC\ - NzgyQ0RCRjlGQjUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTc1RjE3Q0U5RDlEMTFFMDkx\ - ODJCNzgyQ0RCRjlGQjUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1l\ - dGE+IDw/eHBhY2tldCBlbmQ9InIiPz7MtgYTAAACd0lEQVR42uyajW2CUBDHH8YBWKBJR8AJChvY\ - AZriBNYJrBOIE9imA6gTyAZlg9p0ATaw99IzfSEgvI9DlLvk5UUUuPu9/71PvePxKPpsA9FzYwAM\ - gAEwAAbAABgAA2AADIABMAAG0EcbmtzkeV7p9Z+nVQhViB8PUNK7j+nBxkF4ZgzVHMp9ydeZfAeU\ - d3hPVnZ/3X6HZ7IhUgQATgZQraEEJT+XDi7AwVQzcB+qjQK0zuTzJ0Xg5ACw1aWjfs1tCTg30wh+\ - XwH0nOVQIlUNpACw5fcNglclKx3MCYJXIYxOSqiLb2CRm75m8AKD+kJwVba2CF6gP+s2RoGlZvCq\ - g/syCHDtFaqxg849hGeNyQDAw2WPHFu20gZVpKbT3OEI90ypgKkDB+9RCScIG8dDfCMFDE0l5shJ\ - 2epLgPBdMc5bGaoqowAQOPQzFnTmU6XAVViTydctA2g0Bb9lAGnfAewoAaQdDz6H/N9SAth1HMCK\ - eiq87XLry5UnKQBcaXUVwurcatNlJzi79ta3AoAqSDoGYKHT+tYbIjjf/nQ8NTa1DIIfFS+SbYgo\ - 9ojSu7RNTG6yBoCpEF0YwqJqV5g8BQpLT90tMjLpt5kCJyVkqIRDi8HnptInWQsghFHdJoRDm5lK\ - n2wxhMOQVMIbcfDynMH6Hc76gDKDfuFF/O0eO1/qQvBRkx+21gdUqCHBlHDZL2Q49Dox8v0ApV9I\ - HAUf6c72LpYCJSkRYkoEbQXfyumwAYhYVB95O235TgIogJjWKCKVOW8q+04DKMwi5UnOg/g/dMlx\ - imvVd5AAuCXjP0kxAAbAABgAA2AADIABMAAGwAB6ab8CDACjlPepVvE3rwAAAABJRU5ErkJggg==" - local hearts = {} - local rings = {} - - local cx = 400 - local cy = 300 - - local pig - local heart_image - - local function add_heart_ring(radius, number, speed) - local step = math.pi*2/number - for i = 1,number do - local heart = { - radius = radius, - position = step*i, - speed = speed, - opacity = radius/450 - } - table.insert(hearts, heart) - end - table.insert(rings, radius) - end - - local function update_hearts(dt) - for i,v in ipairs(hearts) do - v.position = v.position + v.speed*dt*0.6 - end - end - - local function draw_hearts() - for i,v in ipairs(hearts) do - local x = math.cos(v.position) * v.radius + cx - local y = math.sin(v.position) * v.radius + cy - love.graphics.setColor(255, 255, 255, v.opacity*255) - love.graphics.draw(heart_image, x, y, v.position+0.4, 1, 1, 32, 32) - end - end - - local function draw_pig(p) - love.graphics.setColor(255, 255, 255, 255) - love.graphics.draw(p.img, p.x, p.y, 0, 1, 1, 128, 128) - end + local baby_png = + "iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAL1klEQVR4nO2deZAU1R3HPz3X\ + 3ruzuywEXZVLBJHAilfUpAQNGo1RPDAxKiaKkpQHlZBKhTIRjSaWlCmrrCJBDR7RaMSUBx6x\ + ElmhCIogi8dKFEQEYWGXva+Znunp/NGzbO/szuwc/XZ39r1P1dT2dr/+9a/7ffv1u59mmiYK\ + eXENtwOK4UUJQHKUACRHCUBylAAkRwlAcpQAJEcJQHKUACRHCUBylAAkRwlAcpQAJEcJQHKU\ + ACRHCUBylAAkRwlAcpQAJEcJQHKUACRHCUBylAAkRwlAcpQAJEcJQHKUACRHCUBylAAkRwlA\ + cjzD7UC2YNRWO2LHPWOuI3acwlEBaJrmpLkRQ/iT9T2blwBXAMcATwL/iO6vAJ4GLgQ+A34A\ + 7AImA9cCRcAzwEdOPCMn53RQKUDy3AKstv3/pG37aeCi6PY04FtAEPgYyIvurwK+K9bF1FEC\ + GATb23+bbXcj8HJ0eyG9kQ9QCzwH/IneyAd4TZCLGaEygclxOjDT9v+zWG94MfBwTNglwDjg\ + Ztu+RuAxkQ6mi0oBEmB7+2+KOfR49O89wHjb/jXAJuDvQK5t/++ALgEuZozmZIZitGUCowLI\ + Bw5hZeQAtmGlCFOxkvuel6gNmIL1rX/LZqYmGt7wnDLPEb+yMhNoe5uyjavojXzoffvvpe/z\ + ux8IA3+17dOBGwEDBn8GTgkkFYQLIOam5wInpGmqmOHJs9xu2w4BpcB9WJm/HjoBDagGKm37\ + XwFOjf7smEAr0AE0AQeAw7ECGQpBCP8ERG9Kw8os3eHYxUYfrcAHwH+wShF7ew7ECsHROBMp\ + AJuiVwB3O3ah0U8E61OylGjm0S4CJ+NsKJLUKuCuIbjOaMIFLMaqO3CLvpAQbG//cgTfxChm\ + LlYmVBiiU4ASYIHga4x2zhdpXLQAvo16+zOlcvAg6SO6GHhaMoGONLfy5qatbK75lLqGJgK6\ + ztgyP7OnTebCc+YwY8oEwW6K4UhzK29sfJ93P9zJwfpG9FCYirISqqZPYf45c5gxOakSsS7S\ + R2GlgGgeYDVWK9qAhMJhVj23jideeovuYPz7nHfmbO669VqOHTfGMV9FoofCPPLsyzz1yr8J\ + 6qG44c4/q4rfLvkx4yvKEpl7Bbg8W0sBhfEOdHR1s2j5SlY9vy5h5AOs37KDBXfew4ef7XHc\ + Qadp7+zmht88yKNr30gY+QBvv1fDgjtWULt7b6JgcZ+hE4gWgD/egWUrH+WD2l1JG2pt7+SW\ + ux+mrqHJEcdEYJomSx9YRc3O3Umf09zWweK7H6ahqTVekHGOOBeHoSgF9OOtTduofv/DlI21\ + tHewcs3ajJ0Sxesb32fT9tqUz2tsaWPlE3HvqwLEtaUMiwBWv/B62gZf37iF/Yca0j5fJJnc\ + 16vV73KwoXGgQxUIjCfRAiiN3VHX0ETtF19lZHT9lh0ZnS+CfXX1fL7367TPN02TdwZOFV1A\ + edqGB0GIAGzJVUXssS/212Vsf48DNpxm74HDGdvYve9gvENx81KZIjIF8AO+2J3tnZl3jGlp\ + 78zYhtO0tHdkbKMt/rPJSgEMmHst9xdnbLiidMCsxbAyxgGfEtxXv0+pU4gUwNiBdp40oRK3\ + O7PLzjgx3T4l4pg28ThcGXaJOzl+zaAfxJQEHK8Ktjk5fqDjJUUFnHvqKWzY+lFa9nN8Xuad\ + MTulcw42NLLpg0/4qq6elrYOugJBy5bXi8ulUZCfR2lxIePKSzl+/FimTTyOooK8Qaz2payk\ + iLOrTk6rGAiQl+PjvNNnxTs8C/gnYDgtAkcFYHNuFv170h7lzusuZ+O2j9Oq0vzpggspKSpI\ + OnwoHOby21fQmkK+QdM0Lj3vLFYuW5ySb3dctyBtAdx81fcSiW45cAPwK+B5o7basSFmjn0C\ + bGPnHsDqCTs/XtgZUyZw68JLUr7G9EnHs+SH30/pnKbW9pQiH6wi2avV71Lf1JLSebNOmsTN\ + V140eMAYZk6dyOKrLh4sWCXWaKQJKV8gAU7nAa4Dfo3VBzAhS69fwE1XJP+wZk6dyJr7fkmu\ + r1/BIiHjykupTKMR6Zix5WllNpf95GoWXZb8CLCqaZN5dMVScnzeZILnAA+l7FQCHGsNjKYA\ + 7wFnpnLef2tqWblmLTv37BvwuL+okMVXX8yiyy7A60nvi/WvTVu5849/Tjq8S9NYvWIp3zlt\ + 5uCB47Bx28c89OSL/O/L/QMe9xcVsuSaS7j+0gvweFLqMtEN5Dv1CXBaADqQlJRj2blnH5t3\ + fEpdfRN6KMSY0hKqpk/mzG9Ox+fNPKvyzLq3+cNjz2EYkYThxpb5uff2Rcw9I26GLGlM02Tn\ + nv1srqnl0JFm9FCIijI/s6dNyvS+tJEqgBG9Fv2er+t4/MU3Wb9lB81tvRU3ebk5zDppEvPP\ + nsOV889N+TMzxOwCpo5UAewDjnPEoGCONLcS1EPk5vgcqZwaQm4EnhpxpYAoTzlsTxhjSks4\ + dtyYbIr8IPALHH7GTlcE/R5rTPzP6Ts2XpEZnwIXAHXg7DQzTqcAOrCMJDuDKpJmF9HId3q8\ + oGMCcM+Ya3cua9LVbELEYFFRjUHCmi8lJSjKsBJAdtAtyrDjAjA0NygBOE32CCDgKybozZ8Q\ + 0dT8Uw4i7BPgeH+Azlw/YXfuTN2Tiy/cTU6oM/rrwmsEnL6cLAjrBu24AALeYiIudweA7slH\ + 9+TTnmf1DXWZBr5QFznhLnJCnfjCXXgMoUPfRgsbunLEdINzXAARlxusZsv+xzQ3AV8RAV/v\ + nEuuSBhfuNv268JrBNHMxI022Yjh8hDRPERcHiKaG8PlJqK5ifT81Ty920f3uU00zZ8XjDty\ + KCOGfZ7AiMvTTxQAHkPHawTwGgE8ho7bCOGJ6HgMHZcZRnNwgGSmhN0+Qu5cwm4fhssb/VkR\ + 3RPphiv9lj9gYWdOqZCZRkUJoDlTA2G3j7DbR3ecOiXNjKCl0PiomZE+onGZRmJbpokrQSoU\ + cbkx0Qi5c4ikH7nJUoWgORhFef6lILtHMTVXam3PWlbPU1E0eJD0EFVWWyfIrqwcEGVYlABq\ + gA2CbMvIdlGGHRfAlLFHKwGXO21bYoS9TCKr6zYDLwi0LwsmsFGUcSECsKUCtwFHRFxDIrYD\ + 9aKMi66wbyDBJFGKpHgN+rxUjiJMADaHXwIeFHWdUY6B4H6WQlOAmAzhyJ3cZ+TyOILrVIaq\ + zdYAfoQ1abRq/UmOtVi9gIUl/zAEArA5b2CtqnEi8BcEdnLIYhqBR7BGVy9kCNYZGtI1g3bX\ + 9xltWwpcDVyDNSv26FpwKHkasGpO1wJvY61KAsR/87NmwYh42IVQEGjE33V4VdBb8LMuXwkB\ + XzGjvTeRhtlgor2INenDO0TXFOphsCQ/KxeNsmO/Qb32HVxmRPeGAxR2N2KiEfQWHG0iDnoK\ + MEfBamTecIB8vYX8YCu+cPc1jYWV1R15vcPWRX7nEzHs/QGiTa5H51bVMMkNdZAb6oDOOkxN\ + Q/fk01Iw/m/dvuJC4GwET5/qFLl6O/l6K/nBVjxGn259+8vb9/ONE6YMl2tHGXYBRFmLNays\ + 32ugmaaZE+q8N0fvWKF78jBcXoBjseYhmBP9zWZkiCKQp7d6CwIt7ny9FVckPFCYDcDuVPoy\ + iGTYF460zStUhbXe7rlYwjyEtQDjI1iraeE5ZV5sRtJOGTAdOBlrUcdKLKEcE90esJtamhhY\ + Q7W+whoR/TnWgpLVE+q3P0DfdYbt1ACXAgcyGeWT9ZnAWGJmvvJgrZrVpztOogeWQBR2CrFm\ + Li23/fxYg1iLgILods/07G1YS7nVY+XUD0d/DVjtG/0enL+zDn9nnQ9rlbQbsWZK6wS2Yi0f\ + /zTRXP6oFECm2CaaApwbBftFg5gOlZMr+vbUjfU/Hk6O7s2UESUAxdAzugvcikFRApAcJQDJ\ + UQKQHCUAyVECkBwlAMlRApAcJQDJUQKQHCUAyVECkBwlAMlRApAcJQDJUQKQHCUAyVECkBwl\ + AMlRApAcJQDJUQKQHCUAyVECkBwlAMlRApAcJQDJUQKQHCUAyVECkJz/A7w3h5w1bl6AAAAA\ + AElFTkSuQmCC\ + " + local background_png = + "iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAgAElEQVR4nO3deZRedZ3n8Xcq\ + SUWTkAUTILIJRCVsArIoqCjdILYGHRZbARc4Mwg2gij0dGPPabFHPEdEFBdUZhoPAq2yqKgj\ + ArIptiACCgFUaCUCgYQlO4ZQqfnjW0UqSS3Pcu/93eX9Ouc5Wary3E/Q3O/3+f7u/d1x/f39\ + SCqt8cDsIa9ZwObATGA6MAPYDHjpwI8vGfLzCQPfN9Tg14d6DvjrRr/3LPACsGLI1wd/vgJY\ + Ciwb+L5ngKeAJUNefR3/jSUVYpwNgJTMDGC7gde2wDYDP24NbMH6ot+TKmCH+oHFRCOwGHgM\ + +Avw6MCPCwd+fDZVQEk2AFKexhFFfe6Q144DP+5EfEpvshXAw0NeDw15PUo0EpJyYgMgda8H\ + eAWwC7ArMA/YDdgZmJIuVqWtAh4E7gMeABYA9wN/BtaliyXVhw2A1J5eorjvBewN7AnsAUxN\ + GapBVgK/A+4B7gbuIpqE51OGkqrIBkAaWQ/xKf51wP7AfsQn/IkpQ2kTa4npwO0Dr18R0wMn\ + BdIobACk9aYCBwBvIIr+fsSV9qqeZcAdREPwC+A2YnogaYANgJpsBvBG4E0Dr72JW+dUPy8Q\ + ywW3Drx+TtzKKDWWDYCapJf4dP+3wCFEwa/aLXbKxjqiIbgeuIGYEKxJmkgqmA2A6m5n4G1E\ + wT8ImJw2jkpqNXAL0RBcS9x5INWaDYDqppco9G8H3kHcby+162Hgx8CPiMbAuwxUOzYAqoOZ\ + wOHAfOBQ3GBH2VoJ/BT4IXAN7mComrABUFXNAt4FHAH8DfHJX8rbWuAm4Arg+8QzEKRKsgFQ\ + lbwMeDdwFDHmH582jhquj1geuBL4LvB02jhSe2wAVHZTgHcCxxDjfTfhURmtBa4DLieWCdxz\ + QKVnA6AyGg+8FTiWKP7up68qWQX8ALiMuHbARyOrlGwAVCY7AR8ETgBenjaKlInHgYsHXg8n\ + ziJtwAZAqU0BjgaOJ3blG5c2jpSLfmL3wYuJCwhXpY0j2QAonV2Ak4D34377apZlwCXA14iH\ + GElJ2ACoSJOI2/ZOIvbel5ruVqIRuBq3IlbBbABUhK2ADwMnAlsmziKV0ZPAN4CvAk8kzqKG\ + sAFQnvYGTgP+nvj0L2l0a4DvAF8kHlYk5cYGQFnrIbbkPZ3YrEdSZ24Bzie2IF6XOItqyAZA\ + Wekl7ts/E5iXOItUJw8A5xL7CvhQImXGBkDd2gz4H8Qn/m0SZ5Hq7FFiInARsCJxFtWADYA6\ + NR34KHAqsHniLFKTPANcQFwnsDRxFlWYDYDaNZO4sO80YEbiLFKTLSWagC/iI4rVARsAtWom\ + MeY/FTfukcpkGTER+AIxHZBaYgOgsUwlRv0fx0/8UpktBc4jGgGfRqgx2QBoJL3Ejn1n4eY9\ + UpUsBj5N7DDoXQMakQ2ANtYDvA84G9g+cRZJnXsE+CTx3AH3EdAmbAA01GHAZ4A9UweRlJl7\ + gX8Erk0dROViAyCIJ/OdRzQAkurpWuJaHp9AKCDGvWquOcBXgN9i8Zfq7jDi3/rXiX/7ajgn\ + AM00gbid73/hlf1SEy0D/o3YQ+CFxFmUiA1A8xwMfIkY+0tqtvuJDwM/Sx1ExXMJoDm2A64g\ + /qFb/CVBnAtuAK4kzhFqEBuA+psAfIx4othRibNIKqcjiXPEx4lzhhrAJYB6ew3wf4B9UgeR\ + VBl3Ek/4vCd1EOXLCUA9vRQ4h/iHbPGX1I59gF8Te4K8NHEW5cgJQP28mbjN51WJc0iqvj8A\ + HwJuTpxDOXACUB8zgIuAG7H4S8rGq4hzykV4y3DtOAGohyOIW/tenjqIpNpaBJwCXJ06iLJh\ + A1Btgzv5/bfUQSQ1xveBDxMNgSrMBqC6jgIuBGalDiKpcZ4CTib2D1BFeQ1A9UwnHu95BRZ/\ + SWnMIs5BlxDnJFWQE4BqeQtwMbB96iCSNGAh8EHgpsQ51CYnANUwEfgssWWnxV9SmWxHnJs+\ + S5yrVBFOAMpvJ+A/gH1TB5GkMfwaeC/wcOogGpsTgHI7BrgLi7+katiXOGcdkzqIxmYDUE5T\ + gW8ClwHT0kaRpLZMI85d3yTOZSoplwDKZx6x0cbOqYNIUpceJJ40eH/qINqUE4ByORa4A4u/\ + pHrYGbidOLepZGwAymESsaPfpTgyk1QvU4lz21eIc51KwiWA9LYndtPysb2S6u5OYhfTR1IH\ + kROA1A4ibpux+Etqgn2Ic95BqYPIBiClU4Drgdmpg0hSgWYT576PpA7SdC4BFG8S8RCf41MH\ + kaTELiYeKrQmdZAmsgEo1lbA94DXpQ4iSSXxK+KR5k+kDtI0NgDF2QX4EbBD6iCSVDJ/AuYD\ + C1IHaRKvASjGW4BfYPGXpOHsAPwcODh1kCaxAcjfB4BrgZmpg0hSic0EfkKcM1UAG4D8jAM+\ + SVzk0ps2iiRVQi9xzvwkcQ5VjrwGIB+9wEXA+1MHkaSK+hbw34HnUwepKxuA7M0EriLW/SVJ\ + nbsZOAJ4NnGOWrIByNYOwI+JJ/pJkrr3APB24k4BZchrALLzWuA/sfhLUpbmEedWt0zPmA1A\ + Nt4M3AhsmTiHJNXRlsDPiHOtMmID0L35wP8DpqUOIkk1No24TXB+6iB1YQPQnWOBq4GXpg4i\ + SQ3wEuKce1zqIHVgA9C5fyBuU5mQOogkNcgE4BLiHKwu2AB05uPAl3GjCklKYRxxDj4jdZAq\ + swFo3z8Dn0sdQpLEucQ5WR2wAWjPvwLnpA4hSXrROcDZqUNUkRsBte4c7DQlqaw+A5yVOkSV\ + OAFozaex+EtSmf0zca5Wi2wAxvav2FVKUhWcRTxJUC1wCWB0Z2FHKUlV8wm8XmtMNgAj+xhw\ + XuoQkqSOnIHn8FHZAAzvH4h7TCVJ1XUK8JXUIcrKBmBTxxI7/LnJjyRVWz/wPuCy1EHKyAZg\ + Q4cDV+H2vpJUFy8ARwLXpA5SNjYA6x0M/BCYnDqIJClTq4mnCN6YOkiZ2ACEfYHrgempg0iS\ + crEMOBS4I3WQsrABgLnAL4HZqYNIknK1BDgAeCh1kDJo+kZAs4GfYPGXpCbwnD9EkxuAycSa\ + /9zUQSRJhZmL13sBzW0AxgP/AeyfOogkqXD7EzVgfOogKTW1AfgSccufJKmZDidqQWM1sQE4\ + HTg5dQhJUnInE9u+N1LT7gI4HLiaho99JEkv6gOOoIEbBTWpAdgduA3YLHUQSVKprCRuD7w3\ + dZAiNaUB2Ar4NbBN6iCSpFJ6FNgPWJQ6SFGacA1AL/A9LP6SpJFtQ9SK3tRBitKEBuBC4HWp\ + Q0iSSm9/omY0Qt0bgI8AJ6QOIUmqjBOI2lF7db4G4CDgOho0zpEkZeJ54sFBt6QOkqe6NgDb\ + Ar/B/Z4lSZ1ZAuwDLEwdJC91XALoBa7C4i9J6txs4EpqPEWuYwNwPrBv6hCSpMrbl6gptVS3\ + JYD3ApenDiFJqpVjiIcH1UqdGoB5wB3A1NRBJEm1soqYBjyQOkiW6rIEMIVY97f4S5KyVssa\ + U5cG4MvEBECSpDzMo2aPD67DEsAxwGWpQ0iSGuE4alJzqt4A7ATcBUxLHUSS1AjLgb2Bh1MH\ + 6VaVlwB6iasyLf6SpKJMA75NDfYHqHID8L/xfn9JUvH2IWpQpVV1CeAtwA1Uu4GRJFVXP/A3\ + wE2pg3Sqig3ADOC3wHapg0iSGm0h8BpgaeognajiJ+gLsPhLktLbjqhJlVS1CcBRwBWpQ0iS\ + NMTRxIODKqVKDcAc4F7gZamDSJI0xNPA7sCi1EHaUaUlgK9j8Zcklc/LiBpVKVVpAN4DzE8d\ + QpKkEcwndqatjCosAWwBLABmpQ4iSdIongJ2BRanDtKKKkwAvoLFX5JUfrOImlUJZW8Ajhp4\ + SZJUBZWpW2VeApgB3E9c/S9JUlUsAnah5BsElXkCcA4Wf0lS9cwBPpM6xFjKOgF4PfALyt2g\ + SJI0knXAG4Ffpg4ykjI2ABOBO4E9UgeRJKkLvyOeHLg2dZDhlPET9ulY/CVJ1bcH8LHUIUZS\ + tgnAdsADwOTUQSRJysBqYB7x5MBSKdsE4HNY/CVJ9TGZqG2lU6YJwFuAG1OHkCQpB4cAN6QO\ + MVRZGoCJwD3EfZOSJNXNg8Q1AaW5ILAsSwCnYvGXJNXXzkStK40yTAC2BP4ATEsdRJKkHC0H\ + Xg08kToIlGMCcDYWf0lS/U0jal4ppJ4A7Eqs/U9IGUKSpIL0AXsC96UOknoC8Dks/pKk5hgP\ + nJs6BKRtAA4BDkt4fEmSUjgMeGvqEKmWAMYDdwO7pzi4JEmJ3UcsBfSlCpBqAvA+LP6SpOba\ + jaiFyaSYAEwCfg9sX/SBJUkqkUeI2wLXpDh4ignAiVj8JUnaHjgp1cGLngBMAR4mNv+RJKnp\ + FgNzgRVFH7joCcBHsfhLkjRoC+C0FAcucgIwE/gTML2oA0qSVAHLgB2AZ4s8aJETgNOx+EuS\ + tLHpwMeKPmhRE4AZwJ+xAZAkaTiFTwGKmgB8FIu/JEkjmU7UysIUMQGYQaz9z8j7QJIkVdgy\ + 4BXA0iIOVsQE4DQs/pIkjWU6cb1cIfKeAEwFFhJ3AEiSpNEtBbYFVuZ9oLwnACdi8ZckqVUz\ + gA8VcaA8JwC9xK5/2+R1AEmSaugxYEfg+TwPkucE4Fgs/pIktWtr4Li8D5LXBKCHeNbxvDze\ + XJKkmnsQ2BVYl9cB8poAzMfiL0lSp3Ymamlu8moACt3MQJKkGsq1luaxBLAXcFfWbypJUgPt\ + DdydxxvnMQHw078kSdnIraZmPQGYQzz0pzfLN5UkqaGeJ7YHXpT1G2c9AfgwFn9JkrLSS9TW\ + zGU5AegFHgVmZ/WGkiSJJcS+OpluDJTlBOBILP6SJGVtNlFjM5VlA3BShu8lSZLWOznrN8xq\ + CWAXYEEWbyRJkoa1GxnW2qwmAJl3JpIkaQOZTtqzmABMIS7+m9F9HEmSNIKlwLbAyizeLIsJ\ + wNFY/CVJytsMouZmIosG4PgM3kOSJI3thKzeqNslgFcCvwfGZRNHkiSNoh94NfDHbt+o2wnA\ + B7H4S5JUlHFE7e3+jbqYAPQAjxC7E0mSpGI8BmwP9HXzJt1MAA7B4i9JUtG2Bg7t9k26aQDe\ + 3+3BJUlSR47r9g06XQKYAjw58KMkSSrWKmDLgR870ukE4J1Y/CVJSmUKUYs71mkDcEw3B5Uk\ + SV3rqhZ3sgQwC3gcmNjNgSVJUlfWAi8HnurkD3cyATgai78kSalNpIutgTtpAI7q9GCSJClT\ + HdfkdpcAZgOLgPGdHlCSJGWmD5gDLGn3D7Y7ATgci78kSWUxng7vBmi3AXD8L0lSuRzZyR9q\ + ZwlgBrH5T28nB5IkSblYC2wBLG3nD7UzAZiPxV+SpLKZSCzRt6XdBkCSJJVP2zW61SWAScT4\ + f3q7B5AkSblbSWzUt6bVP9DqBOAgLP6SJJXVVKJWt6zVBuDt7WeRJEkFaqtWt7oE8BCwU0dx\ + JElSER4G5rb6za1MAHbG4i9JUtntBOza6je30gC8rfMskiSpQG9t9RtbaQAO6SKIJEkqTss1\ + e6xrACYBTwNTuk0kSZJy9xwwkxZuBxxrAvB6LP6SJFXFS4EDW/nGsRqAQ7vPIkmSCtTSMsBY\ + DYDr/5IkVUtLtXu0awBmEOv/7T4yWJIkpbOO2Bb42dG+abTifuAYX5ckSeXTA7yhlW8aSVt7\ + CkuSpNJ401jfMFoDMOYfliRJpTRmDR/pGoCpxNrBhKwTSZKk3L0AbA6sGOkbRpoAHIjFX5Kk\ + qpoAHDDaN4zUAIz6hyRJUul11AC8PocgkiSpOKPW8uGuAegBngGm55VIkiTlbhlxHcC64b44\ + 3ARgHhZ/SZKqbjpR04c1XAOwX35ZJElSgV430heGawD2zzGIJEkqzr4jfcEJgCRJ9TXih/qN\ + LwKcRGwaMDHvRJIkKXdrgc2ANRt/YeMJwK5Y/CVJqouJwG7DfWHjBmCv/LNIkqQCDVvbbQAk\ + Sao3GwBJkhpo7+F+c+hFgD3AcmBKUYkkSVLuVgHT2GhHwKETgB2x+EuSVDdTgB02/s2hDcCu\ + xWWRJEkF2mXj3xjaAAx7m4AkSaq8TT7kD20ANukOJElSLYzaAIz4xCBJklRpm3zIH7wLoIfY\ + Anhy0YkkSVLuVhNbAr94J8DgBGBrLP6SJNXVZGDbob8x2ADsVHwWSZJUoA1q/WAD8KoEQSRJ\ + UnHmDv3FYAOwY4IgkiSpOMM2AHOH+UZJklQfNgCSJDXQBtcADN4GuJy4PUCSJNXTKmDq4C96\ + gJlY/CVJqrspwOaDv+hho/sCJUlSbb1Y820AJElqDhsASZIaaLvBn/QM/YUkSaq1bQZ/0jP0\ + F5IkqdY2mADMSRhEkiQVZ6vBn/QAWyQMIkmSirPl4E96GNINSJKkWnvxQ/+4/v7+PtZvCSxJ\ + kuprHdAL9PVg8ZckqSl6gFmDP5EkSc0xB2wAJElqGicAkiQ10AywAZAkqWlsACRJaiAbAEmS\ + GsgGQJKkBrIBkCSpgWwAJElqoGlgAyBJUtNMAhsASZKaZjLYAEiS1DRTwQZAkqSmcQlAkqQG\ + mgI2AJIkNY0NgCRJDTQBbAAkSWokGwBJkhrIBkCSpGbpBRjX39/fnzqJJEkq1DgnAJIkNZAN\ + gCRJDWQDIElSA9kASJLULM+BDYAkSU3zPNgASJLUSDYAkiQ1kA2AJEnN8gLYAEiS1DSrwAZA\ + kqSmsQGQJKmB1oANgCRJTbMSbAAkSWqa1WADIElS07gEIElSAy0HGwBJkppmKdgASJLUNDYA\ + kiQ1kA2AJEkNZAMgSVID2QBIktRANgCSJDXQU2ADIElS0zwBMK6/v78PGwFJkppgHdAL9PUw\ + MAqQJEm19xTQB/HJ/8m0WSRJUkEWD/7EBkCSpOZ4seb3AIsSBpEkScV5YvAnPcCjCYNIkqTi\ + LBz8Sc/QX0iSpFp78UO/EwBJkprDCYAkSQ20wQTgLwmDSJKk4rz4oX9cf38/wHJgs2RxJElS\ + 3lYBUwd/MbgF8J+TRJEkSUV5eOgvBhuA/0oQRJIkFWfYBuDhYb5RkiTVx0NDf2EDIElSMwzb\ + APwxQRBJklScYRuAPyQIIkmSirPBtH/wNsAeYAUwOUUiSZKUq9XE7f7rBn9jcAKwDvh9ikSS\ + JCl3DzKk+MP6BgDggWKzSJKkgty/8W/0jPZFSZJUCws2/o2e0b4oSZJqYdQJwH0FBpEkScXZ\ + 5EP+4F0AEM3AcmBKkYkkSVKuNrkDADacAKwDfltkIkmSlLvfsVHxhw0bAIC7i8kiSZIKctdw\ + v2kDIElSvQ1b220AJEmqt3uG+82hFwECTCK2BJ5YRCJJkpSrtcQFgGs2/sLGE4A1eDugJEl1\ + sYBhij9s2gAA3JFvFkmSVJBfj/QFGwBJkurr9pG+MFwDMOI3S5KkSvnVSF/Y+CJAiKbgGWB6\ + nokkSVKulgGbM8wmQDD8BGAdLgNIklR1dzBC8YfhGwAYZWQgSZIqYdRaPlIDcFsOQSRJUnFG\ + reXDXQMAsWnAM8CEPBJJkqRc9QEzic39hjXSBGAFIzw8QJIkld5djFL8YeQGAODWbLNIkqSC\ + 3DLWN4zWAIz5hyVJUimN+SF+pGsAAGYATzN6kyBJksplHTALeHa0bxqtuC/F6wAkSaqauxmj\ + +MPYn+6vzyaLJEkqyA2tfJMNgCRJ9dJS7R7tGgCAScR+AJOzSCRJknL1HHH//5qxvnGsCcAa\ + vBtAkqSquIUWij+0doW/ywCSJFVDyzW7lQbgJ10EkSRJxWm5ARjrGoBBDwE7dRxHkiTl7WFg\ + bqvf3OomPz/uLIskSSpIW7XaBkCSpHpoq1a3ugQwCXgKmNpJIkmSlKuVxPa/Ld0BAK1PANbg\ + xYCSJJXVdbRR/KG9B/38qL0skiSpID9o9w+0ugQA8XTAxcDEdg8iSZJysxbYkhYeADRUOxOA\ + pcDP2nlzSZKUuxtps/hDew0AwFXtHkCSJOWqo9rczhIAwGxgETC+k4NJkqRM9QFzgCXt/sF2\ + JwBL8OFAkiSVxa10UPyh/QYA4MpODiRJkjJ3Rad/sN0lAIiNBh7HuwEkSUppLfByYqO+tnUy\ + AXiK2HBAkiSlcx0dFn/orAEAuLzTA0qSpEx0VYs7WQIAmAI8OfCjJEkq1ipi859Vnb5BpxOA\ + VXSw7aAkScrED+ii+EPnDQDApd0cWJIkdazrGtzpEgBE8/AIsE23ISRJUsseA7YnNgHqWDcT\ + gHXAJd0cXJIkte1bdFn8obsJAMArgd8D47oNIkmSxtQPvBr4Y7dv1M0EgIEAt3UbQpIkteQ2\ + Mij+0H0DAHBxBu8hSZLG9s2s3qjbJQCAqcCjwPTu40iSpBEsIy68X5nFm2UxAVhJXJAgSZLy\ + cykZFX/IZgIAsCtwXxZvJEmShrUbsCCrN8tiAgAR6OcZvZckSdrQz8mw+EN2DQDAhRm+lyRJ\ + Wu9rWb9hVksAAL3ExYCzs3pDSZLEEuLiv+ezfNMsJwDPA1/P8P0kSVLU1kyLP2Q7AQCYA/yZ\ + mAZIkqTuPA+8AliU9RtnOQGACPjtjN9TkqSm+jY5FH/IfgIAsBdwV9ZvKklSA+0N3J3HG2c9\ + AYAIenMO7ytJUpPcTE7FH/JpAAC+kNP7SpLUFF/M883zWAKAaCwWADvn8eaSJNXc74FdgHV5\ + HSCvCcA64Nyc3luSpLo7lxyLP+Q3AYC4FfC/gK3zOoAkSTX0OLADOdz7P1ReEwCI4Ofn+P6S\ + JNXR+eRc/CHfCQDAVGAhMDPPg0iSVBNLgW3J8LG/I8lzAgDxF8j1KkZJkmrkAgoo/pD/BABg\ + BvCngR8lSdLwlhFr/88WcbC8JwAQ44wLCjiOJElVdgEFFX8oZgIAcQ3An4DpRRxMkqSKWU48\ + 9KewBqCICQDEX+hLBR1LkqSqKfTTPxQ3AQDYnJgCTCvqgJIkVcByYu3/mSIPWtQEAOIvdl6B\ + x5MkqQrOo+DiD8VOAAA2Ax4CtijyoJIkldRiYC6wougDFzkBgPgLnlPwMSVJKqtzSFD8ofgJ\ + AMAk4ilH2xd9YEmSSuQR4NXAmhQHL3oCAPEX/WSC40qSVCafJFHxhzQTAIDxwN3A7ikOLklS\ + YvcBewJ9qQKkmABA/IXPSHRsSZJSO5OExR/SNQAA1wHXJjy+JEkp/JQS1L9USwCDdgV+SywJ\ + SJJUd33AXsC9qYOknAAALAD+b+IMkiQV5d8pQfGH9BMAgC2BP+AWwZKkeltO3Pb3ROogkH4C\ + APAk8KnUISRJytmnKEnxh3JMAAAmAr8Ddk4dRJKkHDwI7AGsTR1kUBkmABD/QU5NHUKSpJyc\ + RomKP5SnAQC4HrgidQhJkjJ2NXHre6mUZQlg0HbAA8Dk1EEkScrAamAesDB1kI2VaQIA8R/I\ + CwIlSXXxb5Sw+EP5JgAQFwT+Bp8TIEmqtnuB11Kytf9BZZsAQPyHOglYlzqIJEkd6idqWSmL\ + P5SzAQD4JXBR6hCSJHXoG0QtK60yLgEMmkFcELhV6iCSJLXhSWJfm6Wpg4ymrBMAiP9wH0kd\ + QpKkNp1CyYs/lLsBALhy4CVJUhVUpm6VeQlg0BbEUwNnpQ4iSdIoniHu+V+cOkgryj4BgPgP\ + eXrqEJIkjeE0KlL8oRoTgEHXAPNTh5AkaRg/BA5PHaIdVWoA5gD3AZunDiJJ0hDPALsBi1IH\ + aUcVlgAGLSI2VZAkqUxOomLFH6rVAEA8LfBbqUNIkjTgUir6JNsqLQEMmgH8lnhyoCRJqfwF\ + 2IMK3PM/nKpNACD+Q3+Q2GdZkqQU+olaVMniD9VsAABuAs5LHUKS1FifB25MHaIbVVwCGNQL\ + 3AbskzqIJKlR7gQOBJ5PHaQbVW4AAOYCdwGbpQ4iSWqEFcDewEOpg3SrqksAgx4CTk4dQpLU\ + GCdTg+IP1W8AAC4DLkkdQpJUe98iak4tVH0JYNBU4A7iIQySJGXtQWBfYGXqIFmpwwQA4n+Q\ + o4BVqYNIkmpnFXAkNSr+UJ8GAOB+4MTUISRJtfMhosbUSp0aAIDLga+mDiFJqo0LqdG6/1B1\ + uQZgKPcHkCRloRb3+4+kjg0AxHMC7gRmpw4iSaqkJcQHyYWpg+SlbksAgxYCRwNrUweRJFXO\ + WuDd1Lj4Q30bAIBbgI+nDiFJqpwzgJtTh8hbXZcAhvp34PjUISRJlXAxcELqEEVoQgPQC9wK\ + 7J86iCSp1G4H3kRNL/rbWBMaAIA5xE6B26QOIkkqpUeJD4qPpw5SlDpfAzDUIuDvqNkuTpKk\ + TKwiakRjij80pwEAuBc4FuhLHUSSVBp9wDFEjWiUJjUAANcA/zN1CElSafwTURsapynXAGzs\ + q8QznSVJzXUh8OHUIVJpagMwHrgaODx1EElSEtcAR9DgZeGmNgAAk4Eb8fZASWqa24GDgdWp\ + g6TU5AYA4lkBvwTmpg4iSSrEQ8ABxF7/jda0iwA3tgR4G/4fQZKawHP+EE1vACC6wXcAy1IH\ + kSTlZhkwnzjnCxuAQXcQF4M8lzqIJClzfyXO8benDlImNgDr3Qi8hwZfESpJNdQH/D1xjtcQ\ + NgAbugb4ANDoKyMlqSb6iXN6Izf6GYsNwKYuA05NHUKS1LVTiXO6hmEDMLwvA2emDiFJ6tiZ\ + xLlcI7ABGNnngE+kDiFJatu/EOdwjcIGYHTnAGenDiFJatnZwKdTh6iCpu8E2KpPA2elDiFJ\ + GtVn8FzdMicArfkE8X8sSVI5WfzbZAPQurNwOUCSyuhTWPzb5hJA+/6ZuDZAkpTeJ/Cc3BEb\ + gM6cCXw2dQhJarh/BM5NHaKqbAA6dwpwATAudRBJaph+YpMf7/Pvgg1Ad44DLgYmpA4iSQ3x\ + AnA8cGnqIFVnA9C9w4HvAC9JHUSSau6vxIN93Ns/AzYA2Xgz8X/IzRLnkKS6WkF84Lo5cY7a\ + sAHIzj7Aj4EtUgeRpJpZAvwdcGfqIHViA5CtucBPBn6UJHXvIeBtAz8qQ24ElK2HgAOAO1IH\ + kaQauAM4EIt/LmwAsrcEOBj4UeogklRhP8LM7JEAAAapSURBVCbOpYtTB6krG4B8rALeBVyU\ + OogkVdBFwDuJc6lyYgOQnz7gROCMgZ9LkkbXR+y0eiKeN3PnRYDFmA9cDkxNHUSSSmolcAzw\ + w9RBmsIGoDh7Ev/H3iZ1EEkqmUeJD0r3pA7SJC4BFOceYF/g9tRBJKlEbgf2w+JfOBuAYj1B\ + 7Bp4ceIcklQG3yTOiYvSxmgmG4Di/RU4gXiS1QuJs0hSCi8Q58DjiXOiEvAagLTeDHwXmJ04\ + hyQVZQnxQJ+bUgdpOhuA9LYHriSeJSBJdXYncBTwSOogcgmgDB4B3gB8LXUQScrR14lzncW/\ + JJwAlMuxRCPgfgGS6mIlcBJwWeog2pANQPnsSiwJ7Jw6iCR16UHgaOC+1EG0KZcAymcBsV/A\ + JamDSFIXLiHOZRb/krIBKKeVwAeA9wHLE2eRpHasAN5PnMNWJs6iUbgEUH6vJJ4j4F0Cksru\ + TmI//z+mDqKxOQEovz8CBwLnAXZrksqonzhHHYjFvzKcAFTLwcTWmdsmziFJg/5C7Oj3s9RB\ + 1B4nANVyI7A7cGnqIJJE3Nq3Bxb/SnICUF1HAxcCL0sdRFLjPEPc239F6iDqnA1Atc0hdtea\ + nzqIpMb4IfAhfIJf5bkEUG2LgMOJHQSfTpxFUr09TZxrDsfiXwtOAOpjC+DLxNKAJGXpSuAU\ + 4MnUQZQdJwD1sRh4N/GkrScSZ5FUD08Q55SjsfjXjg1A/VwFzCMeKrQucRZJ1bSOuL5oHnFO\ + UQ25BFBvryf+Ee+eOoikyrgXOBm4LXUQ5csJQL39J7A38E/A6sRZJJXbc8S54rVY/BvBCUBz\ + bAecDxyROoik0vke8FFgYeogKo4NQPP8LfBFYJfUQSQldz9R+K9PHUTFcwmgeW4AXgOcASxL\ + nEVSGsuJc8BeWPwbywlAs80BziYe5DEhcRZJ+XsBuAT4F9zMp/FsAASxHHAecFjqIJJycy3w\ + cWLsL7kEICBOCG8beN2XOIukbA39923x14tsADTUtcT1Acfj1cBS1S0k/i2/hvi3LW3AJQCN\ + pJd43OcniOcMSKqGJcCniceFP584i0rMBkBjmQqcTqwdTk+cRdLIlhHX8pwPrEycRRVgA6BW\ + bU7cL3waMC1xFknrrQAuAD4PPJM4iyrEBkDtmsn6RsCJgJTOcuIR4J8Hnk6cRRVkA6BOzSCa\ + gNOIpkBSMZ4FvkTs6OknfnXMBkDd2gw4kbhOYOvEWaQ6e4xY3/8GMfaXumIDoKz0AscBZwI7\ + J84i1cmDwLnApXhVvzJkA6Cs9QDvJK4TeFPiLFKV3Qp8AfgBsC5xFtWQDYDytDdxjcB7iAmB\ + pNE9D3yHKPx3Jc6imrMBUBG2Aj5MXCuwZeIsUhk9SaztfxV4InEWNYQNgIo0CTiC2GHQ5QEJ\ + fk7s2Hc1sCZxFjWMDYBS2ZVoBN6H+wmoWZYB3wK+BixInEUNZgOg1KYARxMPLXkjMC5tHCkX\ + /cSn/YuBK3GrXpWADYDK5FXACcRU4OWJs0hZeJz4tP9N4nY+qTRsAFRG44G3EvsKvBOYnDaO\ + 1JbVxK17lwI/BfrSxpGGZwOgsptKNAHvBQ4FJqaNIw1rLXA9cDlR/B3xq/RsAFQls4B3D7ze\ + QEwKpFT6gF8A3x14PZU2jtQeGwBV1RbAu4AjgbfgZEDFWAvcBFwFfB9YnDaO1DkbANXBTODw\ + gdehxLKBlJWVwHXANQOvZ9PGkbJhA6C66QXeDLwDeDuwY9I0qqo/AT8aeN2Cm/SohmwAVHe7\ + AIcBhxC7D3pHgYazmrhP/zrgWuD+tHGk/NkAqEleAhxANAOHAnsSTy9U86wD7iEK/vXAL4G/\ + Jk0kFcwGQE02k7ib4CBiOrAXMCFpIuXlBeBu4lP+zcTV+67lq9FsAKT1NiMmBG8E9gf2xecU\ + VNVy4A7gdqLY3wasSJpIKhkbAGlkPcA8ohl4HbAfcU2BtxyWywvEQ3XuAH418OP9xJhf0ghs\ + AKT2vATYjVgu2BPYG9gDLy4symrgXuA3xBr+3cB9uH4vtc0GQOreeGAHYjqwC/Go43kDLxuD\ + zqwGHhh4LSA+0d9P3J7n3vpSBmwApPz0ANsCcwdeOw75+U7Eo5CbbDXw0MDr4YHX4K//giN8\ + KVc2AFI6s4BtiCZhu4GfbwNsTWx1PHvgNS5VwA71A0sGXouBx4BHB14LieL+KO6dLyVlAyCV\ + 23g2bAY2B2YM85oy8JoMTAKmERcrbnwXwzQ2fYhSH3HV/FDLiH3vlxO74K0GVg28lg7zeob1\ + RX8JcWGepBL7/+6JvSCr2fnsAAAAAElFTkSuQmCC\ + " + local bubble_png = + "iVBORw0KGgoAAAANSUhEUgAAAQAAAACACAYAAADktbcKAAAHH0lEQVR4nO3dy89ccxzH8ffz\ + 9F6XXrR9tK6lLXVpVCQkLhGhIWiIRF0SG4S9hJUVGxaWNhb+AItKBGFh04UgIihBVJuWtmir\ + V8VDx+J3Js90OvN0fmfm9Fx+71cyeWaezuXbNt/P73d+58w5Y61WC0lpGi+7AEnlMQCkhM0s\ + uwDVy6pLV0Y9/8cd2wuqRKNgACQqtpG7jAELgGXAcmACWJI9ngCOAS8Bh4arUkUbcxGw3oZs\ + 5HHgLGAhoXGXAYuz23kd9xf1uH+6zce3gQfBWUCVOQOogCGbGGAWoZHPJTTu+cBFhGZtN+yi\ + rsfnAecM+8HTeABYD3xR4GdoSAbACI1gNJ4NzAPOJjTpBHAhsJLQsN1N3L5f1cXcRzAAKs1N\ + gB6GbOQZhBF5LmFUXgAsBVYAlwKrCVPt7iaePcyHVtTnwA3gZkBVNXoGMIIReSahMecTpteL\ + CKPyJcDlwFXABUw18fxhPrCB1hP+HU+UXYh6q00ADNHMY4RReSYwh9CkCwlT6uWEZr4CuIYw\ + 1V5MGME1vHHCv/fRsgtRb6UEwIiauT3FXkiYYi8njMpXEkaeK7LnqlyLMAAqa2QBkKOpxwgj\ + xCzCyNy9vbwSWANcB6yjugtdmt75wK6yi1BvAwfAgA3eXgCbT9jFtJipZl5NmGbfhNvKKbkI\ + +KzsItTbQAHQ0fyzCCvZa4C1hBXeVcDFhJFb6nZ52QWov5hNgHHge8JoLg3q6rILUH8x29Wr\ + sPkVb13ZBai/mABYXVgVajIDoMJiAmCisCrUZDNgJN93UAFiAsBFPuU1VnYB6i0mAJYUVoWa\ + zgCoKANAZ4JHZFZUTACY4srLAKgoD6/VmWAAVFRMAMwprAo1XW2+dZqamACYV1gVajq/Xl1R\ + bgLoTDAAKiomAPYXVoWazgCoqJgA2FlYFWq6Jp7vsBFiAmB3YVWo6SbLLkC9xQTAnsKqUNP9\ + XXYB6i0mALzMk/I6XnYB6i0mAP4orAo1nYNHRRkAKtpx8MIgVRUTAMcKq0JN5inBKywmAFzI\ + UR57yy5A/cUEgLtylIe7jyssJgD+K6wKNdnPZReg/mICwMsIKw+PH6mwgQKgYwXXhUDF2lZ2\ + Aeov9tuAXxRShZrMy4JVWGwAbCmkCjXRb8DrwDdlF6L+Ys/U8mUhVaiOWoQm3wns6Pj5HbCV\ + jt1/HgRUXbEB8EMhVagq/gL2Ab8Szv+wj9Dkv2f3dxMa+5fsd/9O92Y2fvXFBsCOIorQyLUI\ + h24f6PrZef83QlPvZ6rJoxd5bfJ6iw2Ag9ltYQG16GSHBrj9wamNfYDwf5SLDZ2W2ABoAe8B\ + jxVQS5Mc4dRmPdjjd/1uuRu4zUbWIMZarcGP78ku8Hgf8E5RBVXMFmAXoaHbt8OEBj3S49Zu\ + 4KEPmrKBdSbkOV/7u8AnwI0jriWvvwkNOQlcOML3fRl4Me+LbWDVQZ4AaAF3A08ANwCXAWcT\ + 1gXmEq4fcG7H848AJzoeTxIWm7p/Hs+ee5Qwyh7O7h/l5BG2/buDhG3ev7L3fR54Jcffp5fn\ + gNfARlazRW0CQKWv8/45cP2Q73ECeAp4E2x+NV90AFRNFkhrgO+HfKtJYBOwGWx+paEp12zb\ + NOTrjwEbgY/A5lc6aj0D6Ngc+RZYm/Nt9gP3EhY2bX4lpQkzgGvJ3/y/EBY0t4LNr/Q0IQAe\ + zfm6bcAG4Cew+ZWm2m4CdEz/txF2RcbYCtxF9o01m1+pqvvlwW8kvvk/Bm7B5pfqGQAdo//D\ + kS/9ELiT7Eo1Nr9SV8sAyIwDj0Q8/y3gfuBPsPklqHcA3AysGPC5bxAWC/8Bm19qq10AdEz/\ + B/1K8qvAM2TXNbD5pSl13Q04A3hogOe9QAgAwOaXutU1AO4Elk7z5yeAZwlTfxtf6qNWATDg\ + 6v8k8Dhh0c/ml6ZRqwDIzKH/9P848CDwAdj80unUMQA2AAt6/P4QcA/hQB+bXxpAbQLgNKv/\ + ewnB8DXY/NKg6rYbcB7hYJ5O24FbsfmlaHULgI3AWR2PtwK3AT+CzS/FqkUA9Fn9/xS4HfgZ\ + bH4pj1oEQGYB4cw9EE7ddQfhbD42v5RTnQJgI2EX4GbCav8xsPmlYVT+hCAd0//3gT3A03hc\ + vzQSdZkBLAa+Ap7E5pdGpi4zgDE6rrdn80ujUZcDgVpg40ujVvkZgKTi1GUNQFIBDAApYQaA\ + lDADQEqYASAlzACQEmYASAkzAKSEGQBSwgwAKWEGgJQwA0BKmAEgJcwAkBJmAEgJMwCkhBkA\ + UsIMAClhBoCUMANASpgBICXMAJASZgBICTMApIQZAFLCDAApYQaAlDADQEqYASAlzACQEmYA\ + SAkzAKSEGQBSwgwAKWEGgJQwA0BKmAEgJcwAkBJmAEgJMwCkhBkAUsIMAClhBoCUMANASpgB\ + ICXMAJASZgBICTMApIQZAFLCDAApYf8DcD99Gl27kUkAAAAASUVORK5CYII=\ + " + local inspector_png = + "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAgAElEQVR4nOy9ebwlV1Uv/l1V\ + Z7hD973dnR4ydyfdhBAyQBBMCCBDngJRGcWfT1QEUQH1Z+CJgk9BHjjA84GATIrTD5+oPPzJ\ + E0UhAWQMICRkAEJC5nnovt13PPdU7ffHrr1rrbVXndvEO/Tz1urP7VOnag9rr+G71t61qw45\ + 59BSSy1tTso2moGWWmpp46gFgJZa2sTUAkBLLW1iagGgpZY2MbUA0FJLm5haAGippU1MLQC0\ + 1NImphYAWmppE1MLAC21tImpBYCWWtrE1AJASy1tYmoBoKWWNjG1ANBSS5uYWgBoqaVNTC0A\ + tNTSJqYWAFpqaRNTCwAttbSJqQWAllraxNQCQEstbWJqAaClljYxtQDQUkubmFoAaKmlTUwt\ + ALTU0iamFgBaamkTUwsALbW0iakFgJZa2sTUAkBLLW1iagGgpZY2MbUA0FJLm5haAGippU1M\ + LQC01NImphYAWmppE1MLAC21tImpBYCWWtrE1AJASy1tYmoBoKWWNjG1ANBSS5uYWgBoqaVN\ + TC0AtNTSJqYWAFpqaRNTCwAttbSJqQWAllraxNQCQEstbWJqAaClljYxtQDQUkubmFoAaKml\ + TUwtALTU0iamFgBaamkTU2ejGWippf8otH/fvnhMIADADTfftEHcHB21GUBLLa0uPYtA1wOY\ + 3mhGjoZaAGippVUgFv1/yjn3MACXOjgc2HfaxjF1FNQCQEstrR51AVwMAhzcywjUc3AbzdNI\ + agGgpZZWgxxAoMfDYWs1/9/t4H5go9laiVoAaKmlVSLn3NOJqPoCEOgFcMD+vfs2lK9R1AJA\ + Sy39OynM/4nomc5VKb/HgR+GnxYcs9QCQEstrQYR9ju4cyvHBwA4uCkiumjjmFqZWgBoqaVV\ + IAL9iDjh4l6AZ8RpwTFILQC01NK/g0L67+B+BPBO7+BARKimAz/g4MQmoWOJWgBoqaV/P50D\ + 4Hw4IK4BAKgi/7kAdmwQXytSCwAttfQQKWzyIdAvEMg7PAHh1r9zDg6OADxpw5hcgVoAaKml\ + h0gODgTaB+CnnXMi+gMAyE8JCPR968/d0VELAC219BAoRH8H93bnnL/VF9b6/E7AcB0Angjg\ + mFwHaJ8GbKml74LUE3+vcnA/FNL+sABYXQPgAcDBPRr+4aCZdWd4BTomAODAvtOQ7Jm2tlBT\ + wzWqBQ4c+49gtvR/J7EHewjAqxzcW+AQ7bKaEsTyDAwyAE90cP+wjuweFR0TAFAJ7qcd3HkE\ + mnVwQyI67JwrQTgEhwKEIwRaBjDnyC3CYRHAPAgDAs0CGAKYcXBOp1oRjfkcjd+adbDPK+II\ + b7UPtODzH40MW3o4gLc6555BRHDk+DVvHy6e4PQEAMccAFCycLHOxKL/1QQ6O6Bo/HTVPVUm\ + WL6xIjqkQ10OmCHQ0MHNEmgAYB7AEoAF59wSCAvhO4AlAi0455aIaAHAwMHNEyj5rNppOl84\ + uCMjB9sENN+NCiyAOop2b7zl5u+ik81J0dlTeU4AeAaAnwTwQ/42v3J2IN77Z3bIpwKfhsOT\ + ieiYChIbngFUjj4O4BHc+QPFDRWExugs6nggmK6OjwsLMnyDRuy7ajdu3KgUyvvkQBT618DE\ + Aasa02EAjkBzAJYd3CKARSIaOudmq2KHKjZmQRjCYRGERQBDOMwSkXPOzVTTmyPOuQKEBQIt\ + ObiCQEeqMft6PhU9AqDwUsBMNTcdAJjfv2+fnQmNoqZs6GgyJquMcS7Jqo4yG0vKAnzzTXO/\ + mgi6z5yIHu6cOw+ERwH4XgI93sF1I69U206wp2qu74/DNWmXjyWi3MEVK4xqXWnDAQAAHNy5\ + AHLtWAIImPEGJVS3WERbYtslc+DQRjAQIhLKE/wwBYbvuqwFEuz6VFVvmoiiIXC+Q1kOLvE8\ + 1X0YsuJfar5IzT8Dz5K/eQDLFe8zFcgMAcxW50JmBCI6Ap/VlAAOR/mhyqDque8ygDk2Jl+e\ + av4c3AwAx2Q2C2DI9LLg4JYIFJ2LR1Heh4iswRGBjIimtF4q6hLRpHOuC8IkHMJnh4i2OLhp\ + ELbB4XgiOtk5d8CRG+My5rLlIMApyj6sBzhmvz54TTi4swFclSh1A+mYAAACPdrBScVVBkbw\ + 8yyRBfAV11DOSMm4MqJ+yHASdsyVzcFCt6OzBu7c0eGY8ymAkGNMjTaJIiLbMKJP5IkZIs+K\ + qtMTLMuZDmMLsud96PHGfhjPjRQcn5yoE9tzkndr4UzIxwBJrgPejuWcQR4CQHi67tI6/Lrm\ + 05yaWvUZWFXlL3DOHVMAcKzsA3hMo2KdEwaTOBYzxHAtRPf4j6jenVUZO0/lQhmePnLA4UYT\ + 2qjBnUQ6y8cQ2ksyDO5wipfAD2/PnBapNhMncixDIlnOdF51SmdZkZcRjh90lfBAJD65TCLf\ + YTjOHl+UG5MrP6eLJ+1C2lUYSzjHwYPLm7fPbUe3A4c4Xj6+aCde149rFN4G0YYCwP69+4Jg\ + H8UNQiO1nmsD8PWCMiCnDOE8NxatMO4cIlVzdTbA/1nTkdCXSSwq6NRV9KvAI/JJcl6ZGDI3\ + NIOFCC4uXVcR6anFd/h0UpZJO+xf4Jl/arCIZanuJ9EPrxL0weqI1N/VfCbzf0iwE9M55aQ6\ + 6+DP9POMioMYl2G0F/kykGTsAC4Ejq0NQcdCBtAl0Lnhi1CiQ2Jw8SufKrBPEWl4U8HQAlgw\ + 8Ij9MKfVkUYrlBucBhIdwQWfSNNJ1om4rq/pqKZePpH0AZbBaP7FGHnUZuPjRh3TcEsWqAFa\ + 36ExnYzxzOUo+GTOLkCTZWzg0yAG2hZp/iIQ6LFXMtPy10GGZ5XWtFJnlhX/Z4L8+tCxQhsO\ + AER0FoAeR1qNwPG7U9EbdpSpG4eMSgokQvmozBBl+HfWpgajmJ0w/rghiXo803DyGh8jj1DW\ + mERbARQ0KAZZaRAJxUjKz8qIrIzHWvE2+WP1rOyJ88Xn2aJty4+5TtKn7kbyJWTO++TOzuxD\ + Z5Aa3EW/Tuo5dsmymwpoiUDfY4xsw2jDAQDAY/SJBMlFIGUpqbE4x8vFKOJPJMqJBsoMQsw/\ + k6CVpt0RCIKTgJIshn8KwGFtRmfGCim6Ij0fjVGUObIwaOYEcSysTwt8BJAZ6a0AmpCWsz7E\ + OBvGl/TNnZGtk8TzVGdu+poYFwPkyAu7y6QjezImlXnp1D/yEsbIwVjZZNVvYu8bSRsKABUy\ + PtoyhqRspQxRLjyBRaxMQxTWaVroh6N2Ei0NULGiaowUIUXVC5BIMxft8LF9fntSpdz8u3Ao\ + 2OeDs+qsgmcPnB/dh+UUyTFzQnF3wtWO1sSrPhfLWmk5ahvgfYlx6zEZU5tQV2SRoU+dcWqe\ + +TwftU6tvQc8uAS9Vu085iixfV1owwDgwL7TQETI8lzcAQCQpGIQ8pVzL77wIqYK7B9XOl+w\ + Eako6yQ4rpU+x7IaNKiux9N5UQYqKhsLlKEMBzwuAyv6xsjEohN3lghMTHaxrwCiruZf886j\ + JI+eYdwWX6Fvkeob8oxgwR2SlPxZVsHHpgGfg5apO549MFnzdrm8mjIYbjMc+BOggbPG8RgA\ + x8wPhmwYAPTHxuCcyzqd/DH61kpy71UZk3U7CcT+UCtHK0XUqS+or7bymyK/dpLIO7vHbhLZ\ + Bsj7005hpatRZhZeMaPnBimcRdXlDib6apgSRSc06phpsso2eN9JNqhBkjm8uE+vozbbN2Da\ + jbrlqm2Mj5nrlstfgILO8Ji8RMZCOEBhp+oxQBsGALt37cT0tm1nDgaDnjYI7UjVgVQBQ2hS\ + /1DNB/n92agXShXKie870Dw0RReeeQASwEQ5HhFVW4njKGBgFxAzGaTpKueJZzLW7cAIrkZb\ + Gow08euWcwY+9QJdyGb0uo11Szc6uAYMzjsHMS4rgrAZIRslZ3EnxLgtGcdp6ErvMbH443qo\ + 2njM+MSEKdf1pg0DgOP37MHjL3jsC4KD8sighZ2gqjPSxHhZpZ0k20mimr8o22lwClHNMHAO\ + LqHP0F6oExyAp686kwh1NSDqLCn2yeelkIbLxySuQxpnzFga5r8BRMX0ximjHxXlwXRJdcQU\ + IKLlY0RlDWhajpFnJ+XCeY39EdMpCxChrJUthTFpnqLONOAY+Hzy3lOftH3H9vTCBtCGAcDk\ + 5ATK0j2Np7aBtDKj4TPH52mgFrpIDSsnSVJx5cy6H+FATrYDyOvCUNSUwBdN97CHehbp1DgY\ + eXLdSMmtzIHLin9vymQSgAy8skzKWqwMPFlZVXQO5xJHEdG+GreQnZ7KuVQXiaOSMU6nxhhA\ + gk8VHERg4XbD6ySAw65rGepsc8/u3Zds2bo1kfFG0IYBwAMPHsS9993/MCsVBlCn7ghfpbFw\ + lA71dESL7UBGa+6EXOGRB74wxQwk9sMWzTR/NftpRNfTCmsOyinJQFCPWY9PrN4z+Vgr1Lx/\ + kX2osfL2myjKMgyfp8TsrgDbDJOA1KjsL+HbAj/m2KIeG2vgI/Rv8RL6SqaXPNNs4DOZEozI\ + ag8fPnLm1MQ43vf7vzNCsutDGwIA+/ftw9axLr5z083HcaQVEdRK8VmaZt2CSdJ7lR5z5+NR\ + NTqDEQGtaAhAZBhJJHByGiLKOdkGT3Hj+FVGJMbO2hd3QXjKTaidUohPOpaIuNbeA51Gh7oq\ + ynFw5e0KHakpSBKxneJBpfXCAcMfZBCo2bZ3WorphaLYN8sKdJtNx9wGdSDgU5RA37nxxi1P\ + ffxjtw+Gw4SP9aYNexrwc1/+av63f/i7N/U6+cPmlgZwZXAeYHZxKZYbDkvMLy2hrK4vF0MM\ + hkV0ucHSMgZFCarOzC8soqyUWJYl5llby8tDLC7V35eWhxgMBtGA5ubnURYFnAOIgEMzswgg\ + PiyGOHz4cKy7uLCAubk5MaaYhai5dHR85pgmMLm6rrUIGR2GOzuYo6nswJpaJSDAHJSDVhIt\ + Q3vKmZtAQwAgyQzNkpkAODYOwZ+ecqhsRThww9hE9y4dkx6zmJqwejGrANWPb7OxCOBj34kI\ + w+VlzC0uPdc5935sMG0YALzn9ZcWjzptT887Bg9XKmwFb/Rf6mvRCIiVUdfjtXBJaT/YbqJg\ + HX1J9sfrV9dml5YxLFzsd3ZhCaVzIAJKB8wtDmJzy8MSS8vLkdvBsMDSch0N5haWUJRl/D67\ + 4N/34eDgSof5xSUQCCWA4XCIpcFyLLu0PMBwWEYnmV9YQumKyO7c/EJ1jVAUQywsLCIIYmmw\ + jIXFJS8uB8zNzWKwXPN98MGDcEVROwcHpgBa7BVZwhkUyIVjrnJrDUNHeP5dZAjGqj2rVKf7\ + UeeyTugv8BUeC7emmLwtveaQTAcUn2HMR+YWnlaW5eYEgBtvvhnltZ9Erf2Q9sn0qXZEFj61\ + I3KAUNghysXzzHEpWAYHEFUPqj/BJ8XPLX32I7BE2DbZZ0ywDICBRtIu502TADSS407kECJa\ + Q3khZ6OtOG7dfqyE4bDA7GINPMPSYX5pUHXlMBg6xBTXOcwPCxTDIrZ4ZKHOxArncGRuAVnF\ + w2BYYHFpCZRlcHBYWhxguXSgysFmFxarZn36PVd9JyIMyxIL8wtRtoPBAEuDIYIeFxeWMCyW\ + 45APH56NWi/LEodmDkW+lhaXMDc7m2Rg1nqAXggMACLqkotTkAdmZs7dd8IebDRt7AtBooMr\ + Jw3a0c6BcK4CDe5MxOqHlLLJSeKp2oFTPmS0SHhuAgTnmrMTnlhwEBDjU30xkLEd1SAuE34u\ + 6dsYr5AFB8j6KwB08gzbtozJ8W8dGy2XUaCUkOobQMKLGIsxzgQUmwEt7V6BJID5xWUMhvUb\ + vWaXBihLF5s9sjCI/RRliYUlluUVpcjUCDQ3XK5BcKNoYwFAO3w8b6TkOro5di005ipgiDbc\ + EGmbphV1AX+OpbONfASndfw6d66mcRnGmfCl+uVltIys8QnnESmIqk81P1amEasbcuKOqIkD\ + YgRBBs6iKe3oXAaBHyUfDXDOpXqx5ANWRvRPqaxZmYmxDiZQZ3oRAHn9ZEyGXPzYp++dmUuv\ + rTNt/NOAzjrh6gsmOKjvPErG68yo+XXteNoIIk/BuBsiBOdDOIeK9NHodcQ3IjLnSzuc5TDJ\ + d3VO1FefsR+dhWlggXIIsPGofpzSGyDlz8HS6kumcYbu6Oh41tkLXCr7ANhxPKxPp8vzes6W\ + NR8z17lFPgvdvnt60r6+jrQhAFBe9yl/4LArGlikYFhMuUmqHBwbxjWLHFPciExDnG8wetEs\ + zy7Y9cCXcOQRBtHIA+8Do9vQwFhfsHkMUVDIkH2OTM1Z00kxrS9IGerIHM4nqbziy0rzLd3H\ + a6xsbMYpnYmCaTu6jABp3T/YGBrshH93OCb2Am9cBkA0DaIJ02i1Y/P0kYODkHX4oowNgO0Y\ + RkjUEVdHhtiucS6eZuARwC3wIiIL45M7gJ4GiDn5UYAX5zlxIAW0nFcoeekoyykBbAN4zTHU\ + p+o+WVndLnc2rQdrGhTbV32GskEnktHmfvk53bbQrR5DQyCSALcFYMFwg2iDAMABwD4ZGVSU\ + tpQgUlGehmoHhB1RdHtNU4BQ34qq1hw9GpZyajFkpwxQGXIy92RdJFkQ0u/m2BSfvG7SHmtT\ + g4gwcpJ1LH6S9QWjnBUpVyKRzutxKTlq3i0Q1KDOxxAzOBX9dZQ3p2kKaDRf9eeWox/82tAG\ + LgK606vPFaKFS4WcRGNKswbdhjyBkZEtSfcZwFD1X9KEkSHwMWljjEYR2AlZDlIZaN4A2/Ai\ + aLmaT82Tlp+OlMniJCTIjsqELH6E4TOeRpIlB0s+BoCbY1P88LFy/q3y1hhXkh/P1qz+6uu9\ + xmxhnWhjMgAHAHS6vbATyhiCs+bhVnSMKRoglGmht5m+hnoGooviTVGe2GUV3fn1kMHorEAb\ + rJmZqMisx8JZ0/N+nkGlhZVMWCZkyT6Mu0kGAqhYWRHNFWmgEWk/68dcwA0y0eV4G+FiOO9s\ + 2TVlBnr84Twvz6dzwZ6CPdRZzNQG+/8GrgG4KgPQcypZpjpoSLd4xLIQPy4o8nP62CIylGX1\ + zfoz552srJVexqHpyKTKcyBL0kxtkDxKGv1Y6yJmZFeZiwWyvFyUC2tDO0QCDAZw8ba5jqUw\ + ZBkzK2JtrZgZGtHaysKS9lRgigkAA/pgO1wn9RrWuN3J+tFG7gM4EYBC44qsFFJ/MmEuLQ9x\ + 3+F5PHBkHodmF3HoyBzml5awtDzEwuIAswuLGAyGGAyXwffoLywuoSj8xo48zzE+xnfvAUSE\ + yfExgIA8yzDe7wEA+t0uOt0cnbyDiV4XRIStE/6e8Hi/i06WodftoNfJ0e920OtkGO/10Mn9\ + jsFOznHXAD2RyjOj4XNzq644HQzN2WVjWzxjccpolR50PZMHBny1IA0mXf1BhPmlZQyWCywM\ + hlguCswvDVA6YHbRb66ZW1xC6YAj84twzuFItaV5fnEQt0QPlodwzmFh0W/D9uz6T/+MiAeL\ + LMsxMd6vWPPbmMf7PfR6XYz1+9gy3ke/28V4v4ttWyawfcsEdmwdx+7pSfTyTNqsmHYAiZPH\ + okp/vs5UIzitE20kABxvnhWo75SdOczML+ErN9yBa268FTfcegduvOlW3HTTTRgOl6NNJXvN\ + AaUTuaVTPHRS9RW3cargnzwA4yojqs7xevphnHBty5atmN42jamtW7F92zSmp7ZieusUdkxv\ + wa7tW7HnuO04YfsW7N25HVsnukgMzZwjs3M86o+cr44g7ejJfNwgUYRwxwNHcOeDM7jrgRnc\ + e+gI7js4g5kjc5iZncWhQzOYmTmCg4cOYubgQQyHBfQefv6wk34q0HoICWR8RtZYu5DbdJME\ + o6qr7aTb62LfvtNw+r5TcWDvSThn/6n4ngMnYWq8pyI+UG8zD2062YHX1Y4V9bDGtHEAQBYA\ + cCOVGcF1t9+P9/3dZfjnT1wWnT15SksrTTl81Le1T9ulD50AzPiUQfE+OYCE/d6873oY3qnm\ + Zmcxe+QI7ohBPjXqwN/pp+/Hgf2n4eGnnYLzH7YX5552AqYm+nWUj0BQj7dx7UAfC7DlWZUq\ + L1JjNf7q2q33H8HXbrgVX7/xFtxw02247hvfwqGDB1MdMTlwkLQeD9b65I9UWw8I8YePkoSH\ + OTIH+/AAk+iHbH0PBgNcf/238O3rr8c/V+PodLv44Ut+AD99yffhzJN3SdnyDC4BUAcAOzY6\ + A6DGF1auEfmHgAAQLcK5fi3kZiT8/y77Cn7nD96TRAntmNpYwrlYNpBC/MZMgF23jFa0pcpp\ + Y+ZAwh9BtQAieS8AM/g8z3HRRRfiqRecj0se+whMT/SbHZozyNNTnj3ozKBpymXQt+96EB/5\ + 3JX4xKc/jxtvvJGJV2VDirS8w9gTIGzI6KxHjXl71jsVEt2o6ZSVFWpdNZZ1Dr1+D7956Svw\ + o086NzA9WraefgnAO7JHPsWU73rQRgHANgAHZcqk0lsAIOAvP/k1vP4tb4+XkojMIgUyQifv\ + VE3Jl1QEchUy+4c4KgWyR2+rQpBn/GO4FrhoIwt9NBmOalVc087S9Ax9OLd7zx78+i+8GM94\ + zBlKjjp8se86tbeMNDJgO/7cwgC//7cfxwc++CF72sS6tbIqfV6TkB+ALM8AEMqyAGUZqDrm\ + MtLH8bvmj4GD+Vgzd3wVRPg4LBDJshzvetNr8bTzTvcdWmso8vh1cO4Nmw8AiM4A3LcajbKi\ + G+8+iGe//DVYWlwSCut0uxgfH0e330en00GW5VUzJRwcymGJ0vln4l3pUJaF/3QFUCmuLMuY\ + ppWleqtLWECKZQAQoXClGb0ACIMM15NsAbaT6AyGU1N/vNwbf+2X8aNPPC91WLFAxR2dZwFG\ + RhA7T510fnEZr3znX+Lyyz+dOJEFWHmeI8tz5HnOmiVQRpXcgpN5/XlHLytWXPrJwLqMAgwt\ + 1JJxZSn4aZziWZG/atYMIEZWx4HmxJNPwt+99Teww3pQiNu5P/dOwP1idtbGAcDGrAE4tyO9\ + PZOmse/5u09gkT3rjYxw0kmnYHLrVpRlibIoUJQlisI/d14UJcpi6CNGAZTkTSRDjhIFsjKL\ + L9qgLAPKEs4BWeaNLhhg1FWWiewgB8XMgGL6UX2ryurnv/ULPuO1YHRUG5W11mCmxpBtvfFt\ + 78V5p/83nHnyTunooxb9CEb2pcvp6QPw/o99AZdf/mkmg7ro2MQ4+mN99HpjyPIMWd6BK8sI\ + wM45FPGYAXR1jNJV+shQlmXMAvgn8hyuKAAiZEamFrjy+mCgpNcMFFCHMnoKmAB5AAYO2mx6\ + eOcdd+B//etX8dJnXigVyQUf23c7jQLrShu1D2AHANS3uxhV3+96cA7/8I//XJ3zHyedciqm\ + d+xAnuXIsgxZ7j87Hf+IZp5nyLIcROQNEFmMNlmeg7IMebhOBGRh+A5ZloEoQzD66EMZE1Go\ + J6JOzX+WZf5S1K+/HF+R5bxD67fJ6BQzLIj5Lo1UVCQQDkuLi/jjj1zOZOVidpNWqJgKTi2A\ + WAMMAxLncP/hBbz/L/9a9N3r93HiKafiYY84C6fsOw3H7dqDLVNT6I+NI88z5JnXCTI/Jetk\ + OSgjEDHdxOMsyj2r5M7fLxi5yvMIdBllET7rMXiJBd1Z60AOHpACCFsLygl4OyTtxOsBGBzw\ + j5/6fGhAyZ2V95nATgPT15U2BgCItkcDbZiDXnbltzCsIjuB0Ov3sWvnbnTyHJRnNQhk3nj8\ + 3L9yfA4ClFUGR/58ZXCAQ0bkjanSYA0CXkMJCIT7yAwogsFVcccDjTLauHqNGgys98wlaadL\ + jTbU5WDg4PCRf/wY7puZj7yLVDNYqM4OnJY/y8JctPaYun70iqsxNzeH8CaeTt7BgTMfgeN2\ + 7kS/10ee+VTfy7rSTQUCndyDAIg8CGcwQCCrQKDWB5ejSFQCCDiHnOlMg3LQnZ7q6jsF1tuT\ + xRuO4eqmFQCHOiGLuOaaa3DHg0fSzEoACQHOnXD5l6/e0J8JW9cpwIF9p+HNr34Znv3kx+0Q\ + t0eMtPXr3765+upTrN0nnIBOr4tiOASIMMQQWSXw4XBYu6NzyDs5UJCfDnQyYFhNBzI+HchR\ + ugIZAS7PffruXEw/w3vzqIoElGU+9awoi9MBPw7vnNUQsiyuCfgSFRBQHf2T7DD6HgMKI/rr\ + 21nB8FxZ4vPX3YRnXXBWbCu8webI4lIU8aAokREhJz+2TpZjvNdBv9vBeC9Ps7IIFMAXv/5N\ + kfzsOfEkjI31UQxLOAA5aicYsjfelgCoAPIMKFEAJZBnHRQogDLzJTIgKwkl/FTPFb6jpukA\ + 4EHAFYUHZUBNBwI5v95QQiza6bWKxkVJklO2eMuRtSUWF6vzl331m/ieh++z2/QMoHDlCT//\ + +rf2ut3uoLng2tK6rwG8+s3vnr5vobjo9BN3jyx31TXXifnVtu07kGUZXFhM6nQwJKAcFsjz\ + HAV8OtOhLobDZeR5BrjcrxwTIadq/p/JNYHw4k5kBFcCcKUCAYZRFVAEyohQOhf9uZ6B+hXh\ + siykkTEgiPe19Z0CYve7AZEVWAta/Nzb/vSDeP+HtuCBBx7EoUMHsTxYTue7MAy6uj42MYbt\ + 23dg29Q0JrdOYue2bThu+zS2TW3Brm3T+OIVXxa87ti1E3neAdwQBGAIoEMdFEWBTqcTQUA7\ + Vwn/ktIcuQKBDFlJKFyBLIJyyUAgq8bOMupqLYfrAxA5ADwIZHAMlLk8hBzZJ9eZlnVj9lDV\ + eeP/eJe8HcnWEVibOyYmJ07as2vnTdgg2ohFwNPe/I73/iiAxACtVzAHoU1OTsbUPsYWl2PY\ + AWhI0QCpLNHpeBDI4rbNIcqiREaZWhgEsrKsQCBDljmUMfIQyhA1WCYgrM+5yuiAehrgyzv4\ + LaccMPQ9/WgULOon542IJQwpoA8Bd9x+u+grrjtQeitRy9vBYWFuAQvzd+DOO+5IQIPPcQEg\ + y3NMbZnyi3oVKOcACgKyajydjgeDomDLLb3XR8UAACAASURBVBWVZQEQkGccBAogI+TIUbqy\ + cm5rYRBRH3FhMIAAgDJJsRgoF0WM6np84Y3GcVFW6SUCA4/81XcOGoEvkbUEUFesPeuSp+84\ + dPDgpgKAZK7L58caZYMR9/p+7/ZwGchzxxvC0A1BcAg3mhwHgQyA81fKsvRRP0wHKICAX4kO\ + 6wZl4e8GyLsDjGcicYswI0LhwhRARdesvq2llS9SfB7RSRpalJO6h83LWtHLMk5BJEEpvtKb\ + 8xmmuHHs/ly/30en2wHYb1s450Aux7BDoKLw0zF2+y86TtVWPR0IIJBDTgcQI3x9t0beFYhO\ + GqZoRMicBwGekQXZBP2KsUb25Iq+0BUkCDTuDSBmv8aYI6BX1/eesHvHJRecG18Mkp315FRP\ + a0jrAgBh999rfvY/43fe9z8TwQrDVYIPRt7tdNQtap8JODf06SZqJRVgmUAxFCudJSoQqGaM\ + WRamA1RnAjmx9JNQlhnCBqI4HeC3CJ0Ttwj52GIfpRF5AhBSbUB8cU+sfIPEO/d5+7E99slT\ + zv5YH5Nb7HdPPHD//aL/qmGpCwdp0OQBOe/koi0i/6MXnSzHEA65y1EUformb/MByJzXgfMr\ + /oUAgSHLBDKfnYHgshxUFiNvETrn6ikakV+jYQYTsjMHv7Eo/hANVIQ25KtvRY7arxHKb52a\ + Qq96eGwUXXDW6T9+1im7ugA+Befmg6+s1+agNd8IFLf++uzsP339lntf+o4P/sNzQJTxLZ71\ + sU/vPv2vn4m77wDg4qc/EyBCMSxQlP4d80Ux9CnmcBlF6fxiYFGiKAuURYHS+Q0/w+opwLJ0\ + KAs/HXDONWwW8m5cOldFHt8/3ycQeAYQo05ApzT9ZLIoCzO9N9PzkBnojEJFF153//4DeNOl\ + L8HUeB8TvQ62jPf8cwOiYRXhqqYOLwxwZGEJc0vLmF1cxtziIu558DAOHp7FfQcP47a778Vl\ + l30y8jC5dQse/8QnY1gsoyxKLC8vV+l+gXI4ROkchmUBNywxLPxTevG6K/3+gKHfx1G6am9A\ + ae8TKEr/S1B8EbZpsxCAOjuLawKWTpwAASEPa+FPZQfJGgwrQ0R435t/E09+5D45ZWxaaPQD\ + uAdEfwbn3gbgbmB9QGBNMwD2vrOLQfQOAGeeu283/ujXXiKFYtwKfMqN38Htt91Wt1WW6I+N\ + ASBQEYTa8UaSdwAMgU4HBRXAsFLQsAAyoJN3MCyGyHOqhjyspwOwFgZLf3cgpp+OZQJhsxDV\ + UScYZkw/AZFbVlYTopcvWhuQTt1D9aZdhE0r1iecsBvnn86esbLAnar/CELuUxN9TE30UDtK\ + 5QlVmVvuO4xPXHZ55Hl5sIxOx996XcYAHVebkl92KZDDocz9wuBwOPSLuM6BHPksLfer9yiB\ + ggoQsUzAZUAZ1gT8Ym2Z50wfOhNgJhWmA2KNhuvEpzGUebsStwRD9oMUmPnUzFpA5GVOO/64\ + 2qbj2o5LQSCcI9oD4FdBeDEcngzgulR5q09rtg+gvO6TqKz4F0H0LwDO9FcChDZUrARy6skn\ + VaX9GsDi4iLyPEe300HWydHpdP1Gk7zjtwPnHWRU3X/u1PsAwj3pTqcLEMXNQmH/QE56s1C1\ + uSQaU9gPQGyfQHUtLA7luVB22CUQzIgbXty2zIyMRxCRhjsnrofyOv0MILJj23Q8Yzq/qhdB\ + IF4LXsQiZjWuHZNjkRcCYbC05Kc+eY5Op1d9dvzW38xv/80o8zrIs+p8Vm3d9vsz8jxH3vHn\ + c7ZZKM86lU5yhA1CGchvI8hqw7H2CURJM53Um7cI3PAckOgjZAMajDUQ80/A6yrc1dm9ew/2\ + 7pyqZSsyAOMc14HDLhD9AbA+LwxdEwAor/1kGOdzALwdgF+6dbUj+A/1yS4dOO0UAPVC1pHZ\ + I36jSTdHJ8+RBefvdioQyJF3Ov5atUswbEzxBud3oQHwRpd34l2CuBON6s1CedyQQskONTE3\ + D8anlrlz7sw6kmT1tbgzEHUaG92MzU15+WCQvDwA7Ds5RH++YKczEZLf1V0NUT+CAbB1vIv9\ + Bw5EnTjnsLC4iE4l8263h7xTg4B37g5yqnYDRnDI2AauCqAZCFAEgdr5iQiUZ8gor9Zo6s1W\ + NQj4z4zrhukkI66faj2nOg4PGFnbtmPG5aTsY7pfBahQhohw3jmPNKK9ZfsaBCjUuRhEPwis\ + PQis5U7AcTi8yx9WEZ8PWqSaSM6ffuIJVTX/75477vTOTj4L6Ha7yDvByTPkebfKBDxAdDod\ + UMcbVV5FHco8aAB+RdlHqsoIw47BLICAjzpAZVyZNLqjAYEspvDGklGmVpyroTv2T4gltFL5\ + cEhbOUDsP+l43gWYQSly0umJAUMwRm3ARHj4w06vMxUiHHzwQXQ7nej0XZUJ5HmOvNvxOshq\ + R8+yvM4E4rburN7KnXMQQAUUUNuGKbKnQUCwLUCgBmTHPl0AASUrndrzz6A7sZZTXXvs2Q+v\ + ZSsYCnKvPvnUhMvd058CWPO3Bq8dABC9CESVRfLIwy0e6nxNF519ujh17z13Ybg8RLfXRZbl\ + yLPMg0C346cDHZ96xqfPsgyd3E8XYrpZXQ/bhnkmQETy2YGs3nIMIKafR50JVN/zMN8UqadH\ + +yyXKSxiSWZkok5dRpDz/X7PgZPrE4mcZXnGeGqopDIDzwwefeZ+wcudd96OrALjCAIhE+h2\ + 4pOaIRvLqq2+ndxH8gASGWUMoHMf6SsQ6GSdWh8KBJDVdyEyIXeSMmVbuYPB8zQ+WmCYXjiY\ + OuDTMsucQzb31PPPrGWpM98AtkHGsREmfw8QOwG8EGtMqw4AbNX/+fGkMiSZY3FrrFPOfbum\ + cc4558R0k0C49Zab0YnG1fVpfTUd6FTTgE6nMsZOx0edLAN1sgocsrhOIDKBvIM8z0TqX2cC\ + FCNHvVcdsW7Ytw7Ui3OUy9tjPBPg5OegWR1p9BSdqI72MByflfuexz4Gu6bDj80ww0rSe0jj\ + i5HeKWOtyrmKUwIuOueMyIeDw3133YX5uVmfdYWsLK4JsCygmuvnWYZOJ6/e2yCnA3kesrRq\ + HYe87BGmbkQg4iCQe13mQR/VsxxBbuwTqECgGrdfo9H68MdZlrMZlJyG8TaT9ZpKRk964hOw\ + d9c0wDKD6PRivSUcumYdAU/Vul5tWqsMIAPcRf7QpcbGBy1QD+Bo+LSLHlcdeiV889prAPgd\ + ZgEE8rCwVK0J+KgeMoFOzAQoLP7FpwL9wqA3QL/glFVGIhYGw3SA8ooXDgJ8YVClijoT4GXU\ + PDzLcnErtBYHW5jin9Fgamd86uMeXcuYU5A310Hsg+lDRyUduRxw4PhteNSjHiX4ufGGG9Dr\ + df36S8gG8hzdTrfKCLpxYbDT7SAjBgLVNCCZDrCpgnyAKCwMViAQsqs4PfN3a4QeNAhUY671\ + US+vhjEFUBbrL0zWQrwMuAmE51x8EcScTqo66i3Rk/CHWGmvvZi7erQ2AEDYCwd/A9rF/9h1\ + lQGIrKBGw2dfdB76/bF4emF+Htdde10V5XN0ux10uz10wnSgWhPodPIYgTpdnynkeY4sXK9A\ + IEQeMR3IMkDNNeu7AyyyZmyVOVMppwaBSol15OHzS29kYToQrxElxhU+9S7KyckJ/OCF56R6\ + SFaa03m9iFS6DvEyntdnXfwkwc83r7kah2dmJAhUC4Odbi9mBxYIEFG8lVhnA3Vkb1wYDJlA\ + Xj/e7fXhnXokCITsrLpFKPPROqrHKQUXDdNd3H/AMr+zzzkb3//oM6AaTW3cmmLZ067jEiZW\ + mVYfAHxknBbzSZYqeWKGyAceU05//qTjpvBjz392vdBCwNVf/TfMzBxCnneRd7s+E+j2/JpA\ + tRbQyavPcKuw00GnMqisWivghtfp+Fd759VLLPIqFY2ZAIFlAtU5IBoawNcEXBwWoEAgRh6e\ + BdSfVEWeiIGonZNveIkpaXXtR5/7LOzZtoXJG/KYL/TpNLTKZOzNKlwv3oCf+/hzcOrevWIu\ + fMXnPw8Codv1GVan68Ggm3fQqbIynQnkVTYGqm/NikygAuzwXYBApqcDfmoX03zoW4Qyu+IL\ + g3myNlPrxGcMKSBbIAwH/OILn4NeJ4ew+WS6a0yzLFD2Nn8Ia0yrDwB+bKU+EWFRrwEEEoAR\ + qji89JInYPuOHSJt/uTH/wULC/PoVKl+HfE9CGR5WP3P492BvJou5NX7BMLCYFwTCO8QyAgU\ + MgEKawJZsk/AA0O4JVW9X0DsE6iNRKwJxMgjM4Hg1AFI9D6BcMwXnQBg565deOklT0rXUsQq\ + P9L5fTw0sgDGq9bLxFgXL3/h8xmmE+695y584XOfBZCh2/V7MuppWgedvBtT/QACeSdHJ+gj\ + y2MWFdcMqkwgrB0cDQh4UK6nWhGgrbsDQScU3g9RTwLqkdULtQF4+ZoAv1Pz7B++BE85J/za\ + nQZZ7uTs2JJ5OO9B5KbGMqtE+etf//pVbdDddzPggeVVIuoIQ7JAQE8D/PHkWA/bjz8Rl33m\ + i7HkcLCMW276Dnbv3oMtW6eqdlFPNyqBe4fxbYVn+oNyHOrUsH7qi73oozp2jkfrcOyd1j9A\ + xMck003+PbyCLFB4k03t3Kz9wDYTRWw3fK/+venVv4BHnX6CjPZ15yIaLS0XuPzq7+DP/umz\ + +POPfhof+uQV+OqNdwJ5D6funJZpr7gNKPV15sm78e37ZnHDjd+Jpw8++ABmZmZw/PEnotfr\ + eglVfNcj5E/JIUY7yohjGgPAqk5GlTwqOVfj52VAtZaS6RhbX7Guhes1KNe6cGCLuEz2nE4/\ + cABvvfRFmOh3pey1jSvbSLKDdFrwdjj8G+0+DWtFawMARAsgeiWc69VGyIyIKR8Ix2BGDIGa\ + Z52yB4fQxVVXXxcVP1we4sZvX4+Zw4cA+DcC9cb6cYHFL+RAKM2JqEhwBJAj1n0wTv8QkLCv\ + GPIcwjqyB4HKuKg2YqlnZnxsEQqx6dCJBBki8nvVlcHxh1Fe/MIfw0uefoGUrTl3B664/nb8\ + 8u+/H3/+wQ/j2uu+idtuvw133nEXrv3GN/EPl/0rvnj9HTj7jP3YOaV+tl7rpjr83rPPwGev\ + vgH33/9APH/40CF8+1vfBCjD2NgYxsb6UTZxxPqBpiDnIAXLSQIAOtnGKBCQ/Mp3KFjrNR4E\ + MpQIuy+jJqrriLoIYEBE2LHjOLzndZfi1J1TKsgZlGwO4sNMnP8BOPcSAIO1BIBVfxjI71xy\ + APARgH4oifZJZEEKCIAUlHMYFA6v/7O/x4c+/BGBxvyz1+9h2/bjsHV6GuPj4+j1evUtw6za\ + T14MMRz6h4WGReFfLjosUJbVgynVQ0TD4TKA+kWjZVmKF1jWDxCV7GeoyupR4koW7FHiMHQA\ + yWvI+QMrDg6uKOvshK0JeLH48y943rPwup/6YXQ72QjD8hU/cPlX8aa3vhvD4RAn7z0Vz3v6\ + xTj3YadiWJS48vqb8Dcf+Sc8eP8DmJqexn//9f8XTz77NMmwpRMAN983g59/wzvwneo3Afh0\ + hkAYGx/H8SedjKnpaUxObEFvrIdOp4OyLFEMh/HhoOFwWL3gtfC//VCW/qGh0qGoZF+WRaWD\ + EkX1wBecA8rqoaPSwTn/xCDXU/ldPEAU9BAfEoqZYfqoNQAcv+d4vPN1l+K8fXukDuKUSgU5\ + Pg1WAJ3o0LkfA/BBYG0fClqTpwH9cwB0MYCPC2FoEg6fHCRCGSwXeM9HP4s//OO/EK/cStBZ\ + UYj+nTxHt99Hr9/3i0z8xaG53KwDIP6WXHgizbPk/Cunyb/SOrz1pn7m37G3CfknEPn8u+SO\ + brwngEeYOrDVBphnGV7xsz+Fl//gE+s5rk4fmXF98NNX4jd/7w/g4PCfX/A8vOoF318/IViV\ + uf/wAn7jfX+DT1z+SfT7Y/jTt/wGHnvgpFQHqZHi3pl5/Nq7/ic+89nPCfnr47qKw/jEOMbG\ + J9Eb6yHPqlu3mc+Csqx+4WdZDr3oUDlo6eJj2mVRouBPEQY9OH89PFHof/uxemS4enKzrObz\ + 4I7OZO1Vkj6izsdx4YUX4I0v+39wynFhCsptR0UndhdFgIKuV+vxtQB+B1j7JwLXCAA+FVDw\ + D+Hw8kYAAGyEbKJKUVfdfA/e+cGP4tP/+tnqNMshoYAgOFCY5yllW4/W8hRP78PXkVl8hzJ2\ + BkY8Muq2rLLhHD/+3sc9Dq/6yefg0eGJv5iau/qYyXNpMMRP/NY7ceXXrsLLf+Yn8cvPfQqL\ + TtWgq++LgwK/9t6/xT/+07/gBc97Ft74kmdBGq/WQ113eejwV5/6N7z3Ax/CvffekwKammNz\ + 0mMVL4IJulVtRbA3ZKjPj6zP5CvKajNk/nzK3lPx4hc8Cy944qPQ62YiOxNR33Ls0FjUm76G\ + e+DcywF8GFifx4HX7H0A1Y5AAtFvAHgNgDEzUvEUV6RFGj2h6gFX33IPPv6Va3H1N2/E1668\ + EvNz876YMjTLCHW012/bCe0kBtpwrjphAkmCaXG8aaTUkefkU0/BEy94LJ75+PNxwRknHR1Q\ + sk7mB0P805e+iedddLbMxAwjnVtcxv/+0rV4/kXn+s06iXU7o35t0EcWBvjHL12LT33lanz2\ + c1/A4uLCigAQxq3l3ShfAHqdQL+ww3xz0ghwH7XA55zD2Wc/Euec9XA84dGPwBMfcRrG+9Wb\ + pI8mlWfyTW0/nMcigDfA4d2Av/X3f/0LQdiWYMA/E/BjAC4A8MjqbzRZKFq3x8oAAGFxMMTN\ + 9x7CrfcfxE133Ie7HziIu++7H3fdcx9uufkWzM3O+iojopC+LhyyAUCSlHeFzMLMTuBfsX36\ + 6afj1FNPxr6TjseZe0/Cmacej4cdvx1ZTpEjQ1BInHJUxNF1G6/pog1GLqZ4dag8srCM6269\ + B9fcdAe+feuduOX2O3DDt2/EoUOHRAQX0dly2BXkzkHBcmQt63rksr3jTzgBJ59yEk7cvQt7\ + du7A3uN34fQTd2H/CTuwPfz+4qhFPCEXPgWoP2yQcADoC3Du8aGZ9fypsLV/IxB/nNH39WwQ\ + /Z0oJFKvJpRsOOZkGX+l4NmFJdx/ZAGH5hZxaG4Bh2cXMLe4iPmFJSws+TfgzC0sYmFxCXML\ + C1heHmK2Ag2AsLC4iKXBMgh+vn9opt6jsWXLFnSrzUREhK1bJj0LWYatk5PYMjGOyYlxTI6P\ + YWJ8DJNjfUyO97F9agv2bNuKHVvGsXtqAmO9jhyHdWzJi5+rhSFlo9vQ5035BRka7WkjF9ka\ + z1BktnLvoTnce3gW983M496DM5idX8Tc4hLm5hcxu7iIudl5zM7NYbbK5gbLy1hYXPItKblv\ + m94WXzIyPj6GXtffhuv2ehjr97FlfBzjk2PYOj6OifE+Jvo9r4uxHqa2TGD7lnHsnJrEcVvG\ + a9kHngUwsmyUk5aTM66tBBqevg3gjPV+HyCwDgDAqfpdwJ8E8OcAjIilUls9X7XqHE3KNQIY\ + mvs0+ousNDglp4ZFOek4IwCuaepjOrI11WgyOsOhxdiMa1Y2MVL+zBmajF+tI0gAUXwlU0LG\ + oxkcrMzG4Oko1jdEP5xEGdjjFTpnY0zlcghw2wFgvX8ncH1/GYhUn0EI2smBWlBOfY91rCjF\ + ylrGqdtMjg2D0P3xdnlZgnGOUvBw1X+Oj4ldJEjD4m3zfoVBhn4JokFttC44QXCShojmwjXl\ + XFaEqwel+NFldLusnSATAdC6PrcVJeMwlsgr0rZifSOSw6VtCHlCnhcAGMZL6XhrZurx8/o1\ + H9sAdI3Ka04b8NNg3BlGRCNSCm8KaFEJkEIdlXoFJ4OT9eJ5ku1og0wVmAKVaJeUYbHP4Fix\ + Xzbm6KQjoqjlfMZh7DPKRPGkQZjLNY4fTEb8U41X8AckDhfY1iAWLvL2eASNIOTStonX4Uwp\ + J06yHSgRWvbJ6ocyZiBSdTiIRFBS12sf2JAfCt2oHwdNU7dASSocLzQYPKvDo4pIW1VEDcbv\ + dFnVd2xbKU47NQePpgwi8ML74VkD5z06P6TR6ClAKBvlxyKZHo8lN+2A1lRDRH4mM3Yq8ihk\ + otrhsrAyJd6gnmJw+fMMIMqd8a91KQdcy5oDPbcFywairJysJ+RujQVSpryo0LcDgF3NUW7t\ + aAMAwEBOK1InCOtgGzwjbXRBWaFevOZYe+H4KPkOhzrT4IFaTD94tBrRZpK2K2fiqXMwPp5h\ + hDoiauvrDd0n7YABEwcoHXW5g3DekbYljkfx5WS5mG0xpgVQaT6clLOZpSHtW+C0kzrWfYXr\ + wqkVyNpzfQVq4Md70qnJ2tPGTwHMNJE5qXAep5SjkbgiK82WBdR55jh6jm2mtZT2IbIVXVbx\ + ZY1dz7m1QWneefZgjV1EaxVFo2zTZm0jZAYrpgtI5SZOQmUBAbSQyiJ8Ol7fCBa8L2saEOTS\ + 5IBOyVg7JK8TQc+wLw54ISsRQK1sjOvbmkqsw7P/Fm1cBhC/cgdSDqkRN5Y3DD/JBniENvoL\ + jhkMbsV0lUcdA+nD0Hik5kCliTuMmc6jrkeMV53eWyTAiQMlb5cZqAavxGiZzMSnIQcOzKJ9\ + BpzcOXS50L6YtjTInmcocZxKBlouMaNg8kiyG36ByYpnBTwDEHpiPOixCZYS8NqRMrz2tM4A\ + oFCfCx5ojtikFKHntAGBtYE09cvncjpq6fqxPLumAYFnKtEAFL9WpmP1ZUWkOAxm8FbmY7Ub\ + +GbsJO3FcUAaqpVhCDkx5zMzIkO3Sf+QOuB9K/+X7eiLpApq0g7HHZKknHTQt6ZlSRZp8Qgp\ + Q5HdJO1t34AlgA1aBBRRzHBOgexGvWgcwfCYQ5gG6SAdRjuRihzW3C+2hbqNZG5v9KlTXdWE\ + bUDqewIeTsnHsT+osRkNW8DDQTWCnZZbwxhjJaTlV5r2CLmzvrnsCIYtBB5VtrDStE9cZzrU\ + wKerJnJwaVktC2Lnue5FNhZphwn6a0wbAwCm0CCdDQ3CFnMs5fjR8Ks6Ol3mhuRUm1Y0tOaR\ + ei7nGpTN02Qxp2SRyqm2dcqu5SIiiSaS9TiIxgyK9xMHxIzfKGNF7iZQ4P3y9jWwx3J8TEyO\ + DUmHHC7vEzJqC6BllUfPwREzN6fOc/AQ01TDRq0pk5Bvg41hU0wBmJC441kInggYhmIg64jr\ + 4bw2VCe/8rbDZ6OhOHlOtKGcL64rID0WUU+PkbOqQcCKcgwwzOkLb8cZ5xVo8jGFKEuBbw62\ + jNemKQsfT5Lp6Y4gZSl0yhrjmYk1B4cqn+glZScBcWsQWv96KhdE0BTcmsCpLn9c45RuDWld\ + fh5ckhsK5wdSoSVRR19H7SAj1w0gFRMVLbzMBhCrf8fqcscWvDDj1O2Jc8FoVH88CxDvBVOk\ + x55kFwYP3E8F+PJ+2XjjdRKnTVkLJzLGJMBMD4aNOYRyp6+jlleiJ2MsYroEo3+ll1A2maaJ\ + LzD1xjPPaAuhi6BLJQPnZFmH7Voq60EbAAA0K5SijZift+bj4PWUsetyTcfcOIQjN/SnvzdG\ + CqOedgwetURkY2XEMauvsw8dBTnACXBlRgjVjgl4QGK4TbKw1jpEGZaZmFEdSp8atHT7rK4F\ + Xsl0i41HABp3WMUzz3pAil9KeTf7U/Jwqn+mtqr9HfbUbm1pY+4CVCCfRiBu/LwaSYPQxi0c\ + w9VGw9NF3V7gp9HJlfEKxpFe48rV5+PYGupG0ZAyFM4TBy+SMtGgCcV77Fb16dhF4RhKCZaM\ + dNuyUaYDSF55e9y5+TRER2DlxyZoO9VuMr3QQDaCp8ib0a+eVgVgbnJea/qRTM0AgHasGFjW\ + gDZmDQBIjZyf58aeTA/Ysa/AK0M4B7HvGgx0NE1YVUYVizaBR5PjWqQALbRr1Y0GbkRRC0h4\ + H8ZhWp6DqMoUdHluuJw/7XgcjARYuLSNBMQtZ+J9BRmMACUNGLy/BISNdoT9qCIadBWLcixA\ + YgPN17bDrc9PgnPaiJ2A8+KrmHtCGTs7F8sqgzIXtpAaekDpBHgaDD6ZEuhPxquIXiMcqDFN\ + hgQ3q15jm7wxJ+XHTseyVvofIxu7ZgIOjLaVQ+t0nY9LOJUGbhhjNPQb9J/IVYOI4t/Su8W/\ + 6EvJmdtqFBfPXkLBJj2MAGzn+iBa9ycC1xcAfKQbxO9aYSIqsPOxvioTFBDbcraB6bmijkpJ\ + 2+p74IUDkI5yoYwYrHJqfY3LIYxFR50mo4lpJwc2Ne5EFsGAVeQjVU+3w8vx9nSGFvli0VWn\ + x5ZzWVlGwjNnTvHQZCOiTd2uq8edZJkKGIOc+Tmwc5w4kOos0wRyYfNTaYNrS+ufATh3REb9\ + RAhA4hwssojUS0UDx+rqCKGVlkQr1PUcq7fyeGr+Y/1gBOFPRTJhUIx3AUp8zMoJtCOi4Tvn\ + L3ZCzLANQ44yUaCjwUTLTqTgfGwGeImIaRCfjiRAQQ3jZvxZU7OEL64bY3zcJvU4rSDRlKHp\ + c3r6JO1gqyWOtaT1BwCiIk3FtOMbThkjS9JerYzoa0YEiF+dbahNcz7BF+/TUCK/ljiYYaA6\ + bbYiUeKkKnrz8hGMQjkNcGp8ScoL1qcFfisAYqzr2JCJsa4iYWNmw51fyU7UYWPVmRwrIj6b\ + ZJJkhLybEWjFx8zPxXpOlrMyl/r8tuaO1obW+Y1ABACHEkNvikThMzq4ZYANUSFeC/2SKC76\ + 4FmFnjNyZxg1D9bXtJGvZEQmaRComNVt6UgVMgyrywCiSbbVYMDWWKvma8fT5XT2o/jUWVOU\ + v3IWi389VdHptgkuKoCMBB42hKZrukCY5vBAE/XRoAe73f/oGYADAPWLHpAOmKRkYE7LI6WF\ + 1FCRVBmyRuAmQ3O6L3UxMRbVJqcYjdVnY8Ri/TZFoSRyO/ansxPIdkjX52UagMzqOzi4TmM1\ + byo41m2QLCPGayhEp/V8qtKIrY61G+SqxmSBaRyfdb7hnCVrfc0qLwFrE6wBwB3xH0A0IBGR\ + dBbABKudPRTXDsT/ABYhWUVzHslZLTbZ1wAAIABJREFUsBTO+zWMSGcWYpy8AIvYAmSc5FHz\ + Z41Lp8lWNhLaFqk145UUXxz8rDUBKzOI8oXs3wLRpmxIO5EA+iZHVcdi6sMdT9mXzvRW6q8J\ + sDVPTdlcohfVnq+37hnAuu4E/OgXv45LLjhvkFzQU4JwLjHA2sjvfOAwHIC5hSUMBkMMiwJz\ + C/710QePzKMsSywOljEoSsA5zC0uYTj0ycfC0gDLRQEiwsLiAMvDoT8eLGNY+N+cW1wu/Hn4\ + 980vLA1QsN/0IyIMlodYLoqKRc93UTgsLC/LxEUbmat+0pJFSwegk2UY63Wq9vwv6Pa6Obq5\ + /4nsibE+8izHlrEeJsfHMDnew7Ytk9izfQp7T9yJ/SftxrbJvhIuc/AoZpVdaR7jNYcb73oQ\ + cCX2n7QLA+Q4PLuAe+8/iAdnZrGwOMDiYIAjcwsoiTA3v+jlB2C5KLCwNIiy0m+fFu/or65R\ + BZKH5xYA57BlYhzsB51ZXWCs20Mn9z/hTlUb/rcBgG6eY3K8L8Y0OdZHHn+CPMP0lvpHUHud\ + HOP9Xmx7y/g4ut0s6mjXtq3oZpBZoxCxq2Urghm7rvWhp0G+4tQNt9+LM87CutE6A8DVePkf\ + /OXU95/3yHK838kWlpZRlGV0rqXBMpaLAoPC/0jk0vIQQ1f6z6LAclFiqSig4CA55tRURsU0\ + s01dPy3Hv4XfqZW/gGP1b7WXtpaOIeVWnSXC3l078ftv+K94xCMeBqIMoAwgIMtylABuvflW\ + vOvd78UXvvwVLA0GGBZDPO+HfgivfNWl2Do97dt2JTq5N423ve9X8C+f+Qymt07h4Owslqrf\ + 4LPGYo35aMdY10tlqftq0qMde2UbTXaj27P7JGQEjHU7sb9up4NunsXy470essqp+70ucspA\ + 5DDR98BMRNgyPhZ9f2KsDyJgfnGA88/Yt33ZFTjj+19gjmQtaN1+F+Dk8x7nOwTe6YBXNBl5\ + 07kmx+TXmwxupTJWnSYHHNXuKB6ajLWpvtU3p7qd2mHKssT8/BwedvLJ+PKnP27Wmz1yBI+5\ + 8CIcmZP7sX7rNa/BS3/2JeLc/Pw8Tj//QiwMBhjr99Ht9Rg/db/yzMpANqpOE9Xl6pJ2O7Kl\ + USDBHVuDRN2uHGcTGEkuZBnJX8oXa+MTp+za8Z9uve9B3H7Vl7AetC5rAKdUzg/gBwF6hTFw\ + QQT+S71URYK6TmpYTS3xMvX/1jXeNj8vfzZMkjM+CdIEuWHWBpoaJKn6mlPH/iTflTOUJeYX\ + FuCcw/W33YY/fv+fm2P9q7/66/irO5z7N7z5zfjsZz8nyr7+v/0uFgY+jV8aLFU/fS7dRPNf\ + 80bs/3r8ANg5Lbu6LKlyml+trzRIpK7ZDKa284drKoFP9OBGHsmxW/VYexffet+DLwbqgLnW\ + tOYZwCnnPS4o51QAVzr4xx5HI2KK4jDOc2qO3s0RoSlVXTnqjurDjhjc+bURW5Et5YH/Pp7i\ + qywxt7Dgf6Kc/PWpiUl86yufR7fn57YB6Z/7vB/Bl772VbPn7VNb8a+f/wKyLEOWE84+/wIc\ + np+PU9Y8yzAxMZkwoMfI+WyKnLyupQuwtlbKJGy9rZSPHFVEXsEeR2VuTb+GbPUvdL8A4LEA\ + riUAt61xJrAuGQABHQf8NUDbORLzKA9wgaSpZXCrFDXT+CAjgxOoLeNrXVdHI4nYZKiymfOm\ + bMLFf5bBpaDA+236Zd3Sudr5Q10HzMzN4hde/ev4xr0z+Ma9M7jmnoO45t4ZDMoQxVPTnltc\ + wp2zS7htZg6//eY/wOH5ed+zA4hQrdcsCunpjMbOA5rkxkvLHE3LpO5PyqUZtENdx46kbpuj\ + vkVS06kF6cxGttIUVDiPVdvjBPwNARNrG5o9rSkAhOgP4PUALtAKrZUiUzCNqvwcIJVgOZwV\ + LWoF+NZS57SjbuiDg5ZtMDUchfZ02mcZzijDCHxaUclVB/PM+QGwO6eEv//Yx3Dw/vtZxRLP\ + +bEfN3j3dMaBA54nyvChD/8vwWFotxguI6xqB91JffC2tb7TGF3LJM1+LL2GUpauoMppvrjM\ + 04id9pf2TMm1pgwnLZnahXW9qn+WA/4HIKbPa0JrBgAn16n/ExzwGq0wyykAbSJpusXLBEFb\ + KaGuz6MdNyQLcOo2nLimwSAle62C1HXbEHg8tY3U6A5Zlqm7TnWt5eUh/vub3gjnyuqOAOGC\ + Jz8N5z/6fLOHC7/vKXAALv/oR/FA/BVeVsYBE+MTcCSjNe9Z61OO35myVkNKdGIBOj/muvLf\ + NX+kdCFrNjkon35IYJMRXoN94Gel7IfXT8vQzxHwww5rux6w1lOAKQAfoKqfZoMmYSj804qa\ + OsroDMGiOlKlaWnTcRMwpGlgbYI6EkqenFm/jqQuMaTAs24v9DkxNoY843dzKX4QAZ/70pdw\ + 2823iGu/+GuvxeTEBDhNTkzg6c95HgjAn/7Zn8ioXTU51u8jz3MhHz3GlE+b9OKqBOb6vOVE\ + dgYmueA6sO9VIJF3WqL+zuO9tsn6uwwyKb+kvqcZDy/lgPcD2IU1pDUBAJa2/C6AveGLTotq\ + pctUkX8GkVtRgKAVUFNT1NDmkFLKY5MRawPTdyM4/2kdu2crUtmLf/U4JsbHhWOGjp0DClfi\ + 7W/5PZ8FAHCuxAmn7sVPvOSlosXHX/QEbJmaxrVf+xpuvfOuhMFut4tetaC4kqytrI1H5/Sc\ + /cfbtzIqLnW9WJhGZNuJ9Via+NdjlYBVcySdmCBDTnq3wQbKCCc7CXgXAJxy3vdiLWjVAYCl\ + /k8B8DKAC1EeaUcO37TgrbTbdmIyjmwD0mlbfT5dH4CqYwGCBjI5phR0gootA6v7cgmocF5C\ + eZDPBCjLZCE4OOfwpSuvxA3f+EZ9iTJsndoqWh4M/C7K9737XSjK8LiG76WT5Rjvj7EzdmYG\ + 43t6GzXIlztsCgpNIJ3aQVpS60iWSOWZBpzm0jqDC6v9TpznwM3zu9H2w8dU18LzCfRcB7cm\ + U4G1mgL0APwRYKc4QBoJrGgqhRzqNTvxaFWnbq3vN/NSowxQG4rdhp03aGCwDNUx3kIZW4bs\ + XJZhcnwcGT9Z7YEvHfDOt77V16EMzpX46he/KOD4G9dei7tuvw1XfeMbdctEyIgwPjYG0MrG\ + yx26Pu/MsvU4wxhrqY2O+FL+lsx1AJH1naE/21KsIMHb1+MjyD74OMN1vYisxwFRNsrnnVij\ + 5wRWFQBOqXf7XQpgvzZcOUinlKcFz80zzRxSQLASOm5IUuzcREME4ildentLLtDpsaVKtaca\ + aZThW2Z4Obv+yGibZRgbG697iQ04fO3aa/Cd678F5/wdg29+41rw8d97/31419veimG11Te0\ + PTY+DmSZEZmbb41yGLAcMZSQ311STgO9veGLuUlDALDAQktbf7Ns1xqPFZj0dT1Oiw9eTgcQ\ + B5xAwGuB1V8QXFUAqAaxxwG/rq9ZwtLXw+coQ0lTwPDpzYQLzzI+O4JpFLfcr8b7NPMYHaE1\ + WYbPFxADINiZhFwwleko0Ol0KxDwIwkP2JQO+JP3vAdEGQ7dfz/uvPNOaMl+4Sv/5o+q0/3+\ + GDp5bhp1U+oNSPlwJzgaMLCie92Odcs35WZUPykA1+W4jVhjgCqj6zX3T6YcAkwGcNMwpOzs\ + UgCnG6z/u2jVACAsUjjg1QC26kHW//ujJsOoS6ROxo+borEvUxsKxHltBJKv+lO6n+XsTW3z\ + SGGhujQuSs7rMehem25N1RHZodvtot/r+XOs0GeuuAL333M3rvzyFxVUAuj1sTRY8j07v+jX\ + 7XZZ6zLb0mDVlMo26diJ6zof02OyIqkdPTm/+loTIMsem66kZAUxK3tINcUBXmej0jYY730C\ + fhVY3SxgFTMABwKNA/iZ1Ah0vHBKMbUIVkLnugWrlG0M+jxPrnQ0d8nZtL6MDmlvKWCRMAQe\ + vRykfJodKZViLZd0y2y/30enK18yW5QF/uL9f4ybvvUt1qqnZcqrx3IJWZ5jrFr04+OtZZC6\ + swSINJpa37XJ83FLeUndNoHKSs+ENGVrK90OdOpY61dq1c5ArDHrgGQFMWWbP4FVfmnIqgFA\ + pbAnApjSZqLxNXWm+sxoFeoNHSkPVsS2DJBzJFPN5pkmL8/VbQGUjI6pqWsnSdsdvcHJchRd\ + brxK4QHEqcDHL7schw4dBI+9WbeHYtnP/XMijI+Px0ZGyVq67ahNTnUprRM9Rn4tcGg9W8Dr\ + Wzq1+g/XeH96fDoo8fZ0BhKuBau2goTWidWXxWFD+XECnmRWe4i02msA1as7pGmkyU39rVZg\ + E1xwQcr6pK7pCGRFC214dV88LvszNTLr+Vlt8PpsyrcECIsXQBpsDYpW23a2lBoTeYsZG0OW\ + ZXEqcGR+DrffcXes4QAs510UziEjQn98HDmlOrCOrZjX5HhclrJ1i3PesoPmRteodSyBEJDy\ + 1nzw69btyqMBFa3LJkCpy+oFZ6lToJ6cWToHaHZ0kPzuaLVvA17mgBu1sVtqtlIufoanRStF\ + Ck7aRI7mcV5/rG/JcbDRGzhkS2k0lEc61bPqNkX7NKrq6ZMsp/lHlmFifJy9rYr8Rp9Qv9PD\ + YFgABPRYxgCkhtyssxToOIVMSPDFWkqzARkO6rHZm310X7xeU8ag++Yat2Sbjqcpm0hBKrWW\ + VFcyk6nhjAcRAFcD7tPGsB8yrdobgS593sVYGgyHd9x96F8+8uUrX+bP1gPRqTB/1LMumTpA\ + +MbVowWWfmrXXgmd04c3zYiq2rXSNJ398Fq2c0gZydUCDmhpVsWXDq0MI57LMoyPT2BhYR4g\ + 4N5DB9GvIn7Z7aNcXESHLfo1ZSaWJJoymiZgStt0kBO71Ml1WxpYYZQf1a/Fv8w55FhTnv0V\ + vUNTQkpq22mwst9WFDaAaZt8xTOffEW3nzvKdEsPnVbtfQDltZ8EgJ0guvl5r33H5Jdvuk12\ + hCZnlWRFQF1flx1VXvevy+pn+dM4YDmkbZijeEr5r/u1xjjK8TQojAIu3vZwOMT8wgKIgJ4r\ + 0M0yzFMHGYCJsYmYDzbp6WgyFXs8o17tZXPcJAfL9JvsaZQtWfXttlIudEBrArvVsN1w/NRH\ + Phx/9l9fsgy4AwBuzc56ClaDVncKQPRzACZ/72U/iu3j1TvQwJ2pJq1YPmB9W0krRF8L9XWE\ + 4Mda7XXEkEt0dR3eoh11mvm3+pH100zB3lhjRZHgIqMzllQenU4H/X7fPyOQdVCQf+Pm2Pg4\ + XJZGVB2J9Tj5eKzMSsvVkp3eLsv7Dm1ZWYXmB8Z3a4efNSbOmwXCDrLPEDRsQLP5agKz5sBU\ + W97uLZP47Z//EQCuC9DPmYbyEGn1AMBz+0w4hwOn7MavvOASJlgZa7VRpwK3Ixs/KxXSnKpp\ + I+TtNSVSUuEr78jTiq9HO7oe/zZqF9so5w5lnbrGZcqv9Xs9dLpdlM5h2flFQqKmJyQl+DVF\ + tybntgyc9yT1bgcJ2znSZzq10wS7S+3CGk19JrU5a5qaLllb4DQKICzbt2w3J+C3XvQcnLhz\ + ypd07vsTxv8dtHoA4ADAne2PHV749Avw/Mc/Rqkb6siThY5N52sDSAVnOXVzejX6LT+6HYn+\ + /FyTk9gPAEnjsHYcjB4PknO2IesIykHNPziUIyN/zz/d9myPwMo4LGO3SMb5dA2HZwk2L9xZ\ + XNKO5DG1tZrfes2hSbZ6bKNAmNdMga62jmZ7kp/hOFz/mR94Ei656NyqkgMIq/rS8NWdAjhM\ + 8ff5v+nnn49zTz0pKWZFN20QVnSrBWubnXamJuPUffK62gA5P1YE1Pf4rfTSGi836KZswhpH\ + k5M2R+IULhyAyfEJUB7WgO1bXqncKOE13QVoP+SlY7YeU5M8ZF+hJVk3kI7yTUGiCdhW0h3Y\ + 9zTi6yc3U860bize+LUnnrkfv/LCZ7CTBIAmVkTb74JWew2gejeVAwgY62Z476+8CKdsnzYF\ + OGrnVlMEkDukHEgZBC9voW4d/esS+taNNgDp2PbrxDQ1Ob4uMyqCcqfgfI0aWxrx9f75SmIE\ + c5+/dn4ZlVPH0fKwpGHlF9Y6j3TbZsDVctDyqHmy468FlE0Ab13T4wjlbfms3IfV9sNP2IN3\ + vPKn0E1X/AvT4B4irfY+gHt0zDxx5zTe/V9ehG1jfSPK6pFIV1wJNFJAGIXQ/JwTnyEddEb7\ + vJ51XkeNehSpWpsiq44VEhj0a8bsdNLKcqzMhbtQeLWXrp9GZXs5zXaYZA97vO5ECSfqcVC3\ + 1oA4n00OrUGXb7WWTk+iniZCs25r/qWVjgIPOb6Vn5s4fnor/uhXXowdW/qqYQc4d6fB8kOm\ + VZ4CuCsswz/ntBPx3ld6ELCiGVe+/z8Vaq1AnejVRtGssO/mvEuuNRlJ3bekeoYqeec9cCOS\ + 49TRz4nzTkmnaWxaSk1Rk39aEctq3SlN8FzKlqZsT09b9LFF6W45+WBVmjNYoFhzoGXOx98U\ + TPioNJjwPq0gxmtajh+df2or/uK1P4u9J2yH/E3D2MHnsIq02lOA94rv7IcPLzxnP9596Ysw\ + Pe4fMtHRSUc9oBawlSpqhLYEC3ZdG5o2Hvk5+kcsbIdmYjiK/qUR8bJp9NOmpJ8dHDUm6zkE\ + zZcVPS3jtyKmNNHmh5qsB3qaQMsChXStRU5tmvvl11Mb0RvL0gVRCYMpQKSLl9oetS41cIZy\ + J05P4X3/5afx8FP31BWS32vE27GKtIq3AQlw7mNw7p3J+YouOnc/PvDan8Mp26bMiBOoVoj9\ + IM0oJVtldHagnVvX0avLso586IXzxqMSP4Zqx+o/daw0gnBJ6IiVAoYNh5Zzaee0+NbXrWtp\ + +3W7+oGeelohoUbmO2nbzVHZrq35SktrwE0t0gI9fl4CJp8CpU8+WO0AwFkn7MEHX/cKnHfg\ + pNrpk5+bp18F8AVjKA+ZVg0AsrOeHA5/EXAvBPB1/5UNBrj+3P0nvuWVP/KMRxPoXQDmARwB\ + UFgm0ZxkpYrVxmk9UGIZj2Vc/LyO7txgUqPiEVAvvumSKxmnE4bE+xsVKSmpT6IMz6p4tJJ1\ + j44smcm6dktSgymc6mlOc/8SuEINe/rVpAn7CucorZWucwRQkxmcLREruNw9c/i6vSds/yUA\ + l4NohtWYAfAxAE8D8GYQIXvkU8xxPBRa9Z8GK6/7pD9wAIimAOwDUMK5WwAcuf3eg/joFVfj\ + o1/8Oq6stgsT8L8B/GCoVp2rm2Htp4qV5XUdK1rztM9qg9fRZXjZUU6p22jiS49Lt9E0Ps6D\ + 5otfaZIFgTAshvFtwkc73lHnmsYJSOdoIouHpnOaRulsVF3uuNqRm+qtpEdbf3Xr1joWgP//\ + Jy6+4DlvfPFzqgs0XQXNGV/Il2SBdlVozX4bsLzuU/UX1odGr+o9gj/ugA+kSXOzAsDOa6Xx\ + cnrPdjgH2OaonXYlXqDaInU+PZY86PHw2k19H81x3U9z/aIokLNbgd+NJTSPTsq3OYbzXCWt\ + M0oHzaBgA18oMWqdSLZvw+AoPdlA0twvB8Zq3G8B8Orbr/qS950RPrOatGpPA2r67pCKPkxw\ + Mw5uGmiKLPbDF9Kt0ihnPW1lGadlWJYjpQYkjVa2mPJWt9H81BkHkZXS8zBGzYMev9V+RvZO\ + jKORA4zjUc6jxwM4yOcfNEg3jXcUOIQ2rHxDwhV30DRPsSK0fFLTDkhWvsPrWPqM378eaq92\ + lB9F6/LjoKOJALgFAB+QZ/VCkBScLhuuSUdN03zRK2C26pKS6TWXlLONojmqEvvfgovgvCTO\ + 8THy6MJbq51XmmZiuE5znXKn+dPjTrOxNBuq67qkrAbzUfKVY6vbaQLldEzaAXUWtjLvFtiT\ + OuKALK/LWkqOVxksrzltOADcdtUV4fCtAAqNjP44KNp6m0ot8BS3m1fsQyltiLyFFMGtCCjv\ + R3NHszMDzYU8U/eRvj46jUzaXO0xQh1HWRFYq/L5inClHk+6Ml9H/FQnnEiV5XdSoD4tfu1M\ + YzSw223qgCDtpslGmnjV/VtT0JovEnKUeyHoMAHXGcNZc9pwAAjk/JuE/kZHZG6UXMByBVg/\ + HDQq/ko8bjIm3oJsW/evU3nJux0pZD8Ebqgk+pEwpEdVG1NaKo2UuoSVYekx1OVSWerz+tZn\ + qgUX+eVj1ePSQCR5lRZgZQ7aSXUfVt8aZNKobgWYZqDVYMZ3n6bBxH0GLPitJx0TAHDbVV8C\ + ADjgtQQscnNOo30g/hwAV7s8sjfO1uU0wkMd87MWyHBFcmTn4CJbab4WakoHsJ9a5A6vjY33\ + o11ZR7JR2UnIukINi2ferjVNk4Cp92PYP32mx8GP5Y3WpjJ2fQ72TWsjqR1Yb37iOVPa10qg\ + xDPZ6so/ONR+sJ50TAAAo5sB/I5G0KbI6UxzkKWa1w50pE0jFt+ZoOeATake2HWdrYB9t/iR\ + nGuDl05NrI7Vvx257NzIynDquml2kYKHLeNaDmFpzSrnzG9NmZl2WN2X5B2ooYeEPvRGq2ZA\ + 5MCXQrZlm1Z/nC9ez8EVDvh7o5l1oWMGAG6vs4Dfdmq3k5WOj454aTaQpvjNv7nHy3Djd6q8\ + ZTw6LeVOVJt/2p6VTKZgE9a363Z0n8ywkrq6PWssmmQ2kl7T3GtQagKPMBp+tcmZeB8yoxit\ + jyChOvnm/NkbtdIx8XUDCaA60vOx8JWVtC+R1X0YwF3YIDpmAIDREMBzAdy4UkGZoqbO1BTl\ + moyaRyzZ3tE5S7hugZNuT3Kqo6lc7ZfXtDmnjq0Nsk5lJSelS+Vn8cj50UDD6+qsbGVyJq8c\ + yJsyFj4BcOJ8zbHdtudS2gDFduxAkPIXajWV02elvcX+SwLeBNQBcL3pmAIAJoS7HXAxgKst\ + B5corO8A+JJSWU1mzY/Te9Ia7bUj82jMM5OmtNKKhmlan47Jcm4L7NIsR47UngDYmUKAISfq\ + pWPUjqn5tcdXf2qQlXpLd+OlYKq1Jr/pjFHfSAWCvC1HreXQBK41L5SMRZMOIg54swOusq1z\ + feiYAgBAgMDNDrgQcG8DMMfLjBIYN1itLG1w2mAsBeo7DGlviD02pcnaCGXN9Nwog9ORWPcB\ + 9SmjpaqTCWMUsuPr+RYv+lbeSmOqQSgFg9RBeV07G9Lj559N5QDu7HWWt7ID6lGkACdzEnm7\ + 2gBvR8A7UP2I7kYs/gU65gAAECAw5/yvoh5PflrwJwC+DaSGE84FktdGJ6VpjuGPrairgUA6\ + m44sNgiF8tqhiV2x0tom3vQfryejbfPOvxT80t2FenSW7DVfddtNOyZrR9fZBli9lOPR6XgK\ + gikQADYvtsxl27qclHsKGBUddMAfAXiUA34JQDmim3WhNXsWYLWI/xIqE/gOAh43nDvyc3Dl\ + s6nbR97twWWZKNfkrEDtEP7YmfV0lArHipcYLa26si/71pU3fv0TWOlWYcvJ6v44D80mHK47\ + OFDVgObbHqNdLv3kMVHyr3nW7XIeVxpzU/vhW9OmnFF9W7ppGiuHNUtv1bk5AF8E8CkHfIqA\ + KxywHEpuZOQPdMwDgKYACLP33Y2Zu257PYDXhWu9sTGMTUwi7/aQd/vIul3knQ6QdZH/n/bu\ + 3seNIg7j+HfsnO98uuSMlEREShoKoEERFNBR0FMhUdNRISEqav4A0iHEP4AoEJRIUYQiQUSV\ + AqVBRJEShUMoQF7OTozt3R/F7J5n32xfXpRbz/Np7rzel1nvzLOz47W9cQzrFD/5lv8PpYZR\ + mFaet3KQaypU3Xrqz+yLzjZN5axbvrkBFCtqWBZnvi9a3ldXWcfcopALy13ei+Z9LAZGXWgv\ + OxuH21/U6JvK27StplCcl/Xg7eF9/I1s1/F39P1q/tbeG5TO8kel4eee2YeBnpX88sD5L0ro\ + uPx77cyYjMdMxuPGZTvdLr2tPhu9ng+JThe6HTY2t34/tjO4AnbawUmD08Bph+tXB4esUmlz\ + 88pilUYUvi1X7o6GZ5CmwajyvPW9jOJ8Rt6xrjJ848/LWRw2zQKisZzVbTaFR/Huzery5Sa2\ + rAHmpQ1DZXF3nNJ8xX1rOtvPJ6ZYkpDOEiyZks6mpNMJSTIjnU4ZPxze3j515tz2CycbA/15\ + jfCvonUBUDIKezDOORb1aNIkYTwaMh5VnvpycObs5zunzpQatPWAXWAA7LrsL9jAZdMdbhds\ + 12DgYGCw42AL2AE77qAPrl9/9i/3CpoaXf33F1DzOCt3FjZNP60drissgwXPzxtKeVvLLgvC\ + Uq12Rm4eb6jfRv0PfrjSeoJtJMDQ4D7YENwonUxOpNNHr6RpiiVTbJaQpAlpOsNmCbPphP8e\ + PSKZzVhiPP3jJv/eurFsviOp7QFwK3ywyuVMTUiMga/v/Xmbu3vz3zPMLjUmwB3gTrWbfbDV\ + SsOonlkMhzthWN8HAgOgb9iW88GybdDDh8UmPni2ga7B8SwYBtl6jwNd5sv0suXz7fey58ga\ + cM9g24HrOtcFNmZmPSuULnttCv2G4mtZPouHDazutQkeT8E9DOMm+3tvXgISYD/b4n2HM8OG\ + +HtCxs4foyn+mtqA+9k6HhhMHeyb/+ackYMhuBH+8X62zDg8NqO//+Le3s2P8R9AO7RSHdpL\ + 0+c+lvfYWh0Azrlf8gMRXgo0zIuZ1T1/gZo7sZ5mt+3c+bcw7AG+whaULyGaLi3C/8s9gUWx\ + FzZOs+qZttTjwcGuHYwMePXBV7udEdkgV2G7wVZWuRYvh0/dvi56fajZXng8s7pyt35PKMxX\ + V59K0y4vW89R1rpBwFyn08kPxGXg7WXzNxzMH4B3gVlbX4en6dz5NxeGySqO2iBXnSwA3gEu\ + rTp/Q/1IgFeB622tP60NADg4kG/gPzvQO+TiXwEf4bv5K10+yHrI6s0O8A8L6k1Tww+mXwA+\ + gfbWnyN5I9AhXcXfJHTwTarOLey0/oz/htUPUeOP2RD4Bnx9qaszTfUim34R+HTRfG3Q6h4A\ + FBr7i/i7q94DXg5mGTnnrpnoVW89AAABXklEQVTZJeBbfGAA7T5w8mSyenPWOXfVzE6Vpi+r\ + G1/g71Bt/Qmk9QEAtWf8TfxoO/ieQfGt3TXYZ3kyeZ1xzr1mZt8DLy2b38wuAp8BP+XT216X\ + 1iIAQk3d/3XbT3lywUByH/jAOfc+8LqZ/3ZqYA+4BvwIfAf8li+7LvVp7QJA5DCWjBdVrFt7\ + UQCIRGwd3gUQkcekABCJmAJAJGIKAJGIKQBEIqYAEImYAkAkYgoAkYgpAEQipgAQiZgCQCRi\ + CgCRiCkARCKmABCJmAJAJGIKAJGIKQBEIqYAEImYAkAkYgoAkYgpAEQipgAQiZgCQCRiCgCR\ + iCkARCKmABCJmAJAJGIKAJGIKQBEIqYAEImYAkAkYgoAkYgpAEQipgAQiZgCQCRiCgCRiCkA\ + RCKmABCJmAJAJGIKAJGIKQBEIqYAEImYAkAkYgoAkYgpAEQipgAQiZgCQCRiCgCRiP0P8fRM\ + CPaFrsEAAAAASUVORK5CYII=\ + " + local text_png = + "iVBORw0KGgoAAAANSUhEUgAAAIAAAABACAYAAADS1n9/AAAHlElEQVR4nO2be4xdVRXGfzOd\ + aWlLizC0Yh88OykWxQotdAoq1BRESVVSYw1pQgiRgBADxoQYidhExGBJNCgYEtNqUjHW8Eak\ + tcX6AMaqiPahViiVUtsiFKaMLZ3284+1Tu6+Z845d163c4ezv+Rk37PX2nuts/d39ln7cZsk\ + EVFeNA+3AxHDi0iAkiMSoLHRBIwHRtXLQCRAY+MmYD/wlXoZiARobEzw9H31MhAJ0Nh4w9Mp\ + 9TIQCdDY6PL0hHoZiARobOz29MR6GWipV8URmZgLfBiYBLwCPAlsLdB/1dNIgDqiDfgD8G/g\ + I0H+aGABcCrwOvBbYGeq7HQvvx3YV2BjNvAD4LwM2UrgeqA7Q7bH02ZsKni4wMaA0DQCl4JH\ + Ae3ATOA04Fng6ZROE9bY5wNTMaLvwTrwl8DeQHc6sMN/zwU2AnOA1cApgd5h4D7gi8A04MfA\ + fJcJeAC4AdiV8mUh8BAw1u+fBv4JvNftATwIfDrjWcdSIcY44H8ZOoODpJFwHSPpKkmPSupS\ + Nf6e0r1Q0ibl4wlJs1JlNrpsuaTJkvb4fY+kTknPBeUflvSv4P5A8HubpLag3qmSXg9kHSm7\ + i4Oyc3Ke/Q2Xt+XIB3UNd8f25fqMpF2qxmFJO4L741Tp/Lc976CkdZJW+PWwKh15WNLpgY0v\ + ef42SXf67x2SZgY6iyQdCmy+Kmm2pGZJl0na6/k/DMrc5Xn/kTQt5/kS8n0+R77V5afnyBuW\ + AGMkjRpkHTcFDf6ypG9IuljSsZJaJXW7bGGqMTslTc+o76KgvluC/JlBfjLCLM4of2+g9+WU\ + 7BLPPyKp3fN2et497nO6vkkyIknS0pw2eMrl8wbZlv0iwHskvSR7MyZLWiZpraRnJP1MNhy3\ + FlQ8VdJb7vhLklZJ+pTsbemrczNlQ7AkfVfS2AydpMNvcz8TvD+nzu8EOn9JyV4IZAdy7H0o\ + 0El/RsLOul3SRFWjR9Lz3n4rJK2W9JrL3nT/s3z+umzE+mA/2m7QBGh3x7ZL2q1s/E3SGTnl\ + F+eU2SLpgj46d6uXeU5SU47Oatd5StJpgZ3jM3THqPK2JZgfyO8O8jfn2GsPdM7KkF8X+Hxi\ + oNutfLwsG9WK2qKlhnzAV940MFmCTKLgbmwa81fgZOBa4CxgPXAOlfkqwCLgp8H9I1hkvBQ4\ + E9gAXAncXyM+bfN0MxZlZ2G/px3YqlkPFvHPAdakdK/xOt/y55gH3OL+AjwGfMF/7yEb44Pf\ + kzLkGzw9GzjotsYDV2AzjTOBk7Ap5kHgeaATOJRjL0FPDfnAkcOMYwOGHpD0gZR8siz6lqT7\ + U+WSYOhZSTMC2SmqDNndqh3UXO+6uyVNyNFZE/i5UNLjge3Rgd4sVaLpO1w3wRWuc4yk/Z63\ + Mcfe7KDchRnyFtlwLUnnSvq5/15T41mH7coTjA4e9J4cnfkuD4OepZ63V9nDcJsqEf23ajjX\ + Jmmf6z6m3t/kNlVPwW6XdF7QAb+T9AlJN0r6r+dtV4VMSed0qRJgrfS8XTk+nRHYOzVHJ/lk\ + LpK0IND/ao3nnajsOKBF0jclXVmj/JASoDlw/OMFFWxwnTv9PvmOfr+gzNdcZ20fHPxc4Mcm\ + SZ+VdeDJsvl8iHVe5jpVSBDiFVV/t9tUGcW6ZBH5R/3+zYJ2WSXpJ8qPS/7sdXzS738U+LBK\ + lZclJNUyt9mt3nHVXC97qMDmkBOAwOnZBTo3uM4mv1/h90Vv922u83gfnbxK1W96Gslcuyso\ + 0yELELe5b9+W9O6MuqdJ+pMs6BvneUtkRBhoo86SfVaSGc8YSY+kfN4uCxR3pvJflDQlVV+r\ + pAdln6VhIUBRY5wd6J0gG6ok6Rc5+jNUGY5v7Iej7TJyhauAm2VDfBivnDTUDTREV5OkayT9\ + Q71xRNLvJV2r6rjlqFxFewE92Lr7Eqqj+hAt2Pp0C7YuPgr4DRa1Xwz82vXGAlcDy7C97Rew\ + Uy79Xdtuxtb2D1Idqe8DjnMf0vsCjYYZ2OxqAvYMW4HXhsuZot3ATmx61Vag04M9xBRsevMA\ + 8ATwMWAtsM5tzMM2M8B23S5lYBsbR7x8GgkBinxtFGzzqyFQdCCk09PJNepI1gAmeroEm1O3\ + AJdgW6rjsLnufdjWaH8a4HzgLuD4Ap2EXLXm0xEpFI0Az2Bbn0X73GBvfRe2KAS2iHQ5cC5w\ + AdY5LwK/onrBqK+4A7gI28pdniEfR+XIVN4CTkQOimKAVuxt3Uj+StzRwHLgZuzbPj9DvgAj\ + 19vAu6jHnvk7GEWfgEPYSZnhPjGyytMObNk5jas9XU/s/H5jJBwK/SN2HAvgbmwdPUEHFnMA\ + fO9oOvVOwUg5EnYOFpO0Ym/6vdhRrlux6H899imI6CdGCgHAdhBX0vt/cluww5x7e5WIqImR\ + RACwkeBmbL6/BTvguY44/RswRhoBIoYYIyEIjKgjIgFKjkiAkiMSoOSIBCg5IgFKjkiAkiMS\ + oOSIBCg5IgFKjkiAkiMSoOSIBCg5IgFKjkiAkiMSoOSIBCg5IgFKjkiAkiMSoOSIBCg5IgFK\ + jkiAkiMSoOSIBCg5IgFKjkiAkiMSoOSIBCg5IgFKjv8D/zcFVeg+jbUAAAAASUVORK5CYII=\ + " local function loadimage(file, name) return love.graphics.newImage(love.image.newImageData(love.filesystem.newFileData(file, name:gsub("_", "."), "base64"))) end + + local inspector = {} + local background = {} + local bubble = {} + local text = {} + local rain = {} + local g_time = 0 + local create_rain + function love.load() - math.randomseed(os.time()) - pig = { - x = cx, - y = cy, - img = loadimage(pig_png, "pig.png") - } - heart_image = loadimage(heart_png, "heart.png") - - add_heart_ring(100, 10, 2.4) - add_heart_ring(150, 20, 2.2) - add_heart_ring(200, 25, 2.0) - add_heart_ring(250, 35, 1.8) - add_heart_ring(300, 40, 1.6) - add_heart_ring(350, 50, 1.4) - add_heart_ring(400, 60, 1.2) - add_heart_ring(450, 70, 1) + -- Subtractive blending isn't supported on some ancient systems, so + -- we should make sure it still looks decent in that case. + if love.graphics.isSupported("subtractive") then + love.graphics.setBackgroundColor(137, 194, 218) + else + love.graphics.setBackgroundColor(11, 88, 123) + end + + local win_w = love.graphics.getWidth() + local win_h = love.graphics.getHeight() + + inspector.image = loadimage(inspector_png, "inspector.png") + inspector.img_w = inspector.image:getWidth() + inspector.img_h = inspector.image:getHeight() + inspector.x = win_w * 0.45 + inspector.y = win_h * 0.55 + + background.image = loadimage(background_png, "background.png") + background.img_w = background.image:getWidth() + background.img_h = background.image:getHeight() + background.x = 0 + background.y = 0 + + bubble.image = loadimage(bubble_png, "bubble.png") + bubble.img_w = bubble.image:getWidth() + bubble.img_h = bubble.image:getHeight() + bubble.x = 140 + bubble.y = -80 + + text.image = loadimage(text_png, "text.png") + text.x = 25 + text.y = 9 + + -- Baby Rain + rain.spacing_x = 110 + rain.spacing_y = 80 + rain.image = loadimage(baby_png, "baby.png") + rain.img_w = rain.image:getWidth() + rain.img_h = rain.image:getHeight() + rain.ox = -rain.img_w / 2 + rain.oy = -rain.img_h / 2 + rain.batch = love.graphics.newSpriteBatch(rain.image, 512) + rain.t = 0 + + create_rain() end + function create_rain() + local batch = rain.batch + + local sx = rain.spacing_x + local sy = rain.spacing_y + local ox = rain.ox + local oy = rain.oy + + local batch_w = 2 * math.ceil(love.graphics.getWidth() / sx) + 2 + local batch_h = 2 * math.ceil(love.graphics.getHeight() / sy) + 2 + + batch:clear() + + if batch:getBufferSize() < batch_w * batch_h then + batch:setBufferSize(batch_w * batch_h) + end + + batch:bind() + + for i = 0, batch_h - 1 do + for j = 0, batch_w - 1 do + local is_even = (j % 2) == 0 + local offset_y = is_even and 0 or sy / 2 + local x = ox + j * sx + local y = oy + i * sy + offset_y + batch:add(x, y) + end + end + + batch:unbind() + end + + local function update_rain(t) + rain.t = t + end + + function love.resize(w, h) + create_rain() + end + function love.update(dt) - update_hearts(dt) + g_time = g_time + dt / 2 + local int, frac = math.modf(g_time) + update_rain(frac) + inspector.x = love.graphics.getWidth() * 0.45 + inspector.y = love.graphics.getHeight() * 0.55 end - + + local function draw_grid() + local blendmode = "subtractive" + if not love.graphics.isSupported("subtractive") then + -- We also change the background color in this case, so it looks OK. + blendmode = "additive" + end + + local y = rain.spacing_y * rain.t + + local small_y = -rain.spacing_y + y / 2 + local big_y = -rain.spacing_y + y + + love.graphics.setBlendMode(blendmode) + love.graphics.setColor(255, 255, 255, 128) + love.graphics.draw(rain.batch, -rain.spacing_x, small_y, 0, 0.5, 0.5) + + love.graphics.setBlendMode("alpha") + love.graphics.setColor(255, 255, 255, 255) + love.graphics.draw(rain.batch, -rain.spacing_x, big_y) + end + + local function draw_text(x, y) + local int, frac = math.modf(g_time) + if frac < 0.5 then + return + end + local tx = x + text.x + local ty = y + text.y + love.graphics.draw(text.image, tx, ty, 0, 1, 1, 70, 70) + end + + local function draw_background(x, y) + local intensity = (math.sin(math.pi * g_time * 2) + 1) / 2 + + local bx = x + local by = y + + love.graphics.setColor(255, 255, 255, 64 + 16*intensity) + love.graphics.draw(background.image, bx, by, 0, 0.7, 0.7, 256, 256) + love.graphics.setColor(255, 255, 255, 32 + 16*intensity) + love.graphics.draw(background.image, bx, by, 0, 0.65, 0.65, 256, 256) + love.graphics.setBlendMode("additive") + love.graphics.setColor(255, 255, 255, 16 + 16*intensity) + love.graphics.draw(background.image, bx, by, 0, 0.6, 0.6, 256, 256) + end + + local function draw_bubble(x, y) + local osc = 10 * math.sin(math.pi * g_time) + local bx = x + bubble.x + local by = y + bubble.y + osc + love.graphics.draw(bubble.image, bx, by, 0, 1, 1, 70, 70) + + draw_text(bx, by) + end + + local function draw_inspector() + local x, y = inspector.x, inspector.y + local ox, oy = inspector.img_w / 2, inspector.img_h / 2 + draw_background(x, y) + love.graphics.setColor(255, 255, 255, 255) + love.graphics.setBlendMode("alpha") + love.graphics.draw(inspector.image, x, y, 0, 1, 1, ox, oy) + draw_bubble(x, y) + end + function love.draw() - love.graphics.setBackgroundColor(254, 224, 238) - draw_hearts() - draw_pig(pig) + love.graphics.setColor(255, 255, 255) + + draw_grid() + draw_inspector() end function love.keyreleased(key) @@ -689,6 +1497,7 @@ function love.nogame() t.modules.sound = false t.modules.physics = false t.modules.joystick = false + t.window.resizable = true end end @@ -707,22 +1516,39 @@ function love.errhand(msg) error_printer(msg, 2) - if not love.graphics or not love.event or not love.graphics.isCreated() then + if not love.window or not love.graphics or not love.event then return end - -- Load. + if not love.graphics.isCreated() or not love.window.isCreated() then + local success, status = pcall(love.window.setMode, 800, 600) + if not success or not status then + return + end + end + + -- Reset state. + if love.mouse then + love.mouse.setVisible(true) + love.mouse.setGrabbed(false) + end + if love.joystick then + -- Stop all joystick vibrations. + for i,v in ipairs(love.joystick.getJoysticks()) do + v:setVibration() + end + end if love.audio then love.audio.stop() end love.graphics.reset() love.graphics.setBackgroundColor(89, 157, 220) - local font = love.graphics.newFont(14) - love.graphics.setFont(font) + local font = love.graphics.setNewFont(14) love.graphics.setColor(255, 255, 255, 255) local trace = debug.traceback() love.graphics.clear() + love.graphics.origin() local err = {} @@ -747,76 +1573,29 @@ function love.errhand(msg) love.graphics.present() end - draw() - - local e, a, b, c while true do - e, a, b, c = love.event.wait() + love.event.pump() - if e == "quit" then - return - end - if e == "keypressed" and a == "escape" then - return + for e, a, b, c in love.event.poll() do + if e == "quit" then + return + end + if e == "keypressed" and a == "escape" then + return + end end draw() - end - -end - -function love.releaseerrhand(msg) - print("An error has occured, the game has been stopped.") - - if not love.graphics or not love.event or not love.graphics.isCreated() then - return - end - - love.graphics.setCanvas() - love.graphics.setShader() - - -- Load. - if love.audio then love.audio.stop() end - love.graphics.reset() - love.graphics.setBackgroundColor(89, 157, 220) - local font = love.graphics.newFont(14) - love.graphics.setFont(font) - - love.graphics.setColor(255, 255, 255, 255) - - love.graphics.clear() - - local err = {} - - p = string.format("An error has occured that caused %s to stop.\nYou can notify %s about this%s.", love._release.title or "this game", love._release.author or "the author", love._release.url and " at " .. love._release.url or "") - - local function draw() - love.graphics.clear() - love.graphics.printf(p, 70, 70, love.graphics.getWidth() - 70) - love.graphics.present() - end - - draw() - - local e, a, b, c - while true do - e, a, b, c = love.event.wait() - - if e == "quit" then - return + if love.timer then + love.timer.sleep(0.1) end - if e == "keypressed" and a == "escape" then - return - end - - draw() - end + end local function deferErrhand(...) - local handler = ((love._release and love.releaseerrhand) or love.errhand or error_printer) + local handler = love.errhand or error_printer return handler(...) end diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index d3666cde0..24349aacc 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -80,15 +80,12 @@ const unsigned char boot_lua[] = 0x6e, 0x2e, 0x0a, 0x2d, 0x2d, 0x5d, 0x5d, 0x0a, 0x2d, 0x2d, 0x20, 0x4d, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2e, 0x0a, - 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, - 0x6f, 0x76, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2e, 0x0a, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x28, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x22, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x74, 0x75, 0x70, 0x3a, 0x0a, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, - 0x2d, 0x2d, 0x20, 0x55, 0x6e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x3a, 0x0a, - 0x61, 0x72, 0x67, 0x76, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x5c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x2f, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, @@ -262,64 +259,142 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x62, 0x2c, 0x20, 0x75, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x70, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x62, 0x2c, 0x20, 0x75, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, + 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x62, 0x2c, 0x20, 0x75, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6b, 0x65, 0x79, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x62, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x72, 0x65, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, - 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, + 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x62, 0x29, + 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, + 0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x28, 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x65, 0x64, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x2c, 0x73, 0x2c, 0x6c, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x65, 0x64, 0x69, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, + 0x2e, 0x74, 0x65, 0x78, 0x74, 0x65, 0x64, 0x69, 0x74, 0x28, 0x74, 0x2c, 0x73, 0x2c, 0x6c, 0x29, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, - 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, - 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x29, 0x20, - 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, + 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, - 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, - 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, - 0x6b, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, - 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x6a, - 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x6b, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, - 0x6b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, - 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, - 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x6b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x61, 0x2c, 0x76, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, + 0x6b, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x61, 0x78, 0x69, 0x73, 0x28, + 0x6a, 0x2c, 0x61, 0x2c, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x68, 0x2c, 0x76, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, + 0x6b, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, + 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x61, 0x74, 0x28, 0x6a, 0x2c, + 0x68, 0x2c, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x72, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x61, 0x2c, 0x76, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, + 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, + 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x61, 0x78, 0x69, 0x73, 0x28, 0x6a, 0x2c, + 0x61, 0x2c, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, + 0x6b, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x65, + 0x64, 0x28, 0x6a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6a, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, + 0x6b, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x28, 0x6a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x66, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x28, 0x66, 0x29, 0x20, - 0x65, 0x6e, 0x64, 0x0a, + 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x28, 0x66, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x66, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, + 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x28, 0x66, 0x29, 0x20, 0x65, + 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x76, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, + 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x28, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x71, 0x75, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, + 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, 0x2c, + 0x20, 0x65, 0x72, 0x72, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x77, 0x2c, 0x20, 0x6f, 0x68, 0x2c, 0x20, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, - 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, - 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x2c, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, - 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x77, - 0x2c, 0x20, 0x68, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, + 0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x7d, 0x2c, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, @@ -333,6 +408,16 @@ const unsigned char boot_lua[] = 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x72, 0x69, + 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x73, 0x29, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x25, + 0x25, 0x78, 0x25, 0x78, 0x22, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x74, + 0x72, 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x68, + 0x61, 0x72, 0x28, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, 0x74, 0x72, 0x3a, 0x73, 0x75, + 0x62, 0x28, 0x32, 0x29, 0x2c, 0x20, 0x31, 0x36, 0x29, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x29, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x6e, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x62, 0x6f, 0x6f, 0x74, @@ -373,8 +458,8 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x31, 0x2c, 0x20, 0x37, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x2f, 0x2f, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x3a, 0x73, - 0x75, 0x62, 0x28, 0x38, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x20, 0x3d, 0x20, 0x75, 0x72, 0x69, 0x64, 0x65, 0x63, 0x6f, + 0x64, 0x65, 0x28, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x38, 0x29, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x65, 0x74, @@ -382,6 +467,18 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x28, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x3a, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x22, 0x5e, 0x28, 0x5b, 0x25, 0x2e, 0x5d, 0x2b, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x2d, + 0x2d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x22, 0x2e, + 0x22, 0x27, 0x73, 0x0a, + 0x09, 0x09, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x3a, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x22, 0x25, 0x2e, 0x28, 0x5b, 0x5e, 0x25, 0x2e, 0x5d, 0x2b, 0x29, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, + 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x3a, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x22, 0x25, 0x2e, 0x22, 0x2c, 0x20, 0x22, 0x5f, 0x22, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x22, 0x2e, 0x22, + 0x27, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x22, 0x5f, 0x22, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x6c, 0x65, 0x61, 0x66, 0x29, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x70, @@ -398,6 +495,9 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, + 0x65, 0x74, 0x46, 0x75, 0x73, 0x65, 0x64, 0x28, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6e, 0x6f, 0x67, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, @@ -417,17 +517,26 @@ const unsigned char boot_lua[] = 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x55, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x22, 0x2c, 0x0a, - 0x09, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x22, 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, - 0x64, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x0a, - 0x09, 0x09, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x38, 0x30, 0x30, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x36, 0x30, 0x30, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x22, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x22, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, @@ -444,15 +553,18 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x09, 0x6d, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2e, 0x0a, 0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, + 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2c, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x69, 0x74, 0x20, 0x61, @@ -482,18 +594,6 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, - 0x7b, 0x0a, - 0x09, 0x09, 0x09, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, - 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x55, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x63, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x75, 0x72, 0x6c, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x75, 0x72, 0x6c, 0x0a, - 0x09, 0x09, 0x7d, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -510,9 +610,11 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x22, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x2c, 0x0a, + 0x09, 0x09, 0x22, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x66, 0x6f, 0x6e, 0x74, 0x22, 0x2c, 0x0a, + 0x09, 0x09, 0x22, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x6d, 0x61, 0x74, 0x68, 0x22, 0x2c, 0x0a, 0x09, 0x09, 0x22, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x22, 0x2c, 0x0a, @@ -528,51 +630,65 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x74, 0x75, 0x70, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x68, - 0x65, 0x72, 0x65, 0x2e, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x73, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, - 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, - 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x20, + 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, - 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, - 0x6e, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x66, - 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x28, 0x63, 0x2e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x2e, 0x73, 0x63, - 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6e, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x7b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x63, - 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, - 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6e, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, - 0x6e, 0x2e, 0x66, 0x73, 0x61, 0x61, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, - 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x63, - 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, - 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x73, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x73, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, - 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, + 0x65, 0x28, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x74, 0x75, 0x70, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x68, + 0x65, 0x72, 0x65, 0x2e, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, + 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x0a, + 0x09, 0x09, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x63, 0x2e, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, + 0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x2e, 0x66, 0x73, 0x61, 0x61, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x2e, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x0a, + 0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, + 0x65, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, + 0x69, 0x74, 0x6c, 0x65, 0x28, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x63, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x2c, 0x20, 0x22, 0x49, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x63, 0x6f, 0x6e, 0x20, 0x69, 0x73, + 0x20, 0x73, 0x65, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2c, + 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x62, 0x65, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x21, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, + 0x49, 0x63, 0x6f, 0x6e, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x6e, 0x65, + 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x28, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x2e, 0x69, 0x63, 0x6f, 0x6e, 0x29, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, - 0x74, 0x43, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x4f, 0x75, 0x72, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x65, 0x70, 0x2c, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x74, 0x61, + 0x73, 0x74, 0x65, 0x70, 0x2c, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -582,17 +698,16 @@ const unsigned char boot_lua[] = 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, - 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x28, 0x63, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, - 0x73, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61, - 0x6d, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2e, 0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x2e, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x2e, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, + 0x29, 0x2c, 0x20, 0x63, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6c, 0x75, - 0x61, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, - 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x61, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -604,13 +719,6 @@ const unsigned char boot_lua[] = 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x70, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x7a, 0x69, 0x70, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, - 0x65, 0x28, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x61, @@ -642,51 +750,79 @@ const unsigned char boot_lua[] = 0x6e, 0x6f, 0x72, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x73, 0x67, 0x20, 0x3d, 0x20, 0x22, 0x54, 0x68, 0x69, 0x73, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x61, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, - 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x70, - 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x2e, 0x5c, 0x6e, 0x22, 0x2e, 0x2e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x22, 0x54, 0x68, 0x65, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, - 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, - 0x65, 0x64, 0x2e, 0x5c, 0x6e, 0x22, 0x20, 0x2e, 0x2e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x22, 0x46, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6d, 0x6f, 0x72, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x73, 0x68, 0x6f, - 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6a, 0x75, 0x64, 0x67, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, - 0x20, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x2e, 0x22, 0x0a, + 0x6f, 0x72, 0x20, 0x61, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x4c, 0xc3, 0x96, 0x56, 0x45, 0x2e, 0x5c, 0x6e, 0x22, 0x2e, + 0x2e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x22, 0x49, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x22, 0x2e, 0x2e, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x2e, 0x22, 0x29, 0x2e, 0x22, 0x0a, 0x09, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x68, 0x61, 0x73, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, - 0x70, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x73, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x63, + 0x61, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, + 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, + 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 0x39, 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, - 0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x73, 0x67, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x37, 0x30, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, - 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, + 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, + 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, + 0x65, 0x72, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x3c, 0x20, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x20, 0x2b, 0x20, 0x34, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, + 0x6d, 0x70, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, + 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, + 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x73, 0x67, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x37, 0x30, + 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, + 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, + 0x65, 0x65, 0x70, 0x28, 0x31, 0x2f, 0x32, 0x30, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, - 0x65, 0x70, 0x28, 0x33, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x28, 0x29, 0x0a, - 0x09, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x73, 0x65, 0x65, 0x64, 0x28, 0x6f, - 0x73, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x29, 0x0a, - 0x09, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x6d, 0x61, 0x74, - 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x61, 0x6e, + 0x64, 0x6f, 0x6d, 0x53, 0x65, 0x65, 0x64, 0x28, 0x6f, 0x73, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, + 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x61, 0x72, 0x67, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x65, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x27, 0x73, 0x20, + 0x64, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x20, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, + 0x64, 0x2e, 0x0a, + 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, 0x74, 0x65, 0x70, 0x28, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x0a, @@ -734,16 +870,19 @@ const unsigned char boot_lua[] = 0x29, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x73, 0x73, 0x20, 0x30, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x73, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, 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, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 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, - 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, @@ -760,843 +899,3904 @@ const unsigned char boot_lua[] = 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6e, 0x6f, 0x67, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x67, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x0a, - 0x09, 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, - 0x4e, 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x43, - 0x41, 0x59, 0x41, 0x41, 0x41, 0x42, 0x63, 0x63, 0x71, 0x68, 0x6d, 0x41, 0x41, 0x41, 0x41, 0x47, 0x58, 0x52, - 0x46, 0x57, 0x48, 0x52, 0x54, 0x62, 0x32, 0x5a, 0x30, 0x64, 0x32, 0x46, 0x79, 0x5a, 0x51, 0x42, 0x42, 0x5a, - 0x47, 0x39, 0x69, 0x5a, 0x53, 0x42, 0x4a, 0x5c, 0x0a, - 0x09, 0x09, 0x62, 0x57, 0x46, 0x6e, 0x5a, 0x56, 0x4a, 0x6c, 0x59, 0x57, 0x52, 0x35, 0x63, 0x63, 0x6c, 0x6c, - 0x50, 0x41, 0x41, 0x41, 0x41, 0x79, 0x42, 0x70, 0x56, 0x46, 0x68, 0x30, 0x57, 0x45, 0x31, 0x4d, 0x4f, 0x6d, - 0x4e, 0x76, 0x62, 0x53, 0x35, 0x68, 0x5a, 0x47, 0x39, 0x69, 0x5a, 0x53, 0x35, 0x34, 0x62, 0x58, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x44, 0x77, 0x2f, 0x65, 0x48, 0x42, 0x68, 0x59, 0x32, 0x74, 0x6c, 0x64, 0x43, - 0x42, 0x69, 0x5a, 0x57, 0x64, 0x70, 0x5c, 0x0a, - 0x09, 0x09, 0x62, 0x6a, 0x30, 0x69, 0x37, 0x37, 0x75, 0x2f, 0x49, 0x69, 0x42, 0x70, 0x5a, 0x44, 0x30, 0x69, - 0x56, 0x7a, 0x56, 0x4e, 0x4d, 0x45, 0x31, 0x77, 0x51, 0x32, 0x56, 0x6f, 0x61, 0x55, 0x68, 0x36, 0x63, 0x6d, - 0x56, 0x54, 0x65, 0x6b, 0x35, 0x55, 0x59, 0x33, 0x70, 0x72, 0x59, 0x7a, 0x6c, 0x6b, 0x49, 0x6a, 0x38, 0x2b, - 0x49, 0x44, 0x78, 0x34, 0x4f, 0x6e, 0x68, 0x74, 0x63, 0x47, 0x31, 0x6c, 0x64, 0x47, 0x45, 0x67, 0x65, 0x47, - 0x31, 0x73, 0x62, 0x6e, 0x4d, 0x36, 0x5c, 0x0a, - 0x09, 0x09, 0x65, 0x44, 0x30, 0x69, 0x59, 0x57, 0x52, 0x76, 0x59, 0x6d, 0x55, 0x36, 0x62, 0x6e, 0x4d, 0x36, - 0x62, 0x57, 0x56, 0x30, 0x59, 0x53, 0x38, 0x69, 0x49, 0x48, 0x67, 0x36, 0x65, 0x47, 0x31, 0x77, 0x64, 0x47, - 0x73, 0x39, 0x49, 0x6b, 0x46, 0x6b, 0x62, 0x32, 0x4a, 0x6c, 0x49, 0x46, 0x68, 0x4e, 0x55, 0x43, 0x42, 0x44, - 0x62, 0x33, 0x4a, 0x6c, 0x49, 0x44, 0x55, 0x75, 0x4d, 0x43, 0x31, 0x6a, 0x4d, 0x44, 0x59, 0x77, 0x49, 0x44, - 0x59, 0x78, 0x4c, 0x6a, 0x45, 0x7a, 0x5c, 0x0a, - 0x09, 0x09, 0x4e, 0x44, 0x63, 0x33, 0x4e, 0x79, 0x77, 0x67, 0x4d, 0x6a, 0x41, 0x78, 0x4d, 0x43, 0x38, 0x77, - 0x4d, 0x69, 0x38, 0x78, 0x4d, 0x69, 0x30, 0x78, 0x4e, 0x7a, 0x6f, 0x7a, 0x4d, 0x6a, 0x6f, 0x77, 0x4d, 0x43, - 0x41, 0x67, 0x49, 0x43, 0x41, 0x67, 0x49, 0x43, 0x41, 0x67, 0x49, 0x6a, 0x34, 0x67, 0x50, 0x48, 0x4a, 0x6b, - 0x5a, 0x6a, 0x70, 0x53, 0x52, 0x45, 0x59, 0x67, 0x65, 0x47, 0x31, 0x73, 0x62, 0x6e, 0x4d, 0x36, 0x63, 0x6d, - 0x52, 0x6d, 0x50, 0x53, 0x4a, 0x6f, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x63, 0x7a, - 0x4c, 0x6d, 0x39, 0x79, 0x5a, 0x79, 0x38, 0x78, 0x4f, 0x54, 0x6b, 0x35, 0x4c, 0x7a, 0x41, 0x79, 0x4c, 0x7a, - 0x49, 0x79, 0x4c, 0x58, 0x4a, 0x6b, 0x5a, 0x69, 0x31, 0x7a, 0x65, 0x57, 0x35, 0x30, 0x59, 0x58, 0x67, 0x74, - 0x62, 0x6e, 0x4d, 0x6a, 0x49, 0x6a, 0x34, 0x67, 0x50, 0x48, 0x4a, 0x6b, 0x5a, 0x6a, 0x70, 0x45, 0x5a, 0x58, - 0x4e, 0x6a, 0x63, 0x6d, 0x6c, 0x77, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x79, 0x5a, 0x47, 0x59, 0x36, 0x59, 0x57, 0x4a, 0x76, - 0x64, 0x58, 0x51, 0x39, 0x49, 0x69, 0x49, 0x67, 0x65, 0x47, 0x31, 0x73, 0x62, 0x6e, 0x4d, 0x36, 0x65, 0x47, - 0x31, 0x77, 0x50, 0x53, 0x4a, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x62, 0x6e, 0x4d, 0x75, - 0x59, 0x57, 0x52, 0x76, 0x59, 0x6d, 0x55, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x33, 0x68, 0x68, 0x63, 0x43, - 0x38, 0x78, 0x4c, 0x6a, 0x41, 0x76, 0x5c, 0x0a, - 0x09, 0x09, 0x49, 0x69, 0x42, 0x34, 0x62, 0x57, 0x78, 0x75, 0x63, 0x7a, 0x70, 0x34, 0x62, 0x58, 0x42, 0x4e, - 0x54, 0x54, 0x30, 0x69, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32, 0x35, 0x7a, 0x4c, 0x6d, - 0x46, 0x6b, 0x62, 0x32, 0x4a, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x34, 0x59, 0x58, 0x41, 0x76, - 0x4d, 0x53, 0x34, 0x77, 0x4c, 0x32, 0x31, 0x74, 0x4c, 0x79, 0x49, 0x67, 0x65, 0x47, 0x31, 0x73, 0x62, 0x6e, - 0x4d, 0x36, 0x63, 0x33, 0x52, 0x53, 0x5c, 0x0a, - 0x09, 0x09, 0x5a, 0x57, 0x59, 0x39, 0x49, 0x6d, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x75, - 0x63, 0x79, 0x35, 0x68, 0x5a, 0x47, 0x39, 0x69, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x76, 0x65, 0x47, - 0x46, 0x77, 0x4c, 0x7a, 0x45, 0x75, 0x4d, 0x43, 0x39, 0x7a, 0x56, 0x48, 0x6c, 0x77, 0x5a, 0x53, 0x39, 0x53, - 0x5a, 0x58, 0x4e, 0x76, 0x64, 0x58, 0x4a, 0x6a, 0x5a, 0x56, 0x4a, 0x6c, 0x5a, 0x69, 0x4d, 0x69, 0x49, 0x48, - 0x68, 0x74, 0x63, 0x44, 0x70, 0x44, 0x5c, 0x0a, - 0x09, 0x09, 0x63, 0x6d, 0x56, 0x68, 0x64, 0x47, 0x39, 0x79, 0x56, 0x47, 0x39, 0x76, 0x62, 0x44, 0x30, 0x69, - 0x51, 0x57, 0x52, 0x76, 0x59, 0x6d, 0x55, 0x67, 0x55, 0x47, 0x68, 0x76, 0x64, 0x47, 0x39, 0x7a, 0x61, 0x47, - 0x39, 0x77, 0x49, 0x45, 0x4e, 0x54, 0x4e, 0x53, 0x42, 0x58, 0x61, 0x57, 0x35, 0x6b, 0x62, 0x33, 0x64, 0x7a, - 0x49, 0x69, 0x42, 0x34, 0x62, 0x58, 0x42, 0x4e, 0x54, 0x54, 0x70, 0x4a, 0x62, 0x6e, 0x4e, 0x30, 0x59, 0x57, - 0x35, 0x6a, 0x5a, 0x55, 0x6c, 0x45, 0x5c, 0x0a, - 0x09, 0x09, 0x50, 0x53, 0x4a, 0x34, 0x62, 0x58, 0x41, 0x75, 0x61, 0x57, 0x6c, 0x6b, 0x4f, 0x6a, 0x64, 0x43, - 0x51, 0x54, 0x59, 0x78, 0x52, 0x45, 0x59, 0x78, 0x4f, 0x55, 0x51, 0x35, 0x52, 0x44, 0x45, 0x78, 0x52, 0x54, - 0x42, 0x42, 0x4e, 0x6a, 0x59, 0x34, 0x52, 0x54, 0x63, 0x31, 0x4e, 0x45, 0x56, 0x45, 0x51, 0x54, 0x55, 0x31, - 0x4d, 0x45, 0x52, 0x44, 0x49, 0x69, 0x42, 0x34, 0x62, 0x58, 0x42, 0x4e, 0x54, 0x54, 0x70, 0x45, 0x62, 0x32, - 0x4e, 0x31, 0x62, 0x57, 0x56, 0x75, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x45, 0x6c, 0x45, 0x50, 0x53, 0x4a, 0x34, 0x62, 0x58, 0x41, 0x75, 0x5a, 0x47, 0x6c, 0x6b, - 0x4f, 0x6a, 0x64, 0x43, 0x51, 0x54, 0x59, 0x78, 0x52, 0x45, 0x59, 0x79, 0x4f, 0x55, 0x51, 0x35, 0x52, 0x44, - 0x45, 0x78, 0x52, 0x54, 0x42, 0x42, 0x4e, 0x6a, 0x59, 0x34, 0x52, 0x54, 0x63, 0x31, 0x4e, 0x45, 0x56, 0x45, - 0x51, 0x54, 0x55, 0x31, 0x4d, 0x45, 0x52, 0x44, 0x49, 0x6a, 0x34, 0x67, 0x50, 0x48, 0x68, 0x74, 0x63, 0x45, - 0x31, 0x4e, 0x4f, 0x6b, 0x52, 0x6c, 0x5c, 0x0a, - 0x09, 0x09, 0x63, 0x6d, 0x6c, 0x32, 0x5a, 0x57, 0x52, 0x47, 0x63, 0x6d, 0x39, 0x74, 0x49, 0x48, 0x4e, 0x30, - 0x55, 0x6d, 0x56, 0x6d, 0x4f, 0x6d, 0x6c, 0x75, 0x63, 0x33, 0x52, 0x68, 0x62, 0x6d, 0x4e, 0x6c, 0x53, 0x55, - 0x51, 0x39, 0x49, 0x6e, 0x68, 0x74, 0x63, 0x43, 0x35, 0x70, 0x61, 0x57, 0x51, 0x36, 0x4e, 0x30, 0x4a, 0x42, - 0x4e, 0x6a, 0x46, 0x45, 0x52, 0x55, 0x59, 0x35, 0x52, 0x44, 0x6c, 0x45, 0x4d, 0x54, 0x46, 0x46, 0x4d, 0x45, - 0x45, 0x32, 0x4e, 0x6a, 0x68, 0x46, 0x5c, 0x0a, - 0x09, 0x09, 0x4e, 0x7a, 0x55, 0x30, 0x52, 0x55, 0x52, 0x42, 0x4e, 0x54, 0x55, 0x77, 0x52, 0x45, 0x4d, 0x69, - 0x49, 0x48, 0x4e, 0x30, 0x55, 0x6d, 0x56, 0x6d, 0x4f, 0x6d, 0x52, 0x76, 0x59, 0x33, 0x56, 0x74, 0x5a, 0x57, - 0x35, 0x30, 0x53, 0x55, 0x51, 0x39, 0x49, 0x6e, 0x68, 0x74, 0x63, 0x43, 0x35, 0x6b, 0x61, 0x57, 0x51, 0x36, - 0x4e, 0x30, 0x4a, 0x42, 0x4e, 0x6a, 0x46, 0x45, 0x52, 0x6a, 0x41, 0x35, 0x52, 0x44, 0x6c, 0x45, 0x4d, 0x54, - 0x46, 0x46, 0x4d, 0x45, 0x45, 0x32, 0x5c, 0x0a, - 0x09, 0x09, 0x4e, 0x6a, 0x68, 0x46, 0x4e, 0x7a, 0x55, 0x30, 0x52, 0x55, 0x52, 0x42, 0x4e, 0x54, 0x55, 0x77, - 0x52, 0x45, 0x4d, 0x69, 0x4c, 0x7a, 0x34, 0x67, 0x50, 0x43, 0x39, 0x79, 0x5a, 0x47, 0x59, 0x36, 0x52, 0x47, - 0x56, 0x7a, 0x59, 0x33, 0x4a, 0x70, 0x63, 0x48, 0x52, 0x70, 0x62, 0x32, 0x34, 0x2b, 0x49, 0x44, 0x77, 0x76, - 0x63, 0x6d, 0x52, 0x6d, 0x4f, 0x6c, 0x4a, 0x45, 0x52, 0x6a, 0x34, 0x67, 0x50, 0x43, 0x39, 0x34, 0x4f, 0x6e, - 0x68, 0x74, 0x63, 0x47, 0x31, 0x6c, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x47, 0x45, 0x2b, 0x49, 0x44, 0x77, 0x2f, 0x65, 0x48, 0x42, 0x68, 0x59, 0x32, 0x74, 0x6c, - 0x64, 0x43, 0x42, 0x6c, 0x62, 0x6d, 0x51, 0x39, 0x49, 0x6e, 0x49, 0x69, 0x50, 0x7a, 0x36, 0x67, 0x52, 0x47, - 0x75, 0x7a, 0x41, 0x41, 0x41, 0x59, 0x58, 0x6b, 0x6c, 0x45, 0x51, 0x56, 0x52, 0x34, 0x32, 0x75, 0x79, 0x64, - 0x58, 0x32, 0x68, 0x63, 0x56, 0x33, 0x37, 0x48, 0x7a, 0x34, 0x78, 0x6b, 0x65, 0x54, 0x64, 0x78, 0x4e, 0x72, - 0x49, 0x54, 0x6b, 0x70, 0x42, 0x6b, 0x5c, 0x0a, - 0x09, 0x09, 0x30, 0x2f, 0x45, 0x6d, 0x67, 0x57, 0x78, 0x4c, 0x62, 0x4b, 0x6c, 0x68, 0x79, 0x5a, 0x5a, 0x43, - 0x50, 0x59, 0x4a, 0x74, 0x53, 0x77, 0x33, 0x46, 0x55, 0x70, 0x65, 0x2b, 0x46, 0x54, 0x7a, 0x7a, 0x73, 0x47, - 0x39, 0x4c, 0x4c, 0x64, 0x46, 0x43, 0x48, 0x32, 0x57, 0x39, 0x46, 0x7a, 0x77, 0x75, 0x66, 0x65, 0x75, 0x44, - 0x52, 0x74, 0x44, 0x58, 0x34, 0x74, 0x47, 0x4c, 0x53, 0x30, 0x74, 0x42, 0x6f, 0x30, 0x49, 0x70, 0x53, 0x31, - 0x73, 0x38, 0x54, 0x6d, 0x6b, 0x33, 0x5c, 0x0a, - 0x09, 0x09, 0x53, 0x39, 0x78, 0x34, 0x6b, 0x6e, 0x69, 0x58, 0x65, 0x4d, 0x6e, 0x4b, 0x6b, 0x37, 0x2f, 0x65, - 0x57, 0x4c, 0x4c, 0x55, 0x38, 0x37, 0x76, 0x7a, 0x75, 0x39, 0x4c, 0x56, 0x2f, 0x4c, 0x2f, 0x33, 0x6e, 0x6e, - 0x50, 0x76, 0x37, 0x39, 0x7a, 0x37, 0x2f, 0x63, 0x42, 0x6c, 0x46, 0x45, 0x63, 0x6a, 0x6a, 0x63, 0x34, 0x35, - 0x76, 0x2b, 0x2f, 0x35, 0x2f, 0x73, 0x37, 0x66, 0x77, 0x73, 0x48, 0x42, 0x67, 0x51, 0x49, 0x41, 0x35, 0x4a, - 0x4d, 0x69, 0x69, 0x67, 0x41, 0x41, 0x5c, 0x0a, - 0x09, 0x09, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x67, - 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x67, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, - 0x41, 0x44, 0x44, 0x42, 0x64, 0x4e, 0x67, 0x33, 0x46, 0x41, 0x6f, 0x46, 0x61, 0x78, 0x2b, 0x6d, 0x38, 0x39, - 0x66, 0x2f, 0x58, 0x4e, 0x59, 0x76, 0x5c, 0x0a, - 0x09, 0x09, 0x39, 0x4a, 0x7a, 0x58, 0x7a, 0x36, 0x78, 0x2b, 0x35, 0x76, 0x69, 0x56, 0x61, 0x50, 0x4a, 0x72, - 0x53, 0x7a, 0x38, 0x66, 0x30, 0x4f, 0x76, 0x73, 0x58, 0x2f, 0x35, 0x42, 0x45, 0x31, 0x55, 0x49, 0x51, 0x44, - 0x2b, 0x54, 0x33, 0x76, 0x6c, 0x5a, 0x43, 0x48, 0x73, 0x35, 0x71, 0x47, 0x6b, 0x42, 0x30, 0x45, 0x46, 0x50, - 0x41, 0x62, 0x36, 0x73, 0x6e, 0x38, 0x76, 0x36, 0x4b, 0x59, 0x56, 0x39, 0x4f, 0x77, 0x76, 0x44, 0x70, 0x6e, - 0x34, 0x61, 0x57, 0x68, 0x41, 0x36, 0x5c, 0x0a, - 0x09, 0x09, 0x71, 0x48, 0x6f, 0x41, 0x48, 0x42, 0x45, 0x41, 0x48, 0x66, 0x77, 0x55, 0x2b, 0x4b, 0x75, 0x42, - 0x58, 0x6a, 0x34, 0x75, 0x44, 0x66, 0x31, 0x73, 0x61, 0x43, 0x46, 0x6f, 0x6f, 0x41, 0x6b, 0x41, 0x43, 0x49, - 0x42, 0x51, 0x41, 0x65, 0x42, 0x65, 0x2f, 0x77, 0x62, 0x62, 0x66, 0x52, 0x75, 0x30, 0x39, 0x58, 0x4e, 0x64, - 0x50, 0x33, 0x57, 0x34, 0x41, 0x67, 0x41, 0x42, 0x45, 0x43, 0x51, 0x41, 0x48, 0x50, 0x78, 0x62, 0x6e, 0x4e, - 0x2f, 0x62, 0x70, 0x73, 0x4e, 0x43, 0x5c, 0x0a, - 0x09, 0x09, 0x55, 0x49, 0x4d, 0x51, 0x41, 0x41, 0x68, 0x41, 0x50, 0x34, 0x6e, 0x4f, 0x41, 0x69, 0x51, 0x63, - 0x2f, 0x49, 0x70, 0x54, 0x43, 0x30, 0x6f, 0x78, 0x37, 0x75, 0x72, 0x66, 0x66, 0x52, 0x58, 0x4e, 0x41, 0x6f, - 0x41, 0x55, 0x48, 0x59, 0x41, 0x4f, 0x77, 0x69, 0x32, 0x4c, 0x74, 0x6e, 0x2f, 0x53, 0x31, 0x47, 0x41, 0x46, - 0x59, 0x77, 0x51, 0x67, 0x4c, 0x58, 0x69, 0x6d, 0x69, 0x32, 0x6a, 0x5a, 0x64, 0x4b, 0x58, 0x69, 0x55, 0x67, - 0x44, 0x75, 0x67, 0x56, 0x65, 0x46, 0x5c, 0x0a, - 0x09, 0x09, 0x31, 0x45, 0x4e, 0x54, 0x50, 0x31, 0x56, 0x64, 0x41, 0x57, 0x30, 0x30, 0x53, 0x57, 0x41, 0x67, - 0x71, 0x4d, 0x6e, 0x52, 0x6c, 0x74, 0x6a, 0x5a, 0x50, 0x68, 0x31, 0x77, 0x75, 0x4d, 0x46, 0x70, 0x37, 0x48, - 0x47, 0x30, 0x4f, 0x47, 0x58, 0x31, 0x70, 0x37, 0x6d, 0x62, 0x75, 0x6e, 0x32, 0x32, 0x4d, 0x69, 0x45, 0x41, - 0x72, 0x48, 0x70, 0x62, 0x41, 0x75, 0x74, 0x75, 0x54, 0x52, 0x63, 0x79, 0x55, 0x67, 0x4d, 0x51, 0x4a, 0x6f, - 0x57, 0x64, 0x55, 0x30, 0x64, 0x72, 0x5c, 0x0a, - 0x09, 0x09, 0x56, 0x55, 0x71, 0x57, 0x30, 0x39, 0x6e, 0x49, 0x30, 0x39, 0x7a, 0x53, 0x42, 0x4f, 0x42, 0x57, - 0x67, 0x6e, 0x6c, 0x2f, 0x57, 0x46, 0x72, 0x73, 0x42, 0x6c, 0x70, 0x6f, 0x34, 0x71, 0x43, 0x6e, 0x33, 0x5a, - 0x59, 0x34, 0x32, 0x43, 0x39, 0x77, 0x2b, 0x30, 0x32, 0x7a, 0x44, 0x56, 0x50, 0x77, 0x4e, 0x37, 0x6a, 0x54, - 0x61, 0x6a, 0x73, 0x6a, 0x41, 0x4c, 0x6f, 0x51, 0x4b, 0x2f, 0x70, 0x6c, 0x33, 0x59, 0x48, 0x36, 0x68, 0x68, - 0x74, 0x41, 0x77, 0x46, 0x4d, 0x50, 0x5c, 0x0a, - 0x09, 0x09, 0x76, 0x38, 0x67, 0x42, 0x58, 0x31, 0x62, 0x68, 0x46, 0x36, 0x59, 0x6c, 0x52, 0x59, 0x33, 0x62, - 0x61, 0x38, 0x63, 0x46, 0x41, 0x62, 0x67, 0x72, 0x75, 0x43, 0x41, 0x48, 0x75, 0x59, 0x45, 0x6c, 0x6c, 0x38, - 0x63, 0x47, 0x64, 0x69, 0x37, 0x57, 0x5a, 0x67, 0x66, 0x30, 0x56, 0x4f, 0x57, 0x59, 0x50, 0x55, 0x2f, 0x51, - 0x48, 0x58, 0x58, 0x4f, 0x33, 0x46, 0x78, 0x75, 0x5a, 0x53, 0x6a, 0x6f, 0x35, 0x7a, 0x6a, 0x6f, 0x4c, 0x77, - 0x6c, 0x32, 0x71, 0x59, 0x4e, 0x6f, 0x5c, 0x0a, - 0x09, 0x09, 0x73, 0x33, 0x4e, 0x74, 0x69, 0x68, 0x55, 0x41, 0x68, 0x33, 0x72, 0x2f, 0x33, 0x67, 0x5a, 0x66, - 0x6c, 0x54, 0x68, 0x54, 0x6f, 0x49, 0x50, 0x62, 0x48, 0x31, 0x54, 0x79, 0x58, 0x2f, 0x30, 0x39, 0x45, 0x37, - 0x4d, 0x70, 0x4e, 0x64, 0x36, 0x67, 0x4f, 0x4e, 0x44, 0x72, 0x70, 0x79, 0x6f, 0x77, 0x6d, 0x4b, 0x57, 0x46, - 0x6f, 0x69, 0x4d, 0x34, 0x36, 0x43, 0x39, 0x7a, 0x34, 0x4a, 0x65, 0x55, 0x32, 0x31, 0x42, 0x62, 0x72, 0x55, - 0x73, 0x56, 0x67, 0x4c, 0x73, 0x4f, 0x5c, 0x0a, - 0x09, 0x09, 0x46, 0x7a, 0x41, 0x74, 0x48, 0x6c, 0x70, 0x4a, 0x4b, 0x64, 0x42, 0x39, 0x2b, 0x31, 0x6c, 0x69, - 0x4f, 0x31, 0x70, 0x79, 0x75, 0x42, 0x79, 0x62, 0x4c, 0x41, 0x69, 0x33, 0x57, 0x52, 0x78, 0x49, 0x47, 0x4e, - 0x6f, 0x49, 0x65, 0x72, 0x73, 0x69, 0x6b, 0x4c, 0x6f, 0x41, 0x43, 0x42, 0x37, 0x35, 0x44, 0x35, 0x73, 0x53, - 0x4c, 0x4e, 0x69, 0x63, 0x72, 0x2b, 0x56, 0x67, 0x6e, 0x2b, 0x50, 0x65, 0x50, 0x4f, 0x32, 0x42, 0x70, 0x71, - 0x53, 0x46, 0x6f, 0x65, 0x55, 0x4c, 0x5c, 0x0a, - 0x09, 0x09, 0x67, 0x34, 0x32, 0x30, 0x67, 0x67, 0x66, 0x78, 0x72, 0x6d, 0x51, 0x30, 0x36, 0x48, 0x75, 0x5a, - 0x44, 0x77, 0x35, 0x6b, 0x53, 0x78, 0x41, 0x41, 0x73, 0x76, 0x36, 0x56, 0x4c, 0x4b, 0x53, 0x4a, 0x4c, 0x41, - 0x49, 0x74, 0x41, 0x38, 0x45, 0x2b, 0x71, 0x34, 0x35, 0x47, 0x6c, 0x63, 0x73, 0x35, 0x43, 0x76, 0x59, 0x77, - 0x36, 0x63, 0x51, 0x32, 0x69, 0x59, 0x4d, 0x57, 0x68, 0x47, 0x62, 0x45, 0x6f, 0x50, 0x63, 0x48, 0x38, 0x71, - 0x37, 0x6b, 0x72, 0x48, 0x7a, 0x62, 0x5c, 0x0a, - 0x09, 0x09, 0x75, 0x6f, 0x32, 0x65, 0x6c, 0x53, 0x51, 0x41, 0x44, 0x35, 0x53, 0x35, 0x58, 0x58, 0x34, 0x53, - 0x47, 0x75, 0x66, 0x4b, 0x6f, 0x46, 0x77, 0x4c, 0x41, 0x57, 0x2f, 0x64, 0x4a, 0x57, 0x79, 0x79, 0x49, 0x4c, - 0x51, 0x6d, 0x44, 0x48, 0x36, 0x62, 0x6d, 0x38, 0x79, 0x6b, 0x63, 0x7a, 0x69, 0x54, 0x6c, 0x61, 0x6f, 0x41, - 0x36, 0x49, 0x70, 0x59, 0x35, 0x49, 0x72, 0x49, 0x56, 0x47, 0x50, 0x55, 0x68, 0x62, 0x73, 0x77, 0x51, 0x64, - 0x44, 0x37, 0x43, 0x30, 0x55, 0x75, 0x5c, 0x0a, - 0x09, 0x09, 0x35, 0x62, 0x67, 0x68, 0x32, 0x68, 0x4c, 0x68, 0x42, 0x6a, 0x75, 0x45, 0x78, 0x71, 0x67, 0x42, - 0x78, 0x6f, 0x44, 0x31, 0x72, 0x32, 0x53, 0x6f, 0x45, 0x35, 0x71, 0x6f, 0x6a, 0x48, 0x51, 0x62, 0x50, 0x53, - 0x31, 0x42, 0x41, 0x4c, 0x4a, 0x69, 0x2f, 0x34, 0x6d, 0x36, 0x47, 0x72, 0x50, 0x34, 0x67, 0x6f, 0x4d, 0x2b, - 0x71, 0x77, 0x4e, 0x4d, 0x55, 0x6d, 0x6b, 0x45, 0x33, 0x45, 0x46, 0x37, 0x52, 0x46, 0x75, 0x73, 0x63, 0x4e, - 0x33, 0x6b, 0x52, 0x59, 0x79, 0x39, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x63, 0x47, 0x30, 0x42, 0x63, 0x42, 0x31, 0x2b, 0x2b, 0x39, 0x76, 0x49, 0x36, 0x34, 0x50, - 0x43, 0x33, 0x77, 0x45, 0x76, 0x62, 0x68, 0x55, 0x59, 0x57, 0x4f, 0x55, 0x4d, 0x2b, 0x42, 0x5a, 0x67, 0x43, - 0x73, 0x5a, 0x36, 0x70, 0x69, 0x47, 0x43, 0x71, 0x4e, 0x75, 0x73, 0x30, 0x75, 0x70, 0x43, 0x51, 0x41, 0x58, - 0x39, 0x43, 0x33, 0x48, 0x41, 0x33, 0x2f, 0x67, 0x2b, 0x51, 0x45, 0x36, 0x36, 0x45, 0x76, 0x71, 0x61, 0x49, - 0x41, 0x4a, 0x51, 0x53, 0x2f, 0x58, 0x5c, 0x0a, - 0x09, 0x09, 0x47, 0x57, 0x78, 0x6f, 0x49, 0x57, 0x69, 0x4d, 0x53, 0x41, 0x38, 0x71, 0x58, 0x49, 0x65, 0x5a, - 0x54, 0x41, 0x39, 0x30, 0x32, 0x79, 0x32, 0x6b, 0x4b, 0x51, 0x42, 0x30, 0x7a, 0x4e, 0x65, 0x31, 0x6a, 0x41, - 0x58, 0x2b, 0x59, 0x71, 0x43, 0x33, 0x42, 0x2b, 0x37, 0x55, 0x4b, 0x61, 0x56, 0x76, 0x31, 0x77, 0x65, 0x6c, - 0x43, 0x44, 0x48, 0x50, 0x6f, 0x70, 0x54, 0x4f, 0x77, 0x74, 0x4e, 0x2f, 0x38, 0x66, 0x76, 0x4e, 0x74, 0x41, - 0x54, 0x41, 0x70, 0x66, 0x78, 0x2f, 0x5c, 0x0a, - 0x09, 0x09, 0x61, 0x4f, 0x42, 0x7a, 0x62, 0x31, 0x2f, 0x4a, 0x61, 0x41, 0x50, 0x4a, 0x5a, 0x59, 0x71, 0x67, - 0x68, 0x61, 0x41, 0x2b, 0x59, 0x70, 0x78, 0x67, 0x4e, 0x55, 0x50, 0x31, 0x76, 0x4b, 0x49, 0x46, 0x6f, 0x4a, - 0x61, 0x57, 0x41, 0x45, 0x6a, 0x65, 0x2b, 0x54, 0x64, 0x4a, 0x34, 0x4a, 0x63, 0x35, 0x36, 0x43, 0x75, 0x49, - 0x6d, 0x38, 0x7a, 0x52, 0x35, 0x72, 0x47, 0x43, 0x32, 0x71, 0x43, 0x78, 0x67, 0x67, 0x77, 0x4a, 0x51, 0x55, - 0x30, 0x4c, 0x77, 0x45, 0x70, 0x61, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x6e, 0x44, 0x67, 0x63, 0x4f, 0x42, 0x54, 0x35, 0x5a, 0x63, 0x52, 0x4a, 0x37, 0x6c, 0x49, - 0x44, 0x37, 0x79, 0x74, 0x74, 0x55, 0x50, 0x53, 0x67, 0x77, 0x71, 0x6e, 0x73, 0x61, 0x36, 0x4f, 0x45, 0x54, - 0x53, 0x31, 0x41, 0x43, 0x77, 0x6b, 0x4c, 0x67, 0x44, 0x43, 0x6c, 0x2f, 0x38, 0x4f, 0x33, 0x45, 0x4b, 0x70, - 0x41, 0x7a, 0x39, 0x72, 0x39, 0x67, 0x2b, 0x45, 0x6f, 0x7a, 0x35, 0x49, 0x43, 0x41, 0x4a, 0x6a, 0x42, 0x43, - 0x34, 0x4f, 0x46, 0x71, 0x59, 0x6d, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x42, 0x52, 0x4d, 0x36, 0x78, 0x49, 0x72, 0x75, 0x48, 0x63, 0x36, 0x44, 0x34, 0x45, 0x50, - 0x51, 0x67, 0x72, 0x42, 0x61, 0x68, 0x59, 0x46, 0x59, 0x4e, 0x72, 0x77, 0x4c, 0x35, 0x59, 0x55, 0x54, 0x45, - 0x33, 0x56, 0x58, 0x62, 0x37, 0x62, 0x47, 0x6d, 0x44, 0x31, 0x72, 0x79, 0x6b, 0x73, 0x79, 0x77, 0x58, 0x48, - 0x6f, 0x51, 0x36, 0x68, 0x6f, 0x74, 0x76, 0x48, 0x4d, 0x53, 0x46, 0x67, 0x78, 0x33, 0x68, 0x56, 0x43, 0x30, - 0x47, 0x64, 0x52, 0x61, 0x43, 0x53, 0x5c, 0x0a, - 0x09, 0x09, 0x70, 0x54, 0x2f, 0x61, 0x74, 0x41, 0x4e, 0x49, 0x2b, 0x39, 0x52, 0x66, 0x67, 0x69, 0x71, 0x75, - 0x37, 0x36, 0x41, 0x45, 0x35, 0x50, 0x67, 0x67, 0x4a, 0x47, 0x74, 0x71, 0x77, 0x47, 0x41, 0x68, 0x70, 0x37, - 0x6e, 0x53, 0x4f, 0x35, 0x43, 0x4a, 0x48, 0x55, 0x43, 0x57, 0x62, 0x67, 0x66, 0x32, 0x4e, 0x2b, 0x79, 0x63, - 0x44, 0x51, 0x59, 0x2f, 0x54, 0x65, 0x66, 0x70, 0x5a, 0x35, 0x33, 0x48, 0x4a, 0x68, 0x44, 0x38, 0x59, 0x46, - 0x4b, 0x38, 0x2b, 0x79, 0x51, 0x34, 0x5c, 0x0a, - 0x09, 0x09, 0x56, 0x54, 0x79, 0x45, 0x32, 0x70, 0x5a, 0x2b, 0x35, 0x71, 0x6d, 0x54, 0x34, 0x54, 0x62, 0x6e, - 0x4e, 0x4b, 0x59, 0x46, 0x49, 0x4b, 0x30, 0x41, 0x49, 0x33, 0x74, 0x47, 0x67, 0x56, 0x2f, 0x72, 0x36, 0x66, - 0x57, 0x76, 0x71, 0x75, 0x36, 0x71, 0x78, 0x41, 0x72, 0x61, 0x4d, 0x34, 0x67, 0x41, 0x35, 0x66, 0x2f, 0x72, - 0x75, 0x68, 0x33, 0x64, 0x59, 0x67, 0x63, 0x5a, 0x46, 0x41, 0x4b, 0x76, 0x7a, 0x61, 0x6e, 0x75, 0x34, 0x4c, - 0x4b, 0x7a, 0x54, 0x44, 0x74, 0x65, 0x5c, 0x0a, - 0x09, 0x09, 0x51, 0x61, 0x50, 0x73, 0x2f, 0x72, 0x72, 0x43, 0x41, 0x42, 0x38, 0x77, 0x41, 0x39, 0x6e, 0x39, - 0x4c, 0x52, 0x34, 0x66, 0x57, 0x50, 0x48, 0x54, 0x41, 0x68, 0x34, 0x66, 0x57, 0x4e, 0x46, 0x70, 0x77, 0x61, - 0x61, 0x77, 0x74, 0x4b, 0x43, 0x64, 0x75, 0x41, 0x50, 0x67, 0x4e, 0x64, 0x5a, 0x4a, 0x55, 0x68, 0x74, 0x67, - 0x39, 0x32, 0x66, 0x31, 0x63, 0x34, 0x33, 0x74, 0x50, 0x6f, 0x49, 0x66, 0x6d, 0x4b, 0x62, 0x43, 0x61, 0x63, - 0x48, 0x69, 0x6b, 0x4c, 0x52, 0x67, 0x5c, 0x0a, - 0x09, 0x09, 0x54, 0x63, 0x6a, 0x6e, 0x2f, 0x43, 0x43, 0x4e, 0x46, 0x43, 0x43, 0x70, 0x67, 0x50, 0x4e, 0x50, - 0x36, 0x46, 0x6e, 0x70, 0x36, 0x66, 0x57, 0x70, 0x55, 0x75, 0x67, 0x4d, 0x77, 0x6d, 0x57, 0x30, 0x55, 0x32, - 0x41, 0x35, 0x4c, 0x62, 0x69, 0x68, 0x32, 0x39, 0x73, 0x4e, 0x50, 0x76, 0x41, 0x6c, 0x4b, 0x41, 0x53, 0x55, - 0x63, 0x73, 0x36, 0x48, 0x36, 0x59, 0x45, 0x7a, 0x34, 0x77, 0x41, 0x53, 0x67, 0x71, 0x62, 0x30, 0x35, 0x6f, - 0x66, 0x30, 0x2b, 0x6a, 0x64, 0x55, 0x5c, 0x0a, - 0x09, 0x09, 0x76, 0x67, 0x35, 0x2f, 0x41, 0x4f, 0x6d, 0x79, 0x4f, 0x4d, 0x51, 0x4e, 0x74, 0x46, 0x67, 0x45, - 0x47, 0x68, 0x41, 0x41, 0x73, 0x39, 0x53, 0x35, 0x35, 0x32, 0x2f, 0x33, 0x35, 0x50, 0x71, 0x33, 0x30, 0x4f, - 0x73, 0x44, 0x53, 0x57, 0x36, 0x41, 0x78, 0x67, 0x5a, 0x6f, 0x54, 0x33, 0x35, 0x61, 0x4b, 0x63, 0x47, 0x77, - 0x75, 0x77, 0x4a, 0x73, 0x43, 0x30, 0x44, 0x5a, 0x34, 0x74, 0x39, 0x45, 0x30, 0x33, 0x76, 0x56, 0x34, 0x44, - 0x4a, 0x65, 0x48, 0x75, 0x46, 0x48, 0x5c, 0x0a, - 0x09, 0x09, 0x72, 0x67, 0x2b, 0x6b, 0x75, 0x49, 0x46, 0x62, 0x66, 0x45, 0x68, 0x4d, 0x62, 0x30, 0x71, 0x51, - 0x39, 0x48, 0x52, 0x68, 0x71, 0x50, 0x52, 0x44, 0x75, 0x67, 0x50, 0x77, 0x38, 0x2f, 0x31, 0x61, 0x6a, 0x2b, - 0x57, 0x6e, 0x77, 0x46, 0x39, 0x46, 0x75, 0x77, 0x4f, 0x43, 0x4b, 0x4c, 0x45, 0x49, 0x4c, 0x50, 0x65, 0x49, - 0x67, 0x4f, 0x64, 0x63, 0x45, 0x78, 0x53, 0x42, 0x56, 0x6c, 0x59, 0x45, 0x77, 0x44, 0x2b, 0x54, 0x50, 0x35, - 0x6a, 0x76, 0x6b, 0x38, 0x4c, 0x65, 0x5c, 0x0a, - 0x09, 0x09, 0x56, 0x56, 0x6a, 0x51, 0x41, 0x2b, 0x52, 0x79, 0x6a, 0x52, 0x61, 0x65, 0x39, 0x61, 0x51, 0x45, - 0x4c, 0x52, 0x61, 0x42, 0x64, 0x67, 0x4b, 0x2f, 0x66, 0x7a, 0x73, 0x4c, 0x41, 0x75, 0x41, 0x48, 0x66, 0x79, - 0x73, 0x51, 0x2f, 0x42, 0x58, 0x4f, 0x39, 0x7a, 0x48, 0x51, 0x42, 0x36, 0x52, 0x44, 0x62, 0x58, 0x57, 0x4c, - 0x44, 0x35, 0x55, 0x4a, 0x69, 0x73, 0x42, 0x38, 0x32, 0x42, 0x34, 0x36, 0x41, 0x6b, 0x33, 0x58, 0x42, 0x59, - 0x41, 0x4f, 0x34, 0x70, 0x7a, 0x76, 0x5c, 0x0a, - 0x09, 0x09, 0x79, 0x66, 0x64, 0x70, 0x55, 0x63, 0x38, 0x36, 0x32, 0x68, 0x56, 0x77, 0x69, 0x44, 0x6c, 0x4f, - 0x43, 0x63, 0x6f, 0x42, 0x45, 0x65, 0x69, 0x77, 0x45, 0x37, 0x41, 0x6c, 0x41, 0x70, 0x32, 0x77, 0x46, 0x39, - 0x67, 0x55, 0x42, 0x51, 0x5a, 0x2f, 0x74, 0x53, 0x66, 0x66, 0x76, 0x36, 0x47, 0x77, 0x6c, 0x42, 0x65, 0x34, - 0x79, 0x53, 0x77, 0x37, 0x67, 0x55, 0x70, 0x43, 0x49, 0x74, 0x41, 0x4d, 0x2b, 0x77, 0x5a, 0x4a, 0x41, 0x72, - 0x44, 0x57, 0x47, 0x2f, 0x79, 0x71, 0x5c, 0x0a, - 0x09, 0x09, 0x4f, 0x38, 0x71, 0x50, 0x67, 0x7a, 0x69, 0x42, 0x36, 0x36, 0x7a, 0x7a, 0x72, 0x4a, 0x56, 0x74, - 0x45, 0x64, 0x68, 0x32, 0x56, 0x51, 0x43, 0x71, 0x2f, 0x70, 0x56, 0x47, 0x48, 0x50, 0x78, 0x7a, 0x48, 0x50, - 0x7a, 0x59, 0x73, 0x77, 0x2b, 0x79, 0x77, 0x69, 0x71, 0x6e, 0x73, 0x6a, 0x5a, 0x46, 0x6f, 0x4f, 0x47, 0x69, - 0x41, 0x42, 0x79, 0x37, 0x32, 0x68, 0x6a, 0x42, 0x44, 0x7a, 0x4a, 0x4d, 0x78, 0x61, 0x49, 0x49, 0x74, 0x45, - 0x62, 0x64, 0x58, 0x69, 0x56, 0x56, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x49, 0x59, 0x46, 0x50, 0x30, 0x62, 0x36, 0x41, 0x55, 0x51, 0x67, 0x48, 0x42, 0x74, 0x52, - 0x33, 0x6c, 0x52, 0x45, 0x38, 0x41, 0x4f, 0x51, 0x43, 0x52, 0x46, 0x6f, 0x75, 0x43, 0x51, 0x41, 0x64, 0x51, - 0x51, 0x2f, 0x67, 0x41, 0x67, 0x59, 0x45, 0x34, 0x46, 0x49, 0x39, 0x6a, 0x38, 0x74, 0x41, 0x65, 0x69, 0x64, - 0x36, 0x6b, 0x50, 0x77, 0x41, 0x34, 0x6a, 0x41, 0x6b, 0x51, 0x6a, 0x51, 0x4a, 0x71, 0x4b, 0x77, 0x79, 0x34, - 0x59, 0x33, 0x6f, 0x6e, 0x36, 0x41, 0x5c, 0x0a, - 0x09, 0x09, 0x70, 0x41, 0x57, 0x67, 0x4f, 0x57, 0x43, 0x71, 0x44, 0x39, 0x74, 0x34, 0x41, 0x55, 0x54, 0x67, - 0x53, 0x41, 0x54, 0x61, 0x4b, 0x76, 0x7a, 0x65, 0x67, 0x59, 0x59, 0x45, 0x41, 0x52, 0x68, 0x6e, 0x51, 0x56, - 0x71, 0x73, 0x62, 0x73, 0x48, 0x67, 0x78, 0x32, 0x34, 0x2b, 0x41, 0x4c, 0x6f, 0x69, 0x73, 0x42, 0x77, 0x51, - 0x67, 0x57, 0x4f, 0x78, 0x4d, 0x69, 0x37, 0x34, 0x6f, 0x39, 0x72, 0x2f, 0x4a, 0x41, 0x57, 0x41, 0x31, 0x4b, - 0x7a, 0x61, 0x63, 0x79, 0x73, 0x50, 0x5c, 0x0a, - 0x09, 0x09, 0x39, 0x66, 0x79, 0x59, 0x36, 0x67, 0x4f, 0x67, 0x79, 0x37, 0x57, 0x65, 0x46, 0x59, 0x4e, 0x4e, - 0x31, 0x64, 0x31, 0x4b, 0x62, 0x4d, 0x33, 0x2b, 0x4a, 0x35, 0x6b, 0x43, 0x56, 0x48, 0x73, 0x32, 0x39, 0x70, - 0x44, 0x6c, 0x4b, 0x61, 0x50, 0x4f, 0x41, 0x65, 0x67, 0x54, 0x67, 0x62, 0x6d, 0x41, 0x43, 0x4e, 0x54, 0x56, - 0x36, 0x46, 0x4f, 0x48, 0x32, 0x2f, 0x70, 0x37, 0x47, 0x74, 0x49, 0x46, 0x6f, 0x42, 0x62, 0x38, 0x6b, 0x4b, - 0x78, 0x79, 0x46, 0x64, 0x51, 0x31, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x48, 0x33, 0x34, 0x65, 0x77, 0x65, 0x43, 0x57, 0x34, 0x6e, 0x70, 0x37, 0x4d, 0x75, 0x6d, - 0x6a, 0x64, 0x34, 0x2f, 0x69, 0x52, 0x53, 0x67, 0x46, 0x54, 0x79, 0x38, 0x6b, 0x39, 0x55, 0x4e, 0x75, 0x2f, - 0x6f, 0x41, 0x47, 0x43, 0x4d, 0x43, 0x50, 0x66, 0x2b, 0x32, 0x4e, 0x43, 0x53, 0x2b, 0x61, 0x6d, 0x49, 0x45, - 0x59, 0x4d, 0x42, 0x41, 0x52, 0x43, 0x65, 0x59, 0x77, 0x77, 0x52, 0x47, 0x2f, 0x41, 0x45, 0x41, 0x6f, 0x35, - 0x6e, 0x6a, 0x67, 0x32, 0x37, 0x39, 0x5c, 0x0a, - 0x09, 0x09, 0x32, 0x50, 0x4b, 0x6e, 0x42, 0x34, 0x50, 0x55, 0x65, 0x32, 0x2b, 0x36, 0x6c, 0x70, 0x59, 0x43, - 0x72, 0x50, 0x58, 0x73, 0x54, 0x63, 0x5a, 0x46, 0x48, 0x51, 0x42, 0x4d, 0x7a, 0x6e, 0x4c, 0x77, 0x78, 0x47, - 0x47, 0x4f, 0x70, 0x65, 0x42, 0x52, 0x2b, 0x45, 0x59, 0x4f, 0x48, 0x44, 0x55, 0x74, 0x41, 0x4f, 0x32, 0x41, - 0x39, 0x51, 0x2b, 0x65, 0x34, 0x30, 0x64, 0x54, 0x48, 0x4e, 0x6a, 0x57, 0x43, 0x30, 0x41, 0x34, 0x65, 0x6f, - 0x38, 0x57, 0x71, 0x2f, 0x46, 0x34, 0x5c, 0x0a, - 0x09, 0x09, 0x51, 0x44, 0x33, 0x4f, 0x31, 0x46, 0x2b, 0x51, 0x61, 0x51, 0x73, 0x43, 0x55, 0x41, 0x6f, 0x71, - 0x46, 0x52, 0x2b, 0x4c, 0x68, 0x41, 0x4d, 0x38, 0x41, 0x59, 0x67, 0x32, 0x48, 0x6b, 0x42, 0x70, 0x63, 0x2f, - 0x43, 0x6d, 0x33, 0x36, 0x72, 0x4a, 0x58, 0x32, 0x44, 0x61, 0x41, 0x58, 0x52, 0x59, 0x6e, 0x5a, 0x71, 0x42, - 0x66, 0x38, 0x4e, 0x4b, 0x50, 0x77, 0x43, 0x69, 0x55, 0x2b, 0x35, 0x5a, 0x4a, 0x4e, 0x51, 0x32, 0x31, 0x66, - 0x76, 0x62, 0x45, 0x49, 0x44, 0x62, 0x5c, 0x0a, - 0x09, 0x09, 0x77, 0x64, 0x79, 0x45, 0x50, 0x7a, 0x67, 0x57, 0x2b, 0x77, 0x41, 0x51, 0x6a, 0x39, 0x58, 0x67, - 0x41, 0x61, 0x4d, 0x6d, 0x4b, 0x52, 0x77, 0x63, 0x48, 0x49, 0x52, 0x37, 0x51, 0x36, 0x45, 0x77, 0x30, 0x66, - 0x66, 0x78, 0x42, 0x38, 0x59, 0x70, 0x76, 0x67, 0x43, 0x59, 0x6f, 0x58, 0x48, 0x6d, 0x35, 0x76, 0x4b, 0x6b, - 0x79, 0x34, 0x50, 0x56, 0x70, 0x48, 0x46, 0x74, 0x63, 0x78, 0x62, 0x67, 0x47, 0x6f, 0x49, 0x66, 0x41, 0x47, - 0x4d, 0x73, 0x42, 0x6b, 0x38, 0x59, 0x5c, 0x0a, - 0x09, 0x09, 0x6c, 0x70, 0x6f, 0x43, 0x2b, 0x4c, 0x30, 0x2f, 0x66, 0x56, 0x43, 0x4d, 0x2b, 0x67, 0x4e, 0x67, - 0x6c, 0x6e, 0x55, 0x6e, 0x42, 0x45, 0x42, 0x68, 0x74, 0x52, 0x38, 0x41, 0x4e, 0x69, 0x67, 0x46, 0x54, 0x78, - 0x63, 0x57, 0x4b, 0x51, 0x43, 0x38, 0x31, 0x72, 0x2b, 0x45, 0x75, 0x67, 0x4c, 0x41, 0x43, 0x6c, 0x65, 0x43, - 0x61, 0x77, 0x4d, 0x6b, 0x4f, 0x67, 0x44, 0x4d, 0x2b, 0x51, 0x4e, 0x67, 0x44, 0x77, 0x72, 0x2b, 0x5a, 0x5a, - 0x45, 0x43, 0x67, 0x4e, 0x34, 0x66, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x4c, 0x64, 0x63, 0x67, 0x47, 0x6b, 0x48, 0x67, 0x4e, 0x34, 0x66, 0x41, 0x49, 0x64, 0x63, - 0x67, 0x44, 0x45, 0x42, 0x51, 0x4f, 0x38, 0x50, 0x67, 0x48, 0x73, 0x75, 0x77, 0x4b, 0x51, 0x44, 0x51, 0x4f, - 0x38, 0x50, 0x51, 0x4c, 0x49, 0x75, 0x6f, 0x43, 0x4a, 0x43, 0x41, 0x48, 0x6a, 0x65, 0x48, 0x37, 0x30, 0x2f, - 0x41, 0x41, 0x6d, 0x37, 0x41, 0x43, 0x6b, 0x4f, 0x34, 0x41, 0x72, 0x71, 0x41, 0x6f, 0x44, 0x45, 0x4b, 0x51, - 0x58, 0x50, 0x44, 0x45, 0x68, 0x46, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x48, 0x6a, 0x4e, 0x50, 0x31, 0x62, 0x39, 0x41, 0x5a, 0x41, 0x4f, 0x6c, 0x39, 0x4e, 0x32, - 0x41, 0x41, 0x68, 0x2b, 0x41, 0x4e, 0x4a, 0x6a, 0x4d, 0x63, 0x35, 0x67, 0x6f, 0x41, 0x6b, 0x42, 0x75, 0x49, - 0x77, 0x36, 0x41, 0x43, 0x42, 0x56, 0x4b, 0x71, 0x6b, 0x49, 0x41, 0x4e, 0x74, 0x2f, 0x37, 0x50, 0x63, 0x48, - 0x77, 0x4e, 0x45, 0x30, 0x49, 0x4b, 0x34, 0x44, 0x67, 0x50, 0x30, 0x48, 0x49, 0x48, 0x33, 0x6d, 0x6f, 0x68, - 0x34, 0x59, 0x45, 0x6c, 0x63, 0x41, 0x5c, 0x0a, - 0x09, 0x09, 0x59, 0x50, 0x38, 0x42, 0x6b, 0x45, 0x45, 0x35, 0x55, 0x51, 0x48, 0x67, 0x67, 0x51, 0x66, 0x59, - 0x66, 0x77, 0x42, 0x6b, 0x63, 0x43, 0x6c, 0x70, 0x42, 0x77, 0x44, 0x37, 0x44, 0x30, 0x42, 0x65, 0x48, 0x59, - 0x44, 0x6d, 0x41, 0x73, 0x6f, 0x63, 0x41, 0x44, 0x48, 0x4d, 0x52, 0x6a, 0x6b, 0x79, 0x4c, 0x49, 0x34, 0x41, - 0x6c, 0x46, 0x48, 0x6d, 0x41, 0x4c, 0x6a, 0x74, 0x41, 0x69, 0x49, 0x4a, 0x41, 0x4f, 0x66, 0x2f, 0x4a, 0x5a, - 0x51, 0x33, 0x41, 0x4b, 0x49, 0x34, 0x5c, 0x0a, - 0x09, 0x09, 0x6e, 0x35, 0x51, 0x44, 0x77, 0x4f, 0x41, 0x66, 0x41, 0x50, 0x4b, 0x59, 0x53, 0x30, 0x6f, 0x41, - 0x59, 0x50, 0x38, 0x42, 0x6b, 0x45, 0x63, 0x70, 0x37, 0x4c, 0x4c, 0x67, 0x71, 0x41, 0x4a, 0x77, 0x48, 0x6d, - 0x55, 0x4e, 0x67, 0x50, 0x73, 0x75, 0x49, 0x4b, 0x6f, 0x41, 0x34, 0x4d, 0x49, 0x50, 0x41, 0x48, 0x49, 0x73, - 0x41, 0x45, 0x67, 0x42, 0x41, 0x4a, 0x43, 0x4a, 0x33, 0x52, 0x54, 0x41, 0x35, 0x4a, 0x6e, 0x6b, 0x41, 0x41, - 0x44, 0x6a, 0x58, 0x4c, 0x41, 0x71, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x41, 0x6f, 0x7a, 0x41, 0x41, 0x42, 0x6b, 0x68, 0x69, 0x4b, 0x4b, 0x41, 0x41, 0x43, 0x4d, - 0x41, 0x59, 0x53, 0x68, 0x68, 0x44, 0x49, 0x47, 0x49, 0x4b, 0x64, 0x6a, 0x41, 0x42, 0x41, 0x41, 0x41, 0x4a, - 0x41, 0x43, 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x51, 0x41, 0x78, 0x68, - 0x74, 0x67, 0x56, 0x44, 0x41, 0x41, 0x43, 0x41, 0x41, 0x77, 0x41, 0x41, 0x5a, 0x49, 0x67, 0x57, 0x42, 0x41, - 0x43, 0x41, 0x6e, 0x48, 0x4c, 0x6d, 0x5c, 0x0a, - 0x09, 0x09, 0x35, 0x6e, 0x49, 0x48, 0x41, 0x67, 0x41, 0x41, 0x73, 0x43, 0x49, 0x41, 0x48, 0x52, 0x51, 0x62, - 0x41, 0x50, 0x6b, 0x56, 0x67, 0x42, 0x61, 0x4b, 0x44, 0x59, 0x44, 0x38, 0x43, 0x67, 0x41, 0x41, 0x51, 0x43, - 0x35, 0x4e, 0x32, 0x77, 0x4c, 0x51, 0x52, 0x68, 0x6b, 0x44, 0x6b, 0x46, 0x4d, 0x48, 0x63, 0x4f, 0x62, 0x6d, - 0x4d, 0x67, 0x51, 0x41, 0x41, 0x4c, 0x6d, 0x45, 0x53, 0x74, 0x47, 0x6e, 0x49, 0x2f, 0x34, 0x53, 0x45, 0x6f, - 0x45, 0x53, 0x79, 0x74, 0x6f, 0x64, 0x5c, 0x0a, - 0x09, 0x09, 0x43, 0x71, 0x65, 0x66, 0x55, 0x49, 0x57, 0x5a, 0x71, 0x65, 0x50, 0x2f, 0x39, 0x75, 0x52, 0x4a, - 0x56, 0x54, 0x68, 0x31, 0x63, 0x75, 0x68, 0x37, 0x39, 0x75, 0x39, 0x2f, 0x31, 0x76, 0x39, 0x76, 0x44, 0x37, - 0x35, 0x53, 0x36, 0x74, 0x46, 0x6a, 0x46, 0x4b, 0x68, 0x63, 0x50, 0x6f, 0x55, 0x41, 0x35, 0x4d, 0x33, 0x47, - 0x50, 0x66, 0x2b, 0x55, 0x55, 0x69, 0x65, 0x6d, 0x56, 0x66, 0x48, 0x4d, 0x45, 0x2f, 0x70, 0x31, 0x79, 0x67, - 0x74, 0x32, 0x37, 0x39, 0x2f, 0x70, 0x5c, 0x0a, - 0x09, 0x09, 0x74, 0x53, 0x66, 0x6f, 0x77, 0x7a, 0x44, 0x31, 0x35, 0x6f, 0x73, 0x6a, 0x2f, 0x2f, 0x2b, 0x42, - 0x46, 0x6f, 0x4d, 0x44, 0x45, 0x6f, 0x50, 0x64, 0x50, 0x66, 0x33, 0x31, 0x51, 0x2f, 0x33, 0x31, 0x58, 0x76, - 0x66, 0x66, 0x76, 0x6e, 0x69, 0x6b, 0x44, 0x72, 0x37, 0x38, 0x47, 0x68, 0x58, 0x6a, 0x77, 0x42, 0x68, 0x41, - 0x56, 0x41, 0x48, 0x59, 0x56, 0x6a, 0x67, 0x58, 0x4d, 0x4a, 0x56, 0x41, 0x39, 0x33, 0x70, 0x74, 0x36, 0x73, - 0x33, 0x31, 0x45, 0x7a, 0x66, 0x41, 0x5c, 0x0a, - 0x09, 0x09, 0x6a, 0x62, 0x67, 0x4b, 0x2f, 0x7a, 0x39, 0x65, 0x50, 0x6a, 0x31, 0x59, 0x49, 0x4c, 0x51, 0x51, - 0x6b, 0x44, 0x69, 0x51, 0x6d, 0x34, 0x42, 0x37, 0x53, 0x49, 0x52, 0x32, 0x45, 0x67, 0x4b, 0x41, 0x63, 0x51, - 0x44, 0x62, 0x77, 0x63, 0x57, 0x42, 0x37, 0x67, 0x55, 0x39, 0x76, 0x7a, 0x71, 0x5a, 0x64, 0x70, 0x42, 0x49, - 0x61, 0x58, 0x48, 0x77, 0x33, 0x55, 0x52, 0x58, 0x45, 0x4c, 0x37, 0x53, 0x67, 0x76, 0x43, 0x35, 0x39, 0x39, - 0x44, 0x58, 0x77, 0x42, 0x78, 0x68, 0x5c, 0x0a, - 0x09, 0x09, 0x78, 0x2b, 0x69, 0x69, 0x43, 0x67, 0x44, 0x57, 0x41, 0x74, 0x6a, 0x6f, 0x34, 0x58, 0x57, 0x67, - 0x55, 0x4b, 0x44, 0x37, 0x51, 0x5a, 0x39, 0x5a, 0x59, 0x64, 0x4e, 0x50, 0x30, 0x58, 0x63, 0x4d, 0x32, 0x68, - 0x48, 0x73, 0x2f, 0x2f, 0x4b, 0x7a, 0x72, 0x69, 0x42, 0x38, 0x31, 0x45, 0x48, 0x71, 0x6b, 0x4b, 0x44, 0x39, - 0x6a, 0x79, 0x77, 0x41, 0x57, 0x6d, 0x56, 0x61, 0x4f, 0x78, 0x64, 0x72, 0x74, 0x43, 0x4c, 0x51, 0x36, 0x67, - 0x6e, 0x42, 0x44, 0x2f, 0x63, 0x66, 0x5c, 0x0a, - 0x09, 0x09, 0x71, 0x5a, 0x39, 0x38, 0x65, 0x55, 0x63, 0x2f, 0x2f, 0x36, 0x66, 0x75, 0x50, 0x64, 0x6f, 0x35, - 0x2f, 0x68, 0x6d, 0x6d, 0x54, 0x36, 0x6c, 0x7a, 0x33, 0x33, 0x78, 0x46, 0x76, 0x66, 0x33, 0x6b, 0x71, 0x2b, - 0x72, 0x6c, 0x6d, 0x54, 0x4e, 0x75, 0x56, 0x70, 0x65, 0x32, 0x37, 0x31, 0x4d, 0x55, 0x39, 0x4e, 0x2b, 0x65, - 0x50, 0x51, 0x71, 0x49, 0x76, 0x4b, 0x48, 0x4c, 0x77, 0x42, 0x4d, 0x2b, 0x2b, 0x76, 0x76, 0x66, 0x65, 0x73, - 0x55, 0x54, 0x41, 0x42, 0x4b, 0x43, 0x5c, 0x0a, - 0x09, 0x09, 0x78, 0x2b, 0x39, 0x2f, 0x34, 0x71, 0x51, 0x37, 0x6f, 0x44, 0x62, 0x37, 0x7a, 0x73, 0x4d, 0x50, - 0x76, 0x54, 0x62, 0x37, 0x33, 0x71, 0x38, 0x2f, 0x37, 0x6d, 0x75, 0x7a, 0x72, 0x35, 0x39, 0x38, 0x51, 0x62, - 0x31, 0x39, 0x36, 0x6c, 0x58, 0x76, 0x31, 0x51, 0x4c, 0x62, 0x69, 0x51, 0x68, 0x41, 0x51, 0x47, 0x30, 0x57, - 0x62, 0x52, 0x58, 0x6b, 0x50, 0x33, 0x35, 0x36, 0x57, 0x32, 0x31, 0x39, 0x2f, 0x72, 0x39, 0x65, 0x67, 0x51, - 0x35, 0x69, 0x5a, 0x2b, 0x38, 0x4c, 0x5c, 0x0a, - 0x09, 0x09, 0x31, 0x64, 0x54, 0x2f, 0x6e, 0x35, 0x36, 0x33, 0x6e, 0x33, 0x78, 0x4e, 0x2f, 0x66, 0x44, 0x30, - 0x39, 0x39, 0x51, 0x33, 0x69, 0x7a, 0x4d, 0x49, 0x2b, 0x67, 0x77, 0x34, 0x68, 0x4b, 0x6b, 0x33, 0x6e, 0x76, - 0x65, 0x65, 0x51, 0x7a, 0x46, 0x34, 0x39, 0x37, 0x34, 0x54, 0x7a, 0x6f, 0x41, 0x43, 0x2f, 0x2b, 0x39, 0x2f, - 0x39, 0x57, 0x38, 0x6a, 0x32, 0x2b, 0x78, 0x50, 0x39, 0x75, 0x35, 0x34, 0x6e, 0x64, 0x72, 0x72, 0x33, 0x33, - 0x68, 0x42, 0x2f, 0x63, 0x6e, 0x73, 0x5c, 0x0a, - 0x09, 0x09, 0x39, 0x30, 0x78, 0x33, 0x58, 0x71, 0x30, 0x6b, 0x42, 0x57, 0x44, 0x62, 0x68, 0x67, 0x42, 0x51, - 0x34, 0x66, 0x33, 0x4e, 0x4c, 0x2f, 0x2b, 0x70, 0x72, 0x38, 0x63, 0x66, 0x42, 0x52, 0x55, 0x6f, 0x46, 0x66, - 0x36, 0x66, 0x50, 0x2f, 0x65, 0x48, 0x59, 0x74, 0x30, 0x41, 0x57, 0x58, 0x71, 0x76, 0x59, 0x56, 0x50, 0x51, - 0x70, 0x7a, 0x68, 0x77, 0x35, 0x36, 0x77, 0x59, 0x61, 0x44, 0x64, 0x41, 0x51, 0x6b, 0x44, 0x4f, 0x51, 0x43, - 0x49, 0x55, 0x2b, 0x4e, 0x51, 0x4f, 0x5c, 0x0a, - 0x09, 0x09, 0x4a, 0x34, 0x58, 0x63, 0x41, 0x62, 0x56, 0x7a, 0x36, 0x72, 0x69, 0x6f, 0x41, 0x30, 0x73, 0x72, - 0x42, 0x53, 0x67, 0x6d, 0x2b, 0x63, 0x73, 0x6d, 0x49, 0x57, 0x7a, 0x77, 0x39, 0x77, 0x6f, 0x48, 0x71, 0x61, - 0x77, 0x6b, 0x70, 0x72, 0x37, 0x7a, 0x72, 0x44, 0x72, 0x78, 0x67, 0x7a, 0x66, 0x55, 0x7a, 0x4d, 0x58, 0x66, - 0x38, 0x72, 0x35, 0x47, 0x38, 0x45, 0x63, 0x58, 0x30, 0x4f, 0x6e, 0x66, 0x4f, 0x61, 0x74, 0x4f, 0x2f, 0x75, - 0x6c, 0x76, 0x71, 0x2b, 0x6c, 0x7a, 0x5c, 0x0a, - 0x09, 0x09, 0x4c, 0x33, 0x6e, 0x69, 0x34, 0x47, 0x72, 0x77, 0x42, 0x39, 0x73, 0x73, 0x76, 0x5a, 0x63, 0x36, - 0x4c, 0x78, 0x4f, 0x39, 0x66, 0x35, 0x68, 0x74, 0x77, 0x4c, 0x45, 0x46, 0x67, 0x4d, 0x59, 0x42, 0x6c, 0x4f, - 0x48, 0x5a, 0x67, 0x48, 0x39, 0x34, 0x38, 0x42, 0x2b, 0x52, 0x67, 0x6a, 0x39, 0x59, 0x6f, 0x48, 0x2f, 0x33, - 0x79, 0x5a, 0x61, 0x59, 0x77, 0x4a, 0x39, 0x5a, 0x50, 0x4f, 0x63, 0x31, 0x57, 0x68, 0x64, 0x48, 0x38, 0x45, - 0x57, 0x6e, 0x55, 0x47, 0x2b, 0x2b, 0x5c, 0x0a, - 0x09, 0x09, 0x65, 0x46, 0x69, 0x32, 0x61, 0x51, 0x74, 0x42, 0x4e, 0x39, 0x2b, 0x2f, 0x45, 0x31, 0x74, 0x41, - 0x68, 0x71, 0x55, 0x4e, 0x49, 0x64, 0x69, 0x4d, 0x38, 0x71, 0x61, 0x34, 0x6d, 0x34, 0x47, 0x4d, 0x75, 0x51, - 0x41, 0x2f, 0x70, 0x34, 0x38, 0x4c, 0x43, 0x55, 0x6a, 0x63, 0x43, 0x6a, 0x45, 0x56, 0x2b, 0x4a, 0x4a, 0x36, - 0x71, 0x53, 0x77, 0x53, 0x4c, 0x4f, 0x75, 0x30, 0x6e, 0x42, 0x56, 0x31, 0x57, 0x69, 0x62, 0x53, 0x58, 0x67, - 0x4d, 0x2f, 0x70, 0x35, 0x47, 0x47, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x47, 0x79, 0x61, 0x4b, 0x73, 0x69, 0x74, 0x7a, 0x33, 0x39, 0x71, 0x72, 0x46, 0x4b, 0x61, - 0x42, 0x6e, 0x39, 0x57, 0x47, 0x49, 0x74, 0x4b, 0x56, 0x68, 0x2b, 0x42, 0x6e, 0x34, 0x34, 0x51, 0x6e, 0x4c, - 0x78, 0x30, 0x33, 0x6b, 0x73, 0x4e, 0x6b, 0x6f, 0x51, 0x36, 0x47, 0x6c, 0x4d, 0x70, 0x4a, 0x2f, 0x32, 0x73, - 0x47, 0x43, 0x36, 0x67, 0x7a, 0x59, 0x34, 0x38, 0x57, 0x51, 0x48, 0x51, 0x76, 0x35, 0x52, 0x55, 0x78, 0x38, - 0x67, 0x42, 0x49, 0x59, 0x62, 0x79, 0x5c, 0x0a, - 0x09, 0x09, 0x6f, 0x45, 0x4d, 0x58, 0x6b, 0x4e, 0x68, 0x59, 0x67, 0x4f, 0x35, 0x35, 0x70, 0x74, 0x39, 0x36, - 0x78, 0x63, 0x76, 0x78, 0x59, 0x66, 0x56, 0x6c, 0x70, 0x41, 0x5a, 0x4a, 0x31, 0x63, 0x4e, 0x37, 0x76, 0x37, - 0x35, 0x76, 0x50, 0x4a, 0x31, 0x49, 0x73, 0x76, 0x63, 0x33, 0x34, 0x51, 0x43, 0x49, 0x75, 0x71, 0x6b, 0x55, - 0x77, 0x43, 0x54, 0x33, 0x64, 0x6e, 0x65, 0x73, 0x4e, 0x77, 0x42, 0x71, 0x61, 0x4e, 0x37, 0x67, 0x33, 0x68, - 0x76, 0x50, 0x49, 0x77, 0x43, 0x46, 0x5c, 0x0a, - 0x09, 0x09, 0x51, 0x4f, 0x37, 0x4c, 0x63, 0x32, 0x4a, 0x61, 0x6c, 0x4b, 0x30, 0x4c, 0x77, 0x4e, 0x63, 0x66, - 0x47, 0x2f, 0x31, 0x35, 0x4f, 0x33, 0x74, 0x66, 0x52, 0x6e, 0x33, 0x72, 0x52, 0x70, 0x6f, 0x43, 0x73, 0x43, - 0x47, 0x74, 0x49, 0x49, 0x6d, 0x66, 0x50, 0x33, 0x70, 0x67, 0x74, 0x66, 0x4c, 0x4a, 0x62, 0x6c, 0x4a, 0x44, - 0x67, 0x39, 0x30, 0x58, 0x6d, 0x68, 0x5a, 0x6f, 0x55, 0x53, 0x5a, 0x78, 0x74, 0x6c, 0x6b, 0x2f, 0x78, 0x6a, - 0x75, 0x74, 0x61, 0x41, 0x50, 0x67, 0x5c, 0x0a, - 0x09, 0x09, 0x72, 0x61, 0x6a, 0x32, 0x33, 0x34, 0x67, 0x41, 0x38, 0x43, 0x2f, 0x50, 0x7a, 0x39, 0x4a, 0x67, - 0x62, 0x54, 0x56, 0x50, 0x58, 0x48, 0x68, 0x74, 0x37, 0x45, 0x34, 0x35, 0x49, 0x4d, 0x41, 0x4e, 0x6e, 0x48, - 0x37, 0x43, 0x71, 0x64, 0x54, 0x73, 0x34, 0x55, 0x47, 0x6b, 0x4d, 0x59, 0x44, 0x72, 0x73, 0x56, 0x79, 0x73, - 0x6f, 0x63, 0x38, 0x65, 0x36, 0x30, 0x4f, 0x38, 0x66, 0x4d, 0x4c, 0x38, 0x34, 0x70, 0x30, 0x7a, 0x30, 0x30, - 0x39, 0x61, 0x43, 0x66, 0x34, 0x5a, 0x5c, 0x0a, - 0x09, 0x09, 0x33, 0x65, 0x74, 0x6a, 0x42, 0x5a, 0x39, 0x6a, 0x67, 0x71, 0x33, 0x72, 0x7a, 0x46, 0x75, 0x44, - 0x59, 0x62, 0x79, 0x4e, 0x6e, 0x54, 0x4c, 0x36, 0x38, 0x79, 0x49, 0x73, 0x44, 0x2b, 0x37, 0x45, 0x79, 0x66, - 0x39, 0x4e, 0x43, 0x6b, 0x43, 0x73, 0x77, 0x55, 0x42, 0x61, 0x77, 0x6d, 0x74, 0x36, 0x47, 0x65, 0x39, 0x4c, - 0x70, 0x6b, 0x57, 0x46, 0x67, 0x7a, 0x2b, 0x72, 0x6d, 0x33, 0x53, 0x79, 0x44, 0x73, 0x33, 0x4f, 0x6d, 0x42, - 0x59, 0x42, 0x30, 0x78, 0x31, 0x58, 0x5c, 0x0a, - 0x09, 0x09, 0x68, 0x45, 0x36, 0x72, 0x45, 0x57, 0x58, 0x78, 0x6a, 0x33, 0x45, 0x42, 0x34, 0x41, 0x38, 0x52, - 0x79, 0x77, 0x58, 0x51, 0x78, 0x68, 0x36, 0x54, 0x79, 0x6d, 0x78, 0x30, 0x53, 0x54, 0x43, 0x43, 0x48, 0x79, - 0x49, 0x77, 0x71, 0x4d, 0x66, 0x2b, 0x68, 0x74, 0x6e, 0x42, 0x33, 0x77, 0x67, 0x4f, 0x59, 0x43, 0x33, 0x75, - 0x37, 0x7a, 0x52, 0x35, 0x4b, 0x6e, 0x41, 0x39, 0x7a, 0x70, 0x74, 0x70, 0x68, 0x35, 0x51, 0x70, 0x76, 0x6d, - 0x39, 0x75, 0x62, 0x62, 0x58, 0x48, 0x5c, 0x0a, - 0x09, 0x09, 0x43, 0x5a, 0x72, 0x62, 0x52, 0x2f, 0x42, 0x6e, 0x51, 0x77, 0x54, 0x65, 0x65, 0x73, 0x56, 0x59, - 0x58, 0x64, 0x49, 0x61, 0x66, 0x6c, 0x50, 0x4f, 0x6c, 0x54, 0x59, 0x48, 0x68, 0x55, 0x77, 0x70, 0x36, 0x69, - 0x62, 0x4f, 0x35, 0x7a, 0x51, 0x6d, 0x41, 0x50, 0x78, 0x68, 0x49, 0x6f, 0x73, 0x41, 0x71, 0x5a, 0x38, 0x4a, - 0x46, 0x30, 0x43, 0x46, 0x57, 0x48, 0x37, 0x71, 0x75, 0x2b, 0x59, 0x61, 0x7a, 0x4c, 0x6d, 0x58, 0x6b, 0x50, - 0x4e, 0x6e, 0x62, 0x55, 0x7a, 0x67, 0x5c, 0x0a, - 0x09, 0x09, 0x77, 0x6d, 0x74, 0x47, 0x56, 0x67, 0x35, 0x53, 0x38, 0x43, 0x38, 0x38, 0x39, 0x5a, 0x74, 0x47, - 0x50, 0x68, 0x62, 0x74, 0x44, 0x41, 0x7a, 0x4a, 0x68, 0x6f, 0x6e, 0x66, 0x61, 0x2f, 0x70, 0x65, 0x67, 0x46, - 0x69, 0x57, 0x35, 0x4d, 0x2b, 0x65, 0x2b, 0x64, 0x33, 0x59, 0x69, 0x6d, 0x72, 0x69, 0x5a, 0x2f, 0x68, 0x34, - 0x4f, 0x2f, 0x67, 0x77, 0x32, 0x70, 0x38, 0x35, 0x61, 0x47, 0x70, 0x77, 0x2b, 0x6b, 0x30, 0x7a, 0x71, 0x77, - 0x62, 0x2f, 0x36, 0x4f, 0x6e, 0x7a, 0x5c, 0x0a, - 0x09, 0x09, 0x58, 0x75, 0x38, 0x64, 0x42, 0x39, 0x6f, 0x52, 0x47, 0x44, 0x4a, 0x6c, 0x70, 0x64, 0x79, 0x2f, - 0x4b, 0x55, 0x34, 0x41, 0x32, 0x41, 0x58, 0x55, 0x34, 0x69, 0x67, 0x71, 0x62, 0x65, 0x6d, 0x4e, 0x47, 0x73, - 0x41, 0x55, 0x2f, 0x43, 0x59, 0x50, 0x57, 0x6b, 0x68, 0x69, 0x4d, 0x51, 0x6c, 0x49, 0x42, 0x31, 0x6f, 0x6e, - 0x59, 0x47, 0x70, 0x36, 0x38, 0x45, 0x66, 0x50, 0x4c, 0x6b, 0x51, 0x65, 0x63, 0x36, 0x49, 0x30, 0x6f, 0x68, - 0x7a, 0x65, 0x52, 0x61, 0x79, 0x59, 0x5c, 0x0a, - 0x09, 0x09, 0x4b, 0x67, 0x63, 0x62, 0x4e, 0x77, 0x4f, 0x52, 0x43, 0x34, 0x67, 0x38, 0x4d, 0x6b, 0x6b, 0x46, - 0x75, 0x66, 0x62, 0x69, 0x44, 0x30, 0x4f, 0x70, 0x4b, 0x74, 0x6e, 0x2b, 0x76, 0x33, 0x72, 0x68, 0x6a, 0x30, - 0x33, 0x75, 0x71, 0x7a, 0x34, 0x38, 0x6d, 0x67, 0x74, 0x6b, 0x57, 0x41, 0x51, 0x4d, 0x75, 0x51, 0x43, 0x2f, - 0x34, 0x77, 0x6f, 0x54, 0x79, 0x50, 0x51, 0x65, 0x36, 0x72, 0x44, 0x6f, 0x43, 0x55, 0x6e, 0x64, 0x35, 0x4e, - 0x30, 0x63, 0x68, 0x59, 0x4f, 0x44, 0x5c, 0x0a, - 0x09, 0x09, 0x67, 0x33, 0x42, 0x76, 0x4b, 0x42, 0x54, 0x47, 0x66, 0x73, 0x2f, 0x4f, 0x78, 0x64, 0x70, 0x56, - 0x2f, 0x62, 0x49, 0x61, 0x39, 0x38, 0x50, 0x52, 0x43, 0x73, 0x48, 0x6d, 0x5a, 0x7a, 0x38, 0x64, 0x75, 0x6b, - 0x61, 0x61, 0x78, 0x49, 0x4c, 0x79, 0x2f, 0x62, 0x63, 0x4e, 0x44, 0x2f, 0x6f, 0x52, 0x6c, 0x43, 0x63, 0x69, - 0x39, 0x38, 0x38, 0x2b, 0x6a, 0x78, 0x72, 0x76, 0x47, 0x44, 0x31, 0x74, 0x69, 0x46, 0x59, 0x48, 0x33, 0x76, - 0x7a, 0x30, 0x74, 0x74, 0x64, 0x6d, 0x5c, 0x0a, - 0x09, 0x09, 0x42, 0x32, 0x33, 0x75, 0x6f, 0x63, 0x37, 0x71, 0x2b, 0x31, 0x36, 0x76, 0x2f, 0x39, 0x30, 0x6f, - 0x54, 0x70, 0x63, 0x36, 0x31, 0x76, 0x6c, 0x4a, 0x42, 0x47, 0x44, 0x53, 0x75, 0x4c, 0x59, 0x69, 0x41, 0x43, - 0x77, 0x43, 0x64, 0x35, 0x58, 0x42, 0x75, 0x77, 0x4e, 0x36, 0x6c, 0x77, 0x76, 0x54, 0x48, 0x4b, 0x79, 0x31, - 0x49, 0x38, 0x42, 0x6d, 0x70, 0x72, 0x79, 0x44, 0x4a, 0x30, 0x44, 0x32, 0x6f, 0x56, 0x4f, 0x47, 0x39, 0x76, - 0x37, 0x72, 0x51, 0x79, 0x73, 0x2f, 0x5c, 0x0a, - 0x09, 0x09, 0x6d, 0x35, 0x62, 0x32, 0x42, 0x6c, 0x66, 0x33, 0x50, 0x54, 0x4e, 0x31, 0x4b, 0x75, 0x37, 0x69, - 0x6f, 0x54, 0x55, 0x64, 0x2f, 0x46, 0x63, 0x6e, 0x2b, 0x63, 0x5a, 0x4a, 0x34, 0x33, 0x72, 0x61, 0x59, 0x74, - 0x6c, 0x57, 0x39, 0x57, 0x50, 0x73, 0x64, 0x41, 0x35, 0x4c, 0x68, 0x79, 0x67, 0x4f, 0x74, 0x6f, 0x62, 0x6f, - 0x2b, 0x58, 0x4f, 0x44, 0x7a, 0x54, 0x54, 0x50, 0x38, 0x50, 0x46, 0x30, 0x37, 0x55, 0x6d, 0x44, 0x50, 0x2b, - 0x30, 0x78, 0x67, 0x4b, 0x37, 0x56, 0x5c, 0x0a, - 0x09, 0x09, 0x36, 0x59, 0x35, 0x53, 0x4e, 0x6c, 0x78, 0x73, 0x46, 0x4a, 0x6a, 0x7a, 0x7a, 0x77, 0x38, 0x4f, - 0x31, 0x58, 0x58, 0x56, 0x69, 0x67, 0x41, 0x6d, 0x38, 0x4b, 0x45, 0x37, 0x61, 0x42, 0x51, 0x67, 0x72, 0x79, - 0x37, 0x41, 0x45, 0x44, 0x56, 0x54, 0x30, 0x33, 0x36, 0x4a, 0x43, 0x67, 0x41, 0x76, 0x45, 0x61, 0x36, 0x69, - 0x69, 0x51, 0x45, 0x51, 0x33, 0x66, 0x6f, 0x72, 0x41, 0x30, 0x74, 0x2b, 0x30, 0x33, 0x49, 0x41, 0x2f, 0x71, - 0x6c, 0x42, 0x44, 0x64, 0x52, 0x6a, 0x5c, 0x0a, - 0x09, 0x09, 0x39, 0x31, 0x6f, 0x73, 0x37, 0x32, 0x6a, 0x72, 0x2f, 0x2f, 0x36, 0x46, 0x39, 0x39, 0x42, 0x74, - 0x4f, 0x47, 0x41, 0x79, 0x36, 0x44, 0x68, 0x77, 0x76, 0x39, 0x79, 0x38, 0x6f, 0x38, 0x48, 0x7a, 0x63, 0x38, - 0x64, 0x67, 0x4e, 0x65, 0x36, 0x47, 0x6e, 0x31, 0x46, 0x4d, 0x4a, 0x2f, 0x56, 0x48, 0x36, 0x47, 0x64, 0x4f, - 0x35, 0x66, 0x68, 0x47, 0x59, 0x57, 0x71, 0x34, 0x65, 0x2b, 0x2f, 0x38, 0x66, 0x4b, 0x44, 0x39, 0x50, 0x50, - 0x46, 0x37, 0x72, 0x2b, 0x4f, 0x34, 0x5c, 0x0a, - 0x09, 0x09, 0x38, 0x47, 0x47, 0x69, 0x2b, 0x65, 0x41, 0x72, 0x74, 0x62, 0x74, 0x39, 0x70, 0x32, 0x2b, 0x71, - 0x62, 0x6d, 0x2f, 0x6d, 0x51, 0x36, 0x2f, 0x63, 0x4d, 0x72, 0x35, 0x57, 0x77, 0x35, 0x72, 0x31, 0x54, 0x38, - 0x77, 0x42, 0x42, 0x46, 0x4b, 0x42, 0x4a, 0x57, 0x65, 0x4b, 0x66, 0x58, 0x63, 0x76, 0x6b, 0x65, 0x41, 0x6e, - 0x79, 0x41, 0x55, 0x38, 0x2b, 0x70, 0x64, 0x33, 0x45, 0x65, 0x6c, 0x44, 0x48, 0x42, 0x4f, 0x56, 0x7a, 0x63, - 0x42, 0x35, 0x65, 0x75, 0x30, 0x41, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x75, 0x6e, 0x2f, 0x47, 0x62, 0x67, 0x2b, 0x6a, 0x4b, 0x34, 0x7a, 0x46, 0x77, 0x69, 0x64, - 0x39, 0x4c, 0x4e, 0x69, 0x2b, 0x35, 0x63, 0x55, 0x6b, 0x2f, 0x70, 0x72, 0x2b, 0x4f, 0x53, 0x67, 0x46, 0x53, - 0x63, 0x61, 0x33, 0x6f, 0x4f, 0x48, 0x52, 0x68, 0x76, 0x78, 0x73, 0x4f, 0x41, 0x50, 0x39, 0x6e, 0x4a, 0x53, - 0x62, 0x37, 0x78, 0x4a, 0x6b, 0x37, 0x33, 0x2f, 0x2f, 0x47, 0x69, 0x73, 0x31, 0x59, 0x38, 0x39, 0x68, 0x36, - 0x39, 0x2f, 0x76, 0x73, 0x42, 0x72, 0x5c, 0x0a, - 0x09, 0x09, 0x78, 0x78, 0x4c, 0x72, 0x4d, 0x49, 0x74, 0x4a, 0x2f, 0x6c, 0x56, 0x61, 0x42, 0x47, 0x69, 0x66, - 0x51, 0x46, 0x32, 0x38, 0x58, 0x66, 0x2f, 0x49, 0x33, 0x48, 0x6d, 0x43, 0x64, 0x4c, 0x66, 0x64, 0x52, 0x4e, - 0x38, 0x48, 0x41, 0x65, 0x67, 0x76, 0x6b, 0x33, 0x76, 0x6a, 0x36, 0x38, 0x47, 0x37, 0x59, 0x6a, 0x78, 0x47, - 0x41, 0x4e, 0x50, 0x4e, 0x78, 0x41, 0x4a, 0x5a, 0x4d, 0x72, 0x6e, 0x63, 0x56, 0x34, 0x77, 0x41, 0x4d, 0x4f, - 0x51, 0x43, 0x52, 0x4a, 0x38, 0x68, 0x5c, 0x0a, - 0x09, 0x09, 0x53, 0x44, 0x32, 0x79, 0x73, 0x56, 0x35, 0x68, 0x39, 0x7a, 0x45, 0x69, 0x4f, 0x55, 0x70, 0x67, - 0x68, 0x68, 0x67, 0x67, 0x6a, 0x57, 0x50, 0x68, 0x4a, 0x78, 0x58, 0x6f, 0x4a, 0x4f, 0x50, 0x44, 0x64, 0x74, - 0x36, 0x66, 0x71, 0x67, 0x44, 0x77, 0x65, 0x4d, 0x43, 0x43, 0x45, 0x72, 0x34, 0x2b, 0x59, 0x50, 0x2f, 0x39, - 0x58, 0x35, 0x6e, 0x35, 0x51, 0x53, 0x63, 0x77, 0x75, 0x42, 0x65, 0x70, 0x59, 0x59, 0x5a, 0x59, 0x69, 0x31, - 0x45, 0x34, 0x46, 0x58, 0x46, 0x4a, 0x5c, 0x0a, - 0x09, 0x09, 0x75, 0x4c, 0x62, 0x2f, 0x6a, 0x2b, 0x38, 0x39, 0x6b, 0x50, 0x52, 0x6e, 0x31, 0x39, 0x6b, 0x6c, - 0x71, 0x38, 0x77, 0x4b, 0x67, 0x43, 0x73, 0x69, 0x73, 0x50, 0x66, 0x75, 0x78, 0x30, 0x61, 0x6d, 0x6d, 0x75, - 0x67, 0x61, 0x38, 0x49, 0x6d, 0x2b, 0x44, 0x38, 0x75, 0x50, 0x6a, 0x7a, 0x4d, 0x7a, 0x4e, 0x64, 0x45, 0x49, - 0x50, 0x79, 0x33, 0x61, 0x69, 0x6e, 0x72, 0x30, 0x39, 0x2b, 0x4f, 0x66, 0x33, 0x5a, 0x63, 0x30, 0x6e, 0x64, - 0x6a, 0x55, 0x63, 0x5a, 0x48, 0x34, 0x5c, 0x0a, - 0x09, 0x09, 0x6d, 0x70, 0x6c, 0x69, 0x57, 0x6e, 0x38, 0x74, 0x44, 0x77, 0x72, 0x4b, 0x58, 0x53, 0x52, 0x45, - 0x76, 0x63, 0x50, 0x50, 0x34, 0x74, 0x2f, 0x38, 0x34, 0x6c, 0x39, 0x78, 0x50, 0x61, 0x34, 0x52, 0x34, 0x33, - 0x4b, 0x52, 0x66, 0x72, 0x7a, 0x7a, 0x47, 0x4d, 0x5a, 0x4d, 0x6a, 0x30, 0x59, 0x39, 0x73, 0x38, 0x45, 0x62, - 0x6e, 0x48, 0x33, 0x33, 0x59, 0x79, 0x6c, 0x2f, 0x4b, 0x73, 0x56, 0x43, 0x4b, 0x72, 0x4e, 0x6b, 0x78, 0x54, - 0x54, 0x2f, 0x61, 0x6c, 0x34, 0x6b, 0x5c, 0x0a, - 0x09, 0x09, 0x4a, 0x46, 0x59, 0x45, 0x61, 0x50, 0x54, 0x65, 0x78, 0x44, 0x51, 0x54, 0x4e, 0x64, 0x4a, 0x68, - 0x41, 0x65, 0x36, 0x64, 0x58, 0x66, 0x2b, 0x44, 0x4e, 0x78, 0x44, 0x74, 0x51, 0x38, 0x70, 0x6d, 0x36, 0x42, - 0x6f, 0x4a, 0x75, 0x70, 0x49, 0x74, 0x78, 0x73, 0x33, 0x4c, 0x6b, 0x38, 0x77, 0x77, 0x4a, 0x42, 0x6a, 0x38, - 0x43, 0x7a, 0x59, 0x58, 0x2b, 0x34, 0x77, 0x73, 0x59, 0x31, 0x76, 0x62, 0x67, 0x63, 0x4f, 0x77, 0x63, 0x37, - 0x46, 0x57, 0x30, 0x53, 0x2f, 0x72, 0x5c, 0x0a, - 0x09, 0x09, 0x55, 0x68, 0x75, 0x68, 0x46, 0x36, 0x41, 0x47, 0x46, 0x75, 0x71, 0x51, 0x6d, 0x4f, 0x7a, 0x66, - 0x36, 0x36, 0x6a, 0x39, 0x2b, 0x35, 0x39, 0x35, 0x7a, 0x71, 0x43, 0x67, 0x47, 0x36, 0x2b, 0x4e, 0x38, 0x2b, - 0x6f, 0x7a, 0x42, 0x37, 0x6d, 0x78, 0x39, 0x7a, 0x38, 0x35, 0x48, 0x42, 0x67, 0x73, 0x2b, 0x75, 0x55, 0x57, - 0x73, 0x55, 0x35, 0x73, 0x62, 0x67, 0x45, 0x4f, 0x53, 0x59, 0x65, 0x44, 0x33, 0x2f, 0x69, 0x67, 0x65, 0x4f, - 0x72, 0x6e, 0x41, 0x57, 0x52, 0x4a, 0x5c, 0x0a, - 0x09, 0x09, 0x42, 0x43, 0x67, 0x2f, 0x39, 0x77, 0x36, 0x53, 0x42, 0x4d, 0x35, 0x44, 0x49, 0x72, 0x49, 0x72, - 0x59, 0x2b, 0x47, 0x56, 0x74, 0x65, 0x41, 0x50, 0x49, 0x77, 0x42, 0x46, 0x4b, 0x52, 0x57, 0x6a, 0x43, 0x36, - 0x49, 0x75, 0x4e, 0x52, 0x32, 0x67, 0x2b, 0x65, 0x69, 0x39, 0x66, 0x37, 0x2b, 0x4c, 0x36, 0x48, 0x45, 0x63, - 0x62, 0x31, 0x6e, 0x78, 0x76, 0x37, 0x36, 0x58, 0x2b, 0x65, 0x42, 0x33, 0x5a, 0x67, 0x7a, 0x41, 0x4a, 0x52, - 0x45, 0x67, 0x43, 0x77, 0x6f, 0x52, 0x5c, 0x0a, - 0x09, 0x09, 0x63, 0x44, 0x76, 0x34, 0x76, 0x53, 0x58, 0x58, 0x36, 0x65, 0x66, 0x39, 0x59, 0x6f, 0x4a, 0x66, - 0x6e, 0x41, 0x42, 0x41, 0x42, 0x49, 0x41, 0x74, 0x32, 0x79, 0x38, 0x6b, 0x2b, 0x43, 0x6e, 0x6f, 0x7a, 0x30, - 0x6f, 0x4a, 0x66, 0x70, 0x45, 0x43, 0x45, 0x42, 0x43, 0x42, 0x4a, 0x53, 0x56, 0x77, 0x6e, 0x51, 0x43, 0x4a, - 0x77, 0x4b, 0x4f, 0x62, 0x2f, 0x35, 0x4f, 0x6e, 0x37, 0x61, 0x68, 0x4f, 0x51, 0x77, 0x4e, 0x2b, 0x75, 0x33, - 0x4b, 0x43, 0x50, 0x37, 0x58, 0x52, 0x5c, 0x0a, - 0x09, 0x09, 0x66, 0x71, 0x63, 0x45, 0x67, 0x45, 0x57, 0x41, 0x70, 0x67, 0x68, 0x46, 0x4c, 0x68, 0x59, 0x69, - 0x4f, 0x2f, 0x6e, 0x31, 0x35, 0x6d, 0x33, 0x73, 0x35, 0x35, 0x63, 0x4d, 0x37, 0x52, 0x62, 0x63, 0x76, 0x69, - 0x4e, 0x6c, 0x74, 0x4c, 0x38, 0x75, 0x4d, 0x66, 0x67, 0x4a, 0x4d, 0x62, 0x4d, 0x41, 0x77, 0x39, 0x69, 0x35, - 0x57, 0x43, 0x76, 0x70, 0x6c, 0x78, 0x75, 0x71, 0x65, 0x35, 0x36, 0x41, 0x4f, 0x47, 0x68, 0x2b, 0x33, 0x37, - 0x74, 0x6c, 0x42, 0x76, 0x76, 0x35, 0x5c, 0x0a, - 0x09, 0x09, 0x52, 0x56, 0x6c, 0x2b, 0x53, 0x74, 0x57, 0x45, 0x37, 0x50, 0x4b, 0x72, 0x4a, 0x62, 0x47, 0x74, - 0x74, 0x36, 0x2b, 0x54, 0x63, 0x6d, 0x30, 0x61, 0x63, 0x49, 0x77, 0x49, 0x30, 0x48, 0x70, 0x61, 0x6d, 0x69, - 0x4a, 0x63, 0x6c, 0x4e, 0x6a, 0x67, 0x76, 0x4b, 0x75, 0x6d, 0x59, 0x69, 0x78, 0x4b, 0x41, 0x65, 0x5a, 0x36, - 0x66, 0x65, 0x72, 0x78, 0x42, 0x57, 0x32, 0x74, 0x72, 0x6e, 0x49, 0x36, 0x71, 0x79, 0x41, 0x41, 0x5a, 0x6f, - 0x54, 0x67, 0x71, 0x6a, 0x4a, 0x77, 0x5c, 0x0a, - 0x09, 0x09, 0x34, 0x59, 0x69, 0x31, 0x66, 0x45, 0x6f, 0x4c, 0x41, 0x41, 0x6c, 0x42, 0x31, 0x4c, 0x58, 0x70, - 0x49, 0x45, 0x61, 0x75, 0x54, 0x34, 0x65, 0x75, 0x47, 0x4e, 0x71, 0x2f, 0x59, 0x59, 0x44, 0x55, 0x52, 0x2f, - 0x6f, 0x7a, 0x4b, 0x51, 0x41, 0x73, 0x41, 0x6f, 0x76, 0x73, 0x42, 0x6d, 0x61, 0x6c, 0x4e, 0x6b, 0x5a, 0x61, - 0x70, 0x54, 0x5a, 0x31, 0x37, 0x6b, 0x55, 0x49, 0x51, 0x52, 0x4b, 0x42, 0x54, 0x32, 0x63, 0x46, 0x76, 0x76, - 0x4d, 0x4c, 0x53, 0x59, 0x64, 0x36, 0x5c, 0x0a, - 0x09, 0x09, 0x4e, 0x46, 0x56, 0x33, 0x50, 0x33, 0x2b, 0x71, 0x2b, 0x58, 0x35, 0x6d, 0x42, 0x63, 0x43, 0x46, - 0x63, 0x51, 0x45, 0x49, 0x67, 0x58, 0x32, 0x72, 0x54, 0x39, 0x74, 0x34, 0x68, 0x51, 0x55, 0x2b, 0x73, 0x57, - 0x62, 0x6a, 0x38, 0x67, 0x34, 0x49, 0x77, 0x48, 0x41, 0x68, 0x75, 0x4b, 0x5a, 0x66, 0x6c, 0x71, 0x57, 0x33, - 0x56, 0x32, 0x2f, 0x74, 0x4f, 0x74, 0x31, 0x47, 0x69, 0x79, 0x32, 0x2f, 0x38, 0x52, 0x71, 0x31, 0x44, 0x6e, - 0x59, 0x36, 0x70, 0x30, 0x47, 0x51, 0x5c, 0x0a, - 0x09, 0x09, 0x31, 0x51, 0x39, 0x61, 0x2f, 0x71, 0x55, 0x6b, 0x44, 0x2f, 0x4b, 0x41, 0x41, 0x42, 0x79, 0x4a, - 0x51, 0x4a, 0x6c, 0x54, 0x67, 0x70, 0x4c, 0x30, 0x42, 0x75, 0x78, 0x74, 0x44, 0x58, 0x37, 0x31, 0x57, 0x56, - 0x58, 0x38, 0x7a, 0x6a, 0x4e, 0x77, 0x42, 0x53, 0x46, 0x74, 0x50, 0x70, 0x33, 0x63, 0x73, 0x79, 0x2f, 0x72, - 0x38, 0x41, 0x34, 0x66, 0x62, 0x30, 0x65, 0x72, 0x74, 0x43, 0x6d, 0x2b, 0x33, 0x41, 0x67, 0x41, 0x69, 0x77, - 0x43, 0x4e, 0x42, 0x36, 0x79, 0x36, 0x5c, 0x0a, - 0x09, 0x09, 0x34, 0x41, 0x59, 0x4f, 0x79, 0x35, 0x48, 0x4f, 0x41, 0x4e, 0x41, 0x70, 0x41, 0x68, 0x30, 0x59, - 0x41, 0x6a, 0x48, 0x6f, 0x68, 0x34, 0x4b, 0x64, 0x67, 0x74, 0x34, 0x37, 0x73, 0x55, 0x66, 0x6d, 0x6f, 0x71, - 0x73, 0x4f, 0x42, 0x37, 0x37, 0x49, 0x4f, 0x79, 0x39, 0x79, 0x4a, 0x51, 0x41, 0x75, 0x75, 0x6f, 0x45, 0x2b, - 0x4d, 0x66, 0x6a, 0x32, 0x61, 0x5a, 0x30, 0x69, 0x7a, 0x4f, 0x62, 0x33, 0x57, 0x6a, 0x4c, 0x4f, 0x36, 0x77, - 0x2f, 0x75, 0x66, 0x79, 0x34, 0x35, 0x5c, 0x0a, - 0x09, 0x09, 0x36, 0x45, 0x58, 0x33, 0x2b, 0x72, 0x6b, 0x58, 0x41, 0x46, 0x66, 0x64, 0x77, 0x44, 0x46, 0x6d, - 0x70, 0x72, 0x7a, 0x62, 0x69, 0x65, 0x6d, 0x73, 0x41, 0x42, 0x6f, 0x37, 0x79, 0x4b, 0x77, 0x37, 0x30, 0x41, - 0x46, 0x4f, 0x4a, 0x2f, 0x4c, 0x53, 0x6f, 0x68, 0x33, 0x76, 0x5a, 0x46, 0x38, 0x44, 0x42, 0x36, 0x38, 0x6b, - 0x51, 0x46, 0x74, 0x31, 0x44, 0x2b, 0x30, 0x55, 0x66, 0x39, 0x4e, 0x56, 0x62, 0x67, 0x55, 0x67, 0x49, 0x41, - 0x51, 0x30, 0x51, 0x30, 0x43, 0x44, 0x5c, 0x0a, - 0x09, 0x09, 0x68, 0x47, 0x57, 0x6e, 0x41, 0x34, 0x58, 0x4f, 0x78, 0x6e, 0x76, 0x75, 0x57, 0x36, 0x70, 0x34, - 0x35, 0x67, 0x6c, 0x56, 0x65, 0x4f, 0x36, 0x70, 0x37, 0x6d, 0x47, 0x5a, 0x44, 0x71, 0x34, 0x36, 0x39, 0x49, - 0x2f, 0x76, 0x70, 0x68, 0x35, 0x2b, 0x6e, 0x30, 0x35, 0x64, 0x64, 0x69, 0x50, 0x67, 0x67, 0x39, 0x44, 0x39, - 0x66, 0x44, 0x58, 0x4a, 0x76, 0x54, 0x34, 0x45, 0x59, 0x4c, 0x41, 0x51, 0x56, 0x46, 0x67, 0x49, 0x5a, 0x6c, - 0x56, 0x57, 0x49, 0x46, 0x47, 0x67, 0x5c, 0x0a, - 0x09, 0x09, 0x77, 0x7a, 0x44, 0x35, 0x51, 0x45, 0x7a, 0x76, 0x39, 0x64, 0x52, 0x4d, 0x2b, 0x6d, 0x36, 0x42, - 0x65, 0x6e, 0x55, 0x4b, 0x37, 0x4e, 0x30, 0x39, 0x37, 0x33, 0x4b, 0x56, 0x2f, 0x5a, 0x33, 0x75, 0x38, 0x65, - 0x6f, 0x4f, 0x42, 0x6e, 0x75, 0x51, 0x4a, 0x74, 0x76, 0x39, 0x39, 0x6a, 0x45, 0x72, 0x38, 0x4c, 0x64, 0x4e, - 0x61, 0x6b, 0x2f, 0x6c, 0x30, 0x6f, 0x2f, 0x4c, 0x47, 0x41, 0x4e, 0x77, 0x51, 0x41, 0x52, 0x6d, 0x4f, 0x53, - 0x57, 0x34, 0x6b, 0x69, 0x6b, 0x68, 0x5c, 0x0a, - 0x09, 0x09, 0x47, 0x43, 0x45, 0x4f, 0x52, 0x50, 0x48, 0x35, 0x62, 0x78, 0x33, 0x56, 0x32, 0x33, 0x50, 0x39, - 0x79, 0x35, 0x54, 0x48, 0x4c, 0x56, 0x33, 0x32, 0x37, 0x6b, 0x66, 0x6f, 0x79, 0x63, 0x57, 0x39, 0x59, 0x4f, - 0x61, 0x37, 0x44, 0x67, 0x36, 0x2b, 0x2b, 0x4c, 0x6f, 0x62, 0x34, 0x48, 0x53, 0x37, 0x6a, 0x74, 0x74, 0x42, - 0x50, 0x73, 0x7a, 0x75, 0x56, 0x77, 0x64, 0x4e, 0x37, 0x65, 0x6e, 0x67, 0x72, 0x33, 0x43, 0x61, 0x57, 0x64, - 0x4c, 0x50, 0x76, 0x42, 0x61, 0x42, 0x5c, 0x0a, - 0x09, 0x09, 0x46, 0x67, 0x54, 0x41, 0x44, 0x53, 0x45, 0x6f, 0x63, 0x63, 0x56, 0x56, 0x46, 0x41, 0x44, 0x44, - 0x41, 0x33, 0x39, 0x74, 0x30, 0x42, 0x72, 0x2b, 0x6e, 0x73, 0x41, 0x2f, 0x64, 0x41, 0x68, 0x61, 0x41, 0x42, - 0x59, 0x67, 0x41, 0x42, 0x41, 0x43, 0x34, 0x44, 0x61, 0x55, 0x32, 0x31, 0x38, 0x66, 0x6c, 0x4f, 0x66, 0x72, - 0x77, 0x43, 0x39, 0x7a, 0x65, 0x79, 0x6b, 0x50, 0x65, 0x65, 0x2b, 0x43, 0x46, 0x6f, 0x45, 0x6d, 0x42, 0x41, - 0x42, 0x43, 0x41, 0x50, 0x49, 0x56, 0x5c, 0x0a, - 0x09, 0x09, 0x2b, 0x47, 0x4a, 0x64, 0x41, 0x41, 0x51, 0x41, 0x51, 0x67, 0x41, 0x6d, 0x73, 0x50, 0x72, 0x36, - 0x61, 0x63, 0x51, 0x49, 0x2f, 0x43, 0x43, 0x69, 0x78, 0x67, 0x49, 0x67, 0x41, 0x50, 0x33, 0x35, 0x47, 0x77, - 0x30, 0x43, 0x74, 0x6b, 0x5a, 0x5a, 0x4e, 0x52, 0x59, 0x43, 0x45, 0x6f, 0x48, 0x73, 0x44, 0x78, 0x62, 0x6d, - 0x46, 0x77, 0x72, 0x53, 0x36, 0x30, 0x4e, 0x79, 0x2f, 0x43, 0x69, 0x42, 0x37, 0x31, 0x50, 0x58, 0x62, 0x61, - 0x73, 0x4b, 0x41, 0x5a, 0x41, 0x72, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x41, 0x38, 0x34, 0x71, 0x45, 0x6b, 0x41, 0x4e, 0x6e, 0x52, 0x6c, 0x31, 0x55, 0x63, 0x49, - 0x41, 0x58, 0x33, 0x66, 0x6f, 0x75, 0x6f, 0x66, 0x38, 0x41, 0x48, 0x75, 0x51, 0x76, 0x57, 0x39, 0x4d, 0x57, - 0x52, 0x55, 0x50, 0x30, 0x37, 0x67, 0x42, 0x31, 0x4f, 0x4a, 0x73, 0x37, 0x70, 0x64, 0x64, 0x53, 0x41, 0x41, - 0x4d, 0x67, 0x58, 0x67, 0x59, 0x4a, 0x67, 0x46, 0x48, 0x46, 0x56, 0x70, 0x76, 0x4c, 0x7a, 0x34, 0x4d, 0x74, - 0x49, 0x44, 0x5a, 0x32, 0x33, 0x2b, 0x5c, 0x0a, - 0x09, 0x09, 0x68, 0x75, 0x72, 0x65, 0x75, 0x74, 0x73, 0x65, 0x30, 0x43, 0x5a, 0x38, 0x74, 0x32, 0x64, 0x71, - 0x57, 0x33, 0x6c, 0x31, 0x56, 0x4d, 0x63, 0x43, 0x41, 0x5a, 0x41, 0x6c, 0x41, 0x45, 0x48, 0x6c, 0x70, 0x6b, - 0x71, 0x37, 0x72, 0x69, 0x75, 0x76, 0x50, 0x59, 0x45, 0x72, 0x4d, 0x4e, 0x6c, 0x67, 0x51, 0x50, 0x4b, 0x39, - 0x76, 0x62, 0x38, 0x6d, 0x35, 0x4c, 0x49, 0x46, 0x64, 0x30, 0x65, 0x64, 0x79, 0x52, 0x49, 0x45, 0x77, 0x43, - 0x30, 0x42, 0x4f, 0x46, 0x61, 0x42, 0x5c, 0x0a, - 0x09, 0x09, 0x4c, 0x41, 0x54, 0x4e, 0x55, 0x64, 0x2f, 0x45, 0x59, 0x77, 0x56, 0x58, 0x57, 0x42, 0x43, 0x51, - 0x49, 0x73, 0x69, 0x41, 0x36, 0x6d, 0x35, 0x54, 0x44, 0x52, 0x6a, 0x55, 0x34, 0x2f, 0x71, 0x66, 0x34, 0x7a, - 0x71, 0x7a, 0x36, 0x65, 0x51, 0x36, 0x75, 0x75, 0x32, 0x63, 0x68, 0x67, 0x44, 0x49, 0x43, 0x33, 0x36, 0x79, - 0x38, 0x56, 0x73, 0x68, 0x72, 0x65, 0x50, 0x59, 0x39, 0x49, 0x44, 0x46, 0x59, 0x49, 0x35, 0x37, 0x45, 0x34, - 0x69, 0x42, 0x76, 0x4b, 0x43, 0x66, 0x5c, 0x0a, - 0x09, 0x09, 0x56, 0x55, 0x65, 0x44, 0x75, 0x6b, 0x6e, 0x56, 0x6a, 0x59, 0x6a, 0x5a, 0x41, 0x41, 0x68, 0x41, - 0x76, 0x2f, 0x72, 0x66, 0x69, 0x71, 0x4c, 0x6f, 0x41, 0x56, 0x63, 0x77, 0x74, 0x6c, 0x4a, 0x5a, 0x44, 0x50, - 0x77, 0x78, 0x41, 0x36, 0x51, 0x4a, 0x46, 0x6e, 0x70, 0x59, 0x31, 0x52, 0x33, 0x45, 0x48, 0x52, 0x72, 0x30, - 0x58, 0x4e, 0x2b, 0x4c, 0x41, 0x56, 0x46, 0x4f, 0x47, 0x68, 0x48, 0x6a, 0x41, 0x42, 0x43, 0x41, 0x61, 0x43, - 0x6e, 0x41, 0x4b, 0x4c, 0x7a, 0x70, 0x5c, 0x0a, - 0x09, 0x09, 0x6f, 0x30, 0x6c, 0x63, 0x51, 0x63, 0x2b, 0x59, 0x77, 0x51, 0x55, 0x57, 0x42, 0x62, 0x69, 0x44, - 0x36, 0x4f, 0x58, 0x75, 0x42, 0x66, 0x32, 0x6f, 0x49, 0x37, 0x64, 0x59, 0x35, 0x50, 0x33, 0x42, 0x32, 0x6a, - 0x53, 0x6e, 0x63, 0x4e, 0x64, 0x30, 0x2b, 0x37, 0x67, 0x4b, 0x41, 0x63, 0x69, 0x65, 0x41, 0x41, 0x79, 0x30, - 0x6e, 0x70, 0x4e, 0x4f, 0x2b, 0x77, 0x54, 0x63, 0x77, 0x51, 0x56, 0x32, 0x42, 0x78, 0x43, 0x45, 0x30, 0x51, - 0x47, 0x2f, 0x54, 0x61, 0x2b, 0x6a, 0x5c, 0x0a, - 0x09, 0x09, 0x74, 0x74, 0x38, 0x47, 0x67, 0x6c, 0x35, 0x53, 0x2b, 0x67, 0x55, 0x42, 0x79, 0x49, 0x45, 0x41, - 0x42, 0x50, 0x45, 0x62, 0x61, 0x79, 0x4e, 0x4d, 0x37, 0x73, 0x63, 0x44, 0x69, 0x53, 0x51, 0x49, 0x35, 0x31, - 0x6b, 0x51, 0x79, 0x6a, 0x6b, 0x4d, 0x39, 0x6a, 0x59, 0x48, 0x2f, 0x47, 0x30, 0x4f, 0x39, 0x75, 0x59, 0x45, - 0x39, 0x56, 0x6a, 0x69, 0x67, 0x4a, 0x65, 0x61, 0x5a, 0x6b, 0x45, 0x41, 0x68, 0x41, 0x72, 0x41, 0x33, 0x51, - 0x52, 0x36, 0x43, 0x54, 0x39, 0x48, 0x5c, 0x0a, - 0x09, 0x09, 0x39, 0x52, 0x70, 0x30, 0x32, 0x41, 0x30, 0x69, 0x37, 0x42, 0x4a, 0x38, 0x64, 0x33, 0x43, 0x42, - 0x58, 0x37, 0x50, 0x69, 0x46, 0x4a, 0x6f, 0x63, 0x38, 0x42, 0x2f, 0x77, 0x31, 0x36, 0x32, 0x77, 0x68, 0x32, - 0x76, 0x6f, 0x4f, 0x74, 0x78, 0x79, 0x51, 0x43, 0x69, 0x64, 0x45, 0x6f, 0x44, 0x70, 0x6e, 0x50, 0x55, 0x32, - 0x74, 0x6f, 0x50, 0x4a, 0x7a, 0x2f, 0x75, 0x39, 0x56, 0x59, 0x53, 0x36, 0x77, 0x51, 0x59, 0x64, 0x51, 0x6f, - 0x74, 0x46, 0x59, 0x57, 0x69, 0x6a, 0x5c, 0x0a, - 0x09, 0x09, 0x35, 0x35, 0x74, 0x6b, 0x57, 0x67, 0x4f, 0x45, 0x6f, 0x63, 0x77, 0x2f, 0x6d, 0x38, 0x54, 0x68, - 0x61, 0x58, 0x36, 0x64, 0x46, 0x64, 0x59, 0x44, 0x64, 0x67, 0x4b, 0x66, 0x66, 0x54, 0x76, 0x77, 0x33, 0x2b, - 0x31, 0x42, 0x69, 0x33, 0x41, 0x69, 0x73, 0x70, 0x31, 0x54, 0x70, 0x32, 0x53, 0x4e, 0x50, 0x44, 0x6b, 0x41, - 0x4b, 0x58, 0x63, 0x49, 0x74, 0x41, 0x4d, 0x75, 0x6f, 0x57, 0x56, 0x69, 0x47, 0x79, 0x6b, 0x4c, 0x68, 0x45, - 0x2f, 0x77, 0x36, 0x39, 0x38, 0x59, 0x5c, 0x0a, - 0x09, 0x09, 0x49, 0x58, 0x71, 0x44, 0x42, 0x4b, 0x51, 0x35, 0x4a, 0x76, 0x67, 0x47, 0x42, 0x62, 0x76, 0x4a, - 0x41, 0x4a, 0x66, 0x69, 0x35, 0x4f, 0x4c, 0x67, 0x31, 0x43, 0x78, 0x41, 0x6e, 0x68, 0x7a, 0x41, 0x42, 0x30, - 0x49, 0x2b, 0x42, 0x7a, 0x58, 0x65, 0x53, 0x71, 0x42, 0x42, 0x2b, 0x34, 0x47, 0x33, 0x71, 0x52, 0x74, 0x4f, - 0x4c, 0x63, 0x6f, 0x50, 0x37, 0x4d, 0x6d, 0x64, 0x6d, 0x78, 0x6d, 0x76, 0x52, 0x39, 0x70, 0x77, 0x73, 0x79, - 0x58, 0x34, 0x38, 0x37, 0x56, 0x63, 0x5c, 0x0a, - 0x09, 0x09, 0x4b, 0x73, 0x78, 0x69, 0x6a, 0x67, 0x52, 0x41, 0x63, 0x6d, 0x44, 0x34, 0x46, 0x68, 0x2b, 0x4d, - 0x55, 0x38, 0x2b, 0x75, 0x59, 0x36, 0x6f, 0x4a, 0x2f, 0x58, 0x68, 0x74, 0x69, 0x63, 0x65, 0x44, 0x51, 0x51, - 0x43, 0x36, 0x44, 0x61, 0x66, 0x46, 0x31, 0x68, 0x55, 0x43, 0x35, 0x58, 0x35, 0x64, 0x72, 0x67, 0x6a, 0x74, - 0x61, 0x54, 0x64, 0x63, 0x4b, 0x38, 0x74, 0x69, 0x7a, 0x74, 0x70, 0x4f, 0x51, 0x33, 0x43, 0x6a, 0x68, 0x67, - 0x43, 0x45, 0x59, 0x30, 0x6d, 0x59, 0x5c, 0x0a, - 0x09, 0x09, 0x6f, 0x48, 0x63, 0x45, 0x4f, 0x78, 0x4d, 0x49, 0x41, 0x4c, 0x4f, 0x4a, 0x33, 0x6a, 0x38, 0x7a, - 0x4c, 0x71, 0x43, 0x74, 0x58, 0x78, 0x59, 0x45, 0x69, 0x63, 0x43, 0x61, 0x6c, 0x4c, 0x4d, 0x41, 0x49, 0x41, - 0x44, 0x44, 0x47, 0x30, 0x31, 0x44, 0x61, 0x42, 0x71, 0x77, 0x69, 0x5a, 0x43, 0x4f, 0x6e, 0x4e, 0x61, 0x74, - 0x53, 0x48, 0x43, 0x57, 0x55, 0x51, 0x64, 0x77, 0x49, 0x51, 0x44, 0x4a, 0x63, 0x78, 0x32, 0x70, 0x53, 0x61, - 0x5a, 0x45, 0x6f, 0x4b, 0x36, 0x36, 0x5c, 0x0a, - 0x09, 0x09, 0x4d, 0x77, 0x4e, 0x70, 0x30, 0x55, 0x72, 0x35, 0x39, 0x30, 0x4d, 0x41, 0x51, 0x6c, 0x49, 0x54, - 0x35, 0x67, 0x4a, 0x61, 0x6f, 0x77, 0x34, 0x69, 0x41, 0x52, 0x4f, 0x4c, 0x77, 0x48, 0x77, 0x4b, 0x39, 0x55, - 0x71, 0x70, 0x32, 0x34, 0x4b, 0x4c, 0x31, 0x6a, 0x2b, 0x33, 0x41, 0x73, 0x43, 0x56, 0x4a, 0x63, 0x6b, 0x46, - 0x58, 0x45, 0x63, 0x49, 0x47, 0x30, 0x73, 0x48, 0x46, 0x6c, 0x52, 0x79, 0x73, 0x77, 0x4d, 0x31, 0x4f, 0x67, - 0x72, 0x63, 0x35, 0x65, 0x44, 0x50, 0x5c, 0x0a, - 0x09, 0x09, 0x71, 0x77, 0x50, 0x77, 0x58, 0x59, 0x43, 0x45, 0x58, 0x72, 0x63, 0x44, 0x2b, 0x32, 0x39, 0x46, - 0x42, 0x47, 0x7a, 0x6d, 0x34, 0x79, 0x33, 0x75, 0x39, 0x56, 0x65, 0x79, 0x55, 0x47, 0x61, 0x35, 0x76, 0x52, - 0x63, 0x67, 0x77, 0x69, 0x6c, 0x42, 0x4e, 0x68, 0x43, 0x78, 0x63, 0x53, 0x53, 0x4c, 0x47, 0x44, 0x72, 0x70, - 0x39, 0x39, 0x69, 0x50, 0x35, 0x50, 0x71, 0x71, 0x75, 0x2f, 0x44, 0x33, 0x59, 0x7a, 0x66, 0x67, 0x5a, 0x49, - 0x33, 0x6b, 0x4b, 0x6a, 0x65, 0x53, 0x5c, 0x0a, - 0x09, 0x09, 0x74, 0x48, 0x72, 0x2f, 0x73, 0x36, 0x35, 0x62, 0x53, 0x45, 0x65, 0x45, 0x77, 0x44, 0x2b, 0x2f, - 0x4d, 0x51, 0x72, 0x6b, 0x30, 0x44, 0x61, 0x6b, 0x33, 0x67, 0x49, 0x4d, 0x41, 0x59, 0x6a, 0x66, 0x51, 0x4e, - 0x5a, 0x56, 0x4f, 0x6b, 0x64, 0x2b, 0x56, 0x31, 0x33, 0x70, 0x54, 0x54, 0x4a, 0x53, 0x7a, 0x79, 0x56, 0x32, - 0x41, 0x35, 0x64, 0x55, 0x64, 0x7a, 0x2f, 0x47, 0x73, 0x4a, 0x32, 0x55, 0x54, 0x62, 0x62, 0x35, 0x33, 0x6f, - 0x45, 0x6b, 0x72, 0x67, 0x6f, 0x30, 0x5c, 0x0a, - 0x09, 0x09, 0x42, 0x45, 0x43, 0x32, 0x43, 0x49, 0x67, 0x35, 0x50, 0x68, 0x70, 0x6b, 0x6b, 0x30, 0x6e, 0x6a, - 0x75, 0x6f, 0x69, 0x69, 0x38, 0x67, 0x61, 0x50, 0x61, 0x42, 0x34, 0x33, 0x71, 0x64, 0x36, 0x59, 0x63, 0x73, - 0x6b, 0x71, 0x53, 0x68, 0x31, 0x49, 0x41, 0x41, 0x4a, 0x77, 0x58, 0x41, 0x53, 0x71, 0x79, 0x75, 0x35, 0x63, - 0x4d, 0x76, 0x33, 0x73, 0x4a, 0x65, 0x54, 0x39, 0x41, 0x41, 0x49, 0x67, 0x55, 0x77, 0x54, 0x49, 0x42, 0x64, - 0x43, 0x43, 0x45, 0x68, 0x73, 0x44, 0x5c, 0x0a, - 0x09, 0x09, 0x50, 0x74, 0x54, 0x7a, 0x4c, 0x37, 0x69, 0x32, 0x58, 0x52, 0x52, 0x6b, 0x47, 0x34, 0x77, 0x42, - 0x44, 0x42, 0x38, 0x58, 0x4b, 0x43, 0x74, 0x7a, 0x30, 0x30, 0x67, 0x6b, 0x4b, 0x46, 0x58, 0x30, 0x2f, 0x45, - 0x44, 0x61, 0x47, 0x41, 0x41, 0x45, 0x59, 0x4c, 0x77, 0x51, 0x6c, 0x46, 0x54, 0x30, 0x61, 0x38, 0x43, 0x6f, - 0x74, 0x31, 0x39, 0x7a, 0x62, 0x51, 0x6f, 0x4a, 0x51, 0x41, 0x41, 0x67, 0x41, 0x49, 0x50, 0x46, 0x77, 0x44, - 0x2b, 0x2b, 0x2b, 0x7a, 0x79, 0x4c, 0x5c, 0x0a, - 0x09, 0x09, 0x51, 0x58, 0x6c, 0x41, 0x6a, 0x75, 0x39, 0x50, 0x49, 0x54, 0x56, 0x67, 0x39, 0x30, 0x48, 0x6d, - 0x42, 0x41, 0x41, 0x41, 0x6b, 0x42, 0x30, 0x77, 0x43, 0x41, 0x67, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x45, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x45, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x45, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, - 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x44, 0x32, 0x2b, 0x48, - 0x38, 0x42, 0x42, 0x67, 0x43, 0x7a, 0x5c, 0x0a, - 0x09, 0x09, 0x34, 0x78, 0x6b, 0x76, 0x62, 0x59, 0x39, 0x64, 0x36, 0x67, 0x41, 0x41, 0x41, 0x41, 0x42, 0x4a, - 0x52, 0x55, 0x35, 0x45, 0x72, 0x6b, 0x4a, 0x67, 0x67, 0x67, 0x3d, 0x3d, 0x22, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x0a, - 0x09, 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, - 0x4e, 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x43, - 0x41, 0x59, 0x41, 0x41, 0x41, 0x43, 0x71, 0x61, 0x58, 0x48, 0x65, 0x41, 0x41, 0x41, 0x41, 0x47, 0x58, 0x52, - 0x46, 0x57, 0x48, 0x52, 0x54, 0x62, 0x32, 0x5a, 0x30, 0x64, 0x32, 0x46, 0x79, 0x5a, 0x51, 0x42, 0x42, 0x5a, - 0x47, 0x39, 0x69, 0x5a, 0x53, 0x42, 0x4a, 0x5c, 0x0a, - 0x09, 0x09, 0x62, 0x57, 0x46, 0x6e, 0x5a, 0x56, 0x4a, 0x6c, 0x59, 0x57, 0x52, 0x35, 0x63, 0x63, 0x6c, 0x6c, - 0x50, 0x41, 0x41, 0x41, 0x41, 0x79, 0x42, 0x70, 0x56, 0x46, 0x68, 0x30, 0x57, 0x45, 0x31, 0x4d, 0x4f, 0x6d, - 0x4e, 0x76, 0x62, 0x53, 0x35, 0x68, 0x5a, 0x47, 0x39, 0x69, 0x5a, 0x53, 0x35, 0x34, 0x62, 0x58, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x44, 0x77, 0x2f, 0x65, 0x48, 0x42, 0x68, 0x59, 0x32, 0x74, 0x6c, 0x64, 0x43, - 0x42, 0x69, 0x5a, 0x57, 0x64, 0x70, 0x5c, 0x0a, - 0x09, 0x09, 0x62, 0x6a, 0x30, 0x69, 0x37, 0x37, 0x75, 0x2f, 0x49, 0x69, 0x42, 0x70, 0x5a, 0x44, 0x30, 0x69, - 0x56, 0x7a, 0x56, 0x4e, 0x4d, 0x45, 0x31, 0x77, 0x51, 0x32, 0x56, 0x6f, 0x61, 0x55, 0x68, 0x36, 0x63, 0x6d, - 0x56, 0x54, 0x65, 0x6b, 0x35, 0x55, 0x59, 0x33, 0x70, 0x72, 0x59, 0x7a, 0x6c, 0x6b, 0x49, 0x6a, 0x38, 0x2b, - 0x49, 0x44, 0x78, 0x34, 0x4f, 0x6e, 0x68, 0x74, 0x63, 0x47, 0x31, 0x6c, 0x64, 0x47, 0x45, 0x67, 0x65, 0x47, - 0x31, 0x73, 0x62, 0x6e, 0x4d, 0x36, 0x5c, 0x0a, - 0x09, 0x09, 0x65, 0x44, 0x30, 0x69, 0x59, 0x57, 0x52, 0x76, 0x59, 0x6d, 0x55, 0x36, 0x62, 0x6e, 0x4d, 0x36, - 0x62, 0x57, 0x56, 0x30, 0x59, 0x53, 0x38, 0x69, 0x49, 0x48, 0x67, 0x36, 0x65, 0x47, 0x31, 0x77, 0x64, 0x47, - 0x73, 0x39, 0x49, 0x6b, 0x46, 0x6b, 0x62, 0x32, 0x4a, 0x6c, 0x49, 0x46, 0x68, 0x4e, 0x55, 0x43, 0x42, 0x44, - 0x62, 0x33, 0x4a, 0x6c, 0x49, 0x44, 0x55, 0x75, 0x4d, 0x43, 0x31, 0x6a, 0x4d, 0x44, 0x59, 0x77, 0x49, 0x44, - 0x59, 0x78, 0x4c, 0x6a, 0x45, 0x7a, 0x5c, 0x0a, - 0x09, 0x09, 0x4e, 0x44, 0x63, 0x33, 0x4e, 0x79, 0x77, 0x67, 0x4d, 0x6a, 0x41, 0x78, 0x4d, 0x43, 0x38, 0x77, - 0x4d, 0x69, 0x38, 0x78, 0x4d, 0x69, 0x30, 0x78, 0x4e, 0x7a, 0x6f, 0x7a, 0x4d, 0x6a, 0x6f, 0x77, 0x4d, 0x43, - 0x41, 0x67, 0x49, 0x43, 0x41, 0x67, 0x49, 0x43, 0x41, 0x67, 0x49, 0x6a, 0x34, 0x67, 0x50, 0x48, 0x4a, 0x6b, - 0x5a, 0x6a, 0x70, 0x53, 0x52, 0x45, 0x59, 0x67, 0x65, 0x47, 0x31, 0x73, 0x62, 0x6e, 0x4d, 0x36, 0x63, 0x6d, - 0x52, 0x6d, 0x50, 0x53, 0x4a, 0x6f, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x63, 0x7a, - 0x4c, 0x6d, 0x39, 0x79, 0x5a, 0x79, 0x38, 0x78, 0x4f, 0x54, 0x6b, 0x35, 0x4c, 0x7a, 0x41, 0x79, 0x4c, 0x7a, - 0x49, 0x79, 0x4c, 0x58, 0x4a, 0x6b, 0x5a, 0x69, 0x31, 0x7a, 0x65, 0x57, 0x35, 0x30, 0x59, 0x58, 0x67, 0x74, - 0x62, 0x6e, 0x4d, 0x6a, 0x49, 0x6a, 0x34, 0x67, 0x50, 0x48, 0x4a, 0x6b, 0x5a, 0x6a, 0x70, 0x45, 0x5a, 0x58, - 0x4e, 0x6a, 0x63, 0x6d, 0x6c, 0x77, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x79, 0x5a, 0x47, 0x59, 0x36, 0x59, 0x57, 0x4a, 0x76, - 0x64, 0x58, 0x51, 0x39, 0x49, 0x69, 0x49, 0x67, 0x65, 0x47, 0x31, 0x73, 0x62, 0x6e, 0x4d, 0x36, 0x65, 0x47, - 0x31, 0x77, 0x50, 0x53, 0x4a, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x62, 0x6e, 0x4d, 0x75, - 0x59, 0x57, 0x52, 0x76, 0x59, 0x6d, 0x55, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x33, 0x68, 0x68, 0x63, 0x43, - 0x38, 0x78, 0x4c, 0x6a, 0x41, 0x76, 0x5c, 0x0a, - 0x09, 0x09, 0x49, 0x69, 0x42, 0x34, 0x62, 0x57, 0x78, 0x75, 0x63, 0x7a, 0x70, 0x34, 0x62, 0x58, 0x42, 0x4e, - 0x54, 0x54, 0x30, 0x69, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32, 0x35, 0x7a, 0x4c, 0x6d, - 0x46, 0x6b, 0x62, 0x32, 0x4a, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x34, 0x59, 0x58, 0x41, 0x76, - 0x4d, 0x53, 0x34, 0x77, 0x4c, 0x32, 0x31, 0x74, 0x4c, 0x79, 0x49, 0x67, 0x65, 0x47, 0x31, 0x73, 0x62, 0x6e, - 0x4d, 0x36, 0x63, 0x33, 0x52, 0x53, 0x5c, 0x0a, - 0x09, 0x09, 0x5a, 0x57, 0x59, 0x39, 0x49, 0x6d, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x75, - 0x63, 0x79, 0x35, 0x68, 0x5a, 0x47, 0x39, 0x69, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x76, 0x65, 0x47, - 0x46, 0x77, 0x4c, 0x7a, 0x45, 0x75, 0x4d, 0x43, 0x39, 0x7a, 0x56, 0x48, 0x6c, 0x77, 0x5a, 0x53, 0x39, 0x53, - 0x5a, 0x58, 0x4e, 0x76, 0x64, 0x58, 0x4a, 0x6a, 0x5a, 0x56, 0x4a, 0x6c, 0x5a, 0x69, 0x4d, 0x69, 0x49, 0x48, - 0x68, 0x74, 0x63, 0x44, 0x70, 0x44, 0x5c, 0x0a, - 0x09, 0x09, 0x63, 0x6d, 0x56, 0x68, 0x64, 0x47, 0x39, 0x79, 0x56, 0x47, 0x39, 0x76, 0x62, 0x44, 0x30, 0x69, - 0x51, 0x57, 0x52, 0x76, 0x59, 0x6d, 0x55, 0x67, 0x55, 0x47, 0x68, 0x76, 0x64, 0x47, 0x39, 0x7a, 0x61, 0x47, - 0x39, 0x77, 0x49, 0x45, 0x4e, 0x54, 0x4e, 0x53, 0x42, 0x58, 0x61, 0x57, 0x35, 0x6b, 0x62, 0x33, 0x64, 0x7a, - 0x49, 0x69, 0x42, 0x34, 0x62, 0x58, 0x42, 0x4e, 0x54, 0x54, 0x70, 0x4a, 0x62, 0x6e, 0x4e, 0x30, 0x59, 0x57, - 0x35, 0x6a, 0x5a, 0x55, 0x6c, 0x45, 0x5c, 0x0a, - 0x09, 0x09, 0x50, 0x53, 0x4a, 0x34, 0x62, 0x58, 0x41, 0x75, 0x61, 0x57, 0x6c, 0x6b, 0x4f, 0x6a, 0x6b, 0x33, - 0x4e, 0x55, 0x59, 0x78, 0x4e, 0x30, 0x4e, 0x47, 0x4f, 0x55, 0x51, 0x35, 0x52, 0x44, 0x45, 0x78, 0x52, 0x54, - 0x41, 0x35, 0x4d, 0x54, 0x67, 0x79, 0x51, 0x6a, 0x63, 0x34, 0x4d, 0x6b, 0x4e, 0x45, 0x51, 0x6b, 0x59, 0x35, - 0x52, 0x6b, 0x49, 0x31, 0x49, 0x69, 0x42, 0x34, 0x62, 0x58, 0x42, 0x4e, 0x54, 0x54, 0x70, 0x45, 0x62, 0x32, - 0x4e, 0x31, 0x62, 0x57, 0x56, 0x75, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x45, 0x6c, 0x45, 0x50, 0x53, 0x4a, 0x34, 0x62, 0x58, 0x41, 0x75, 0x5a, 0x47, 0x6c, 0x6b, - 0x4f, 0x6a, 0x6b, 0x33, 0x4e, 0x55, 0x59, 0x78, 0x4e, 0x30, 0x51, 0x77, 0x4f, 0x55, 0x51, 0x35, 0x52, 0x44, - 0x45, 0x78, 0x52, 0x54, 0x41, 0x35, 0x4d, 0x54, 0x67, 0x79, 0x51, 0x6a, 0x63, 0x34, 0x4d, 0x6b, 0x4e, 0x45, - 0x51, 0x6b, 0x59, 0x35, 0x52, 0x6b, 0x49, 0x31, 0x49, 0x6a, 0x34, 0x67, 0x50, 0x48, 0x68, 0x74, 0x63, 0x45, - 0x31, 0x4e, 0x4f, 0x6b, 0x52, 0x6c, 0x5c, 0x0a, - 0x09, 0x09, 0x63, 0x6d, 0x6c, 0x32, 0x5a, 0x57, 0x52, 0x47, 0x63, 0x6d, 0x39, 0x74, 0x49, 0x48, 0x4e, 0x30, - 0x55, 0x6d, 0x56, 0x6d, 0x4f, 0x6d, 0x6c, 0x75, 0x63, 0x33, 0x52, 0x68, 0x62, 0x6d, 0x4e, 0x6c, 0x53, 0x55, - 0x51, 0x39, 0x49, 0x6e, 0x68, 0x74, 0x63, 0x43, 0x35, 0x70, 0x61, 0x57, 0x51, 0x36, 0x4f, 0x54, 0x63, 0x31, - 0x52, 0x6a, 0x45, 0x33, 0x51, 0x30, 0x51, 0x35, 0x52, 0x44, 0x6c, 0x45, 0x4d, 0x54, 0x46, 0x46, 0x4d, 0x44, - 0x6b, 0x78, 0x4f, 0x44, 0x4a, 0x43, 0x5c, 0x0a, - 0x09, 0x09, 0x4e, 0x7a, 0x67, 0x79, 0x51, 0x30, 0x52, 0x43, 0x52, 0x6a, 0x6c, 0x47, 0x51, 0x6a, 0x55, 0x69, - 0x49, 0x48, 0x4e, 0x30, 0x55, 0x6d, 0x56, 0x6d, 0x4f, 0x6d, 0x52, 0x76, 0x59, 0x33, 0x56, 0x74, 0x5a, 0x57, - 0x35, 0x30, 0x53, 0x55, 0x51, 0x39, 0x49, 0x6e, 0x68, 0x74, 0x63, 0x43, 0x35, 0x6b, 0x61, 0x57, 0x51, 0x36, - 0x4f, 0x54, 0x63, 0x31, 0x52, 0x6a, 0x45, 0x33, 0x51, 0x30, 0x55, 0x35, 0x52, 0x44, 0x6c, 0x45, 0x4d, 0x54, - 0x46, 0x46, 0x4d, 0x44, 0x6b, 0x78, 0x5c, 0x0a, - 0x09, 0x09, 0x4f, 0x44, 0x4a, 0x43, 0x4e, 0x7a, 0x67, 0x79, 0x51, 0x30, 0x52, 0x43, 0x52, 0x6a, 0x6c, 0x47, - 0x51, 0x6a, 0x55, 0x69, 0x4c, 0x7a, 0x34, 0x67, 0x50, 0x43, 0x39, 0x79, 0x5a, 0x47, 0x59, 0x36, 0x52, 0x47, - 0x56, 0x7a, 0x59, 0x33, 0x4a, 0x70, 0x63, 0x48, 0x52, 0x70, 0x62, 0x32, 0x34, 0x2b, 0x49, 0x44, 0x77, 0x76, - 0x63, 0x6d, 0x52, 0x6d, 0x4f, 0x6c, 0x4a, 0x45, 0x52, 0x6a, 0x34, 0x67, 0x50, 0x43, 0x39, 0x34, 0x4f, 0x6e, - 0x68, 0x74, 0x63, 0x47, 0x31, 0x6c, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x47, 0x45, 0x2b, 0x49, 0x44, 0x77, 0x2f, 0x65, 0x48, 0x42, 0x68, 0x59, 0x32, 0x74, 0x6c, - 0x64, 0x43, 0x42, 0x6c, 0x62, 0x6d, 0x51, 0x39, 0x49, 0x6e, 0x49, 0x69, 0x50, 0x7a, 0x37, 0x4d, 0x74, 0x67, - 0x59, 0x54, 0x41, 0x41, 0x41, 0x43, 0x64, 0x30, 0x6c, 0x45, 0x51, 0x56, 0x52, 0x34, 0x32, 0x75, 0x79, 0x61, - 0x6a, 0x57, 0x32, 0x43, 0x55, 0x42, 0x44, 0x48, 0x48, 0x38, 0x59, 0x42, 0x57, 0x4b, 0x42, 0x4a, 0x52, 0x38, - 0x41, 0x4a, 0x43, 0x68, 0x76, 0x59, 0x5c, 0x0a, - 0x09, 0x09, 0x41, 0x5a, 0x72, 0x69, 0x42, 0x4e, 0x59, 0x4a, 0x72, 0x42, 0x4f, 0x49, 0x45, 0x39, 0x69, 0x6d, - 0x41, 0x36, 0x67, 0x54, 0x79, 0x41, 0x5a, 0x6c, 0x67, 0x39, 0x70, 0x30, 0x41, 0x54, 0x61, 0x77, 0x39, 0x39, - 0x49, 0x7a, 0x66, 0x53, 0x45, 0x67, 0x76, 0x49, 0x39, 0x44, 0x6c, 0x4c, 0x76, 0x6b, 0x35, 0x55, 0x55, 0x55, - 0x75, 0x50, 0x75, 0x39, 0x2f, 0x37, 0x31, 0x50, 0x76, 0x65, 0x50, 0x78, 0x4b, 0x50, 0x70, 0x73, 0x41, 0x39, - 0x46, 0x7a, 0x59, 0x77, 0x41, 0x4d, 0x5c, 0x0a, - 0x09, 0x09, 0x67, 0x41, 0x45, 0x77, 0x41, 0x41, 0x62, 0x41, 0x41, 0x42, 0x67, 0x41, 0x41, 0x32, 0x41, 0x41, - 0x44, 0x49, 0x41, 0x42, 0x4d, 0x41, 0x41, 0x47, 0x30, 0x45, 0x63, 0x62, 0x6d, 0x74, 0x7a, 0x6b, 0x65, 0x56, - 0x37, 0x70, 0x39, 0x5a, 0x2b, 0x6e, 0x56, 0x51, 0x68, 0x56, 0x69, 0x42, 0x38, 0x50, 0x55, 0x4e, 0x4b, 0x37, - 0x6a, 0x2b, 0x6e, 0x42, 0x78, 0x6b, 0x46, 0x34, 0x5a, 0x67, 0x7a, 0x56, 0x48, 0x4d, 0x70, 0x39, 0x79, 0x64, - 0x65, 0x5a, 0x66, 0x41, 0x65, 0x55, 0x5c, 0x0a, - 0x09, 0x09, 0x64, 0x33, 0x68, 0x50, 0x56, 0x6e, 0x5a, 0x2f, 0x33, 0x58, 0x36, 0x48, 0x5a, 0x37, 0x49, 0x68, - 0x55, 0x67, 0x51, 0x41, 0x54, 0x67, 0x5a, 0x51, 0x72, 0x61, 0x45, 0x45, 0x4a, 0x54, 0x2b, 0x58, 0x44, 0x69, - 0x37, 0x41, 0x77, 0x56, 0x51, 0x7a, 0x63, 0x42, 0x2b, 0x71, 0x6a, 0x51, 0x4b, 0x30, 0x7a, 0x75, 0x54, 0x7a, - 0x4a, 0x30, 0x58, 0x67, 0x35, 0x41, 0x43, 0x77, 0x31, 0x61, 0x57, 0x6a, 0x66, 0x73, 0x31, 0x74, 0x43, 0x54, - 0x67, 0x33, 0x30, 0x77, 0x68, 0x2b, 0x5c, 0x0a, - 0x09, 0x09, 0x58, 0x77, 0x48, 0x30, 0x6e, 0x4f, 0x56, 0x51, 0x49, 0x6c, 0x55, 0x4e, 0x70, 0x41, 0x43, 0x77, - 0x35, 0x66, 0x63, 0x4e, 0x67, 0x6c, 0x63, 0x6c, 0x4b, 0x78, 0x33, 0x4d, 0x43, 0x59, 0x4a, 0x58, 0x49, 0x59, - 0x78, 0x4f, 0x53, 0x71, 0x69, 0x4c, 0x62, 0x32, 0x43, 0x52, 0x6d, 0x37, 0x35, 0x6d, 0x38, 0x41, 0x4b, 0x44, - 0x2b, 0x6b, 0x4a, 0x77, 0x56, 0x62, 0x61, 0x32, 0x43, 0x46, 0x36, 0x67, 0x50, 0x2b, 0x73, 0x32, 0x52, 0x6f, - 0x47, 0x6c, 0x5a, 0x76, 0x43, 0x71, 0x5c, 0x0a, - 0x09, 0x09, 0x67, 0x2f, 0x73, 0x79, 0x43, 0x48, 0x44, 0x74, 0x46, 0x61, 0x71, 0x78, 0x67, 0x38, 0x34, 0x39, - 0x68, 0x47, 0x65, 0x4e, 0x79, 0x51, 0x44, 0x41, 0x77, 0x32, 0x57, 0x50, 0x48, 0x46, 0x75, 0x32, 0x30, 0x67, - 0x5a, 0x56, 0x70, 0x4b, 0x62, 0x54, 0x33, 0x4f, 0x45, 0x49, 0x39, 0x30, 0x79, 0x70, 0x67, 0x4b, 0x6b, 0x44, - 0x42, 0x2b, 0x39, 0x52, 0x43, 0x53, 0x63, 0x49, 0x47, 0x38, 0x64, 0x44, 0x66, 0x43, 0x4d, 0x46, 0x44, 0x45, - 0x30, 0x6c, 0x35, 0x73, 0x68, 0x4a, 0x5c, 0x0a, - 0x09, 0x09, 0x32, 0x65, 0x70, 0x4c, 0x67, 0x50, 0x42, 0x64, 0x4d, 0x63, 0x35, 0x62, 0x47, 0x61, 0x6f, 0x71, - 0x6f, 0x77, 0x41, 0x51, 0x4f, 0x50, 0x51, 0x7a, 0x46, 0x6e, 0x54, 0x6d, 0x55, 0x36, 0x58, 0x41, 0x56, 0x56, - 0x69, 0x54, 0x79, 0x64, 0x63, 0x74, 0x41, 0x32, 0x67, 0x30, 0x42, 0x62, 0x39, 0x6c, 0x41, 0x47, 0x6e, 0x66, - 0x41, 0x65, 0x77, 0x6f, 0x41, 0x61, 0x51, 0x64, 0x44, 0x7a, 0x36, 0x48, 0x2f, 0x4e, 0x39, 0x53, 0x41, 0x74, - 0x68, 0x31, 0x48, 0x4d, 0x43, 0x4b, 0x5c, 0x0a, - 0x09, 0x09, 0x65, 0x69, 0x71, 0x38, 0x37, 0x58, 0x4c, 0x72, 0x79, 0x35, 0x55, 0x6e, 0x4b, 0x51, 0x42, 0x63, - 0x61, 0x58, 0x55, 0x56, 0x77, 0x75, 0x72, 0x63, 0x61, 0x74, 0x4e, 0x6c, 0x4a, 0x7a, 0x69, 0x37, 0x39, 0x74, - 0x61, 0x33, 0x41, 0x6f, 0x41, 0x71, 0x53, 0x44, 0x6f, 0x47, 0x59, 0x4b, 0x48, 0x54, 0x2b, 0x74, 0x59, 0x62, - 0x49, 0x6a, 0x6a, 0x66, 0x2f, 0x6e, 0x51, 0x38, 0x4e, 0x54, 0x61, 0x31, 0x44, 0x49, 0x49, 0x66, 0x46, 0x53, - 0x2b, 0x53, 0x62, 0x59, 0x67, 0x6f, 0x5c, 0x0a, - 0x09, 0x09, 0x39, 0x6f, 0x6a, 0x53, 0x75, 0x37, 0x52, 0x4e, 0x54, 0x47, 0x36, 0x79, 0x42, 0x6f, 0x43, 0x70, - 0x45, 0x46, 0x30, 0x59, 0x77, 0x71, 0x4a, 0x71, 0x56, 0x35, 0x67, 0x38, 0x42, 0x51, 0x70, 0x4c, 0x54, 0x39, - 0x30, 0x74, 0x4d, 0x6a, 0x4c, 0x70, 0x74, 0x35, 0x6b, 0x43, 0x4a, 0x79, 0x56, 0x6b, 0x71, 0x49, 0x52, 0x44, - 0x69, 0x38, 0x48, 0x6e, 0x70, 0x74, 0x49, 0x6e, 0x57, 0x51, 0x73, 0x67, 0x68, 0x46, 0x48, 0x64, 0x4a, 0x6f, - 0x52, 0x44, 0x6d, 0x35, 0x6c, 0x4b, 0x5c, 0x0a, - 0x09, 0x09, 0x6e, 0x32, 0x77, 0x78, 0x68, 0x4d, 0x4f, 0x51, 0x56, 0x4d, 0x49, 0x62, 0x63, 0x66, 0x44, 0x79, - 0x6e, 0x4d, 0x48, 0x36, 0x48, 0x63, 0x37, 0x36, 0x67, 0x44, 0x4b, 0x44, 0x66, 0x75, 0x46, 0x46, 0x2f, 0x4f, - 0x30, 0x65, 0x4f, 0x31, 0x2f, 0x71, 0x51, 0x76, 0x42, 0x52, 0x6b, 0x78, 0x2b, 0x32, 0x31, 0x67, 0x64, 0x55, - 0x71, 0x43, 0x48, 0x42, 0x6c, 0x48, 0x44, 0x5a, 0x4c, 0x32, 0x51, 0x34, 0x39, 0x44, 0x6f, 0x78, 0x38, 0x76, - 0x30, 0x41, 0x70, 0x56, 0x39, 0x49, 0x5c, 0x0a, - 0x09, 0x09, 0x48, 0x41, 0x55, 0x66, 0x36, 0x63, 0x37, 0x32, 0x4c, 0x70, 0x59, 0x43, 0x4a, 0x53, 0x6b, 0x52, - 0x59, 0x6b, 0x6f, 0x45, 0x62, 0x51, 0x58, 0x66, 0x79, 0x75, 0x6d, 0x77, 0x41, 0x59, 0x68, 0x59, 0x56, 0x42, - 0x39, 0x35, 0x4f, 0x32, 0x33, 0x35, 0x54, 0x67, 0x49, 0x6f, 0x67, 0x4a, 0x6a, 0x57, 0x4b, 0x43, 0x4b, 0x56, - 0x4f, 0x57, 0x38, 0x71, 0x2b, 0x30, 0x34, 0x44, 0x4b, 0x4d, 0x77, 0x69, 0x35, 0x55, 0x6e, 0x4f, 0x67, 0x2f, - 0x67, 0x2f, 0x64, 0x4d, 0x6c, 0x78, 0x5c, 0x0a, - 0x09, 0x09, 0x69, 0x6d, 0x76, 0x56, 0x64, 0x35, 0x41, 0x41, 0x75, 0x43, 0x58, 0x6a, 0x50, 0x30, 0x6b, 0x78, - 0x41, 0x41, 0x62, 0x41, 0x41, 0x42, 0x67, 0x41, 0x41, 0x32, 0x41, 0x41, 0x44, 0x49, 0x41, 0x42, 0x4d, 0x41, - 0x41, 0x47, 0x77, 0x41, 0x42, 0x36, 0x61, 0x62, 0x38, 0x43, 0x44, 0x41, 0x43, 0x6a, 0x6c, 0x50, 0x65, 0x70, - 0x56, 0x76, 0x45, 0x33, 0x72, 0x77, 0x41, 0x41, 0x41, 0x41, 0x42, 0x4a, 0x52, 0x55, 0x35, 0x45, 0x72, 0x6b, - 0x4a, 0x67, 0x67, 0x67, 0x3d, 0x3d, 0x22, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, - 0x09, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x78, 0x20, 0x3d, 0x20, 0x34, 0x30, 0x30, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x79, 0x20, 0x3d, 0x20, 0x33, 0x30, 0x30, 0x0a, - 0x09, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x67, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x0a, - 0x09, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, - 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x72, 0x61, 0x64, 0x69, 0x75, - 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, - 0x68, 0x2e, 0x70, 0x69, 0x2a, 0x32, 0x2f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x0a, - 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, - 0x73, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x65, - 0x70, 0x2a, 0x69, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x73, 0x70, 0x65, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x64, 0x69, - 0x75, 0x73, 0x2f, 0x34, 0x35, 0x30, 0x0a, - 0x09, 0x09, 0x09, 0x7d, 0x0a, - 0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x68, 0x65, - 0x61, 0x72, 0x74, 0x73, 0x2c, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x72, 0x69, 0x6e, - 0x67, 0x73, 0x2c, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x28, 0x64, 0x74, 0x29, 0x0a, - 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, - 0x73, 0x28, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x09, 0x76, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x76, 0x2e, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2b, 0x20, 0x76, 0x2e, 0x73, 0x70, 0x65, 0x65, 0x64, - 0x2a, 0x64, 0x74, 0x2a, 0x30, 0x2e, 0x36, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, - 0x61, 0x77, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, - 0x73, 0x28, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x63, 0x6f, 0x73, 0x28, 0x76, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x2a, 0x20, - 0x76, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x2b, 0x20, 0x63, 0x78, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x73, 0x69, 0x6e, 0x28, 0x76, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x2a, 0x20, - 0x76, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x2b, 0x20, 0x63, 0x79, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, - 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, - 0x32, 0x35, 0x35, 0x2c, 0x20, 0x76, 0x2e, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x2a, 0x32, 0x35, 0x35, - 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, - 0x72, 0x61, 0x77, 0x28, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x78, - 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x76, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2b, 0x30, 0x2e, - 0x34, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x33, 0x32, 0x2c, 0x20, 0x33, 0x32, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, - 0x61, 0x77, 0x5f, 0x70, 0x69, 0x67, 0x28, 0x70, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, - 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, - 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, - 0x61, 0x77, 0x28, 0x70, 0x2e, 0x69, 0x6d, 0x67, 0x2c, 0x20, 0x70, 0x2e, 0x78, 0x2c, 0x20, 0x70, 0x2e, 0x79, - 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x32, 0x38, 0x2c, 0x20, 0x31, 0x32, - 0x38, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x62, 0x79, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x0a, + 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x4e, + 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x43, 0x41, + 0x59, 0x41, 0x41, 0x41, 0x44, 0x44, 0x50, 0x6d, 0x48, 0x4c, 0x41, 0x41, 0x41, 0x4c, 0x31, 0x6b, 0x6c, 0x45, + 0x51, 0x56, 0x52, 0x34, 0x6e, 0x4f, 0x32, 0x64, 0x65, 0x5a, 0x41, 0x55, 0x31, 0x52, 0x33, 0x48, 0x50, 0x7a, + 0x33, 0x58, 0x5c, 0x0a, + 0x09, 0x33, 0x72, 0x75, 0x7a, 0x75, 0x79, 0x77, 0x45, 0x58, 0x5a, 0x56, 0x4c, 0x42, 0x4a, 0x48, 0x41, 0x69, + 0x6c, 0x66, 0x55, 0x70, 0x41, 0x51, 0x4e, 0x47, 0x6f, 0x31, 0x52, 0x50, 0x44, 0x41, 0x78, 0x4b, 0x69, 0x61, + 0x4b, 0x6b, 0x70, 0x51, 0x48, 0x6c, 0x5a, 0x42, 0x4b, 0x68, 0x54, 0x49, 0x52, 0x6a, 0x53, 0x61, 0x57, 0x6c, + 0x43, 0x6d, 0x72, 0x72, 0x43, 0x4a, 0x42, 0x44, 0x52, 0x37, 0x52, 0x61, 0x4d, 0x53, 0x55, 0x42, 0x78, 0x36, + 0x78, 0x5c, 0x0a, + 0x09, 0x45, 0x6c, 0x6d, 0x68, 0x43, 0x49, 0x6f, 0x67, 0x69, 0x38, 0x64, 0x4b, 0x46, 0x45, 0x51, 0x45, 0x59, + 0x57, 0x47, 0x58, 0x76, 0x61, 0x2b, 0x5a, 0x6e, 0x75, 0x6e, 0x70, 0x2f, 0x4e, 0x47, 0x7a, 0x62, 0x4f, 0x2f, + 0x73, 0x7a, 0x75, 0x77, 0x63, 0x2f, 0x58, 0x5a, 0x33, 0x39, 0x72, 0x31, 0x50, 0x31, 0x64, 0x54, 0x32, 0x64, + 0x72, 0x2f, 0x2b, 0x39, 0x61, 0x2f, 0x37, 0x66, 0x66, 0x76, 0x31, 0x75, 0x35, 0x39, 0x6d, 0x6d, 0x69, 0x59, + 0x4b, 0x5c, 0x0a, + 0x09, 0x65, 0x58, 0x45, 0x4e, 0x74, 0x77, 0x4f, 0x4b, 0x34, 0x55, 0x55, 0x4a, 0x51, 0x48, 0x4b, 0x55, 0x41, + 0x43, 0x52, 0x48, 0x43, 0x55, 0x42, 0x79, 0x6c, 0x41, 0x41, 0x6b, 0x52, 0x77, 0x6c, 0x41, 0x63, 0x70, 0x51, + 0x41, 0x4a, 0x45, 0x63, 0x4a, 0x51, 0x48, 0x4b, 0x55, 0x41, 0x43, 0x52, 0x48, 0x43, 0x55, 0x42, 0x79, 0x6c, + 0x41, 0x41, 0x6b, 0x52, 0x77, 0x6c, 0x41, 0x63, 0x70, 0x51, 0x41, 0x4a, 0x45, 0x63, 0x4a, 0x51, 0x48, 0x4b, + 0x55, 0x5c, 0x0a, + 0x09, 0x41, 0x43, 0x52, 0x48, 0x43, 0x55, 0x42, 0x79, 0x6c, 0x41, 0x41, 0x6b, 0x52, 0x77, 0x6c, 0x41, 0x63, + 0x70, 0x51, 0x41, 0x4a, 0x45, 0x63, 0x4a, 0x51, 0x48, 0x4b, 0x55, 0x41, 0x43, 0x52, 0x48, 0x43, 0x55, 0x42, + 0x79, 0x6c, 0x41, 0x41, 0x6b, 0x52, 0x77, 0x6c, 0x41, 0x63, 0x70, 0x51, 0x41, 0x4a, 0x45, 0x63, 0x4a, 0x51, + 0x48, 0x4b, 0x55, 0x41, 0x43, 0x52, 0x48, 0x43, 0x55, 0x42, 0x79, 0x6c, 0x41, 0x41, 0x6b, 0x52, 0x77, 0x6c, + 0x41, 0x5c, 0x0a, + 0x09, 0x63, 0x6a, 0x7a, 0x44, 0x37, 0x55, 0x43, 0x32, 0x59, 0x4e, 0x52, 0x57, 0x4f, 0x32, 0x4c, 0x48, 0x50, + 0x57, 0x4f, 0x75, 0x49, 0x33, 0x61, 0x63, 0x77, 0x6c, 0x45, 0x42, 0x61, 0x4a, 0x72, 0x6d, 0x70, 0x4c, 0x6b, + 0x52, 0x51, 0x2f, 0x69, 0x54, 0x39, 0x54, 0x32, 0x62, 0x6c, 0x77, 0x42, 0x58, 0x41, 0x4d, 0x63, 0x41, 0x54, + 0x77, 0x4c, 0x2f, 0x69, 0x4f, 0x36, 0x76, 0x41, 0x4a, 0x34, 0x47, 0x4c, 0x67, 0x51, 0x2b, 0x41, 0x33, 0x34, + 0x41, 0x5c, 0x0a, + 0x09, 0x37, 0x41, 0x49, 0x6d, 0x41, 0x39, 0x63, 0x43, 0x52, 0x63, 0x41, 0x7a, 0x77, 0x45, 0x64, 0x4f, 0x50, + 0x43, 0x4d, 0x6e, 0x35, 0x33, 0x52, 0x51, 0x4b, 0x55, 0x44, 0x79, 0x33, 0x41, 0x4b, 0x73, 0x74, 0x76, 0x33, + 0x2f, 0x70, 0x47, 0x33, 0x37, 0x61, 0x65, 0x43, 0x69, 0x36, 0x50, 0x59, 0x30, 0x34, 0x46, 0x74, 0x41, 0x45, + 0x50, 0x67, 0x59, 0x79, 0x49, 0x76, 0x75, 0x72, 0x77, 0x4b, 0x2b, 0x4b, 0x39, 0x62, 0x46, 0x31, 0x46, 0x45, + 0x43, 0x5c, 0x0a, + 0x09, 0x47, 0x41, 0x54, 0x62, 0x32, 0x33, 0x2b, 0x62, 0x62, 0x58, 0x63, 0x6a, 0x38, 0x48, 0x4a, 0x30, 0x65, + 0x79, 0x47, 0x39, 0x6b, 0x51, 0x39, 0x51, 0x43, 0x7a, 0x77, 0x48, 0x2f, 0x49, 0x6e, 0x65, 0x79, 0x41, 0x64, + 0x34, 0x54, 0x5a, 0x43, 0x4c, 0x47, 0x61, 0x45, 0x79, 0x67, 0x63, 0x6c, 0x78, 0x4f, 0x6a, 0x44, 0x54, 0x39, + 0x76, 0x2b, 0x7a, 0x57, 0x47, 0x39, 0x34, 0x4d, 0x66, 0x42, 0x77, 0x54, 0x4e, 0x67, 0x6c, 0x77, 0x44, 0x6a, + 0x67, 0x5c, 0x0a, + 0x09, 0x5a, 0x74, 0x75, 0x2b, 0x52, 0x75, 0x41, 0x78, 0x6b, 0x51, 0x36, 0x6d, 0x69, 0x30, 0x6f, 0x42, 0x45, + 0x6d, 0x42, 0x37, 0x2b, 0x32, 0x2b, 0x4b, 0x4f, 0x66, 0x52, 0x34, 0x39, 0x4f, 0x38, 0x39, 0x77, 0x48, 0x6a, + 0x62, 0x2f, 0x6a, 0x58, 0x41, 0x4a, 0x75, 0x44, 0x76, 0x51, 0x4b, 0x35, 0x74, 0x2f, 0x2b, 0x2b, 0x41, 0x4c, + 0x67, 0x45, 0x75, 0x5a, 0x6f, 0x7a, 0x6d, 0x5a, 0x49, 0x5a, 0x69, 0x74, 0x47, 0x55, 0x43, 0x6f, 0x77, 0x4c, + 0x49, 0x5c, 0x0a, + 0x09, 0x42, 0x77, 0x35, 0x68, 0x5a, 0x65, 0x51, 0x41, 0x74, 0x6d, 0x47, 0x6c, 0x43, 0x46, 0x4f, 0x78, 0x6b, + 0x76, 0x75, 0x65, 0x6c, 0x36, 0x67, 0x4e, 0x6d, 0x49, 0x4c, 0x31, 0x72, 0x58, 0x2f, 0x4c, 0x5a, 0x71, 0x59, + 0x6d, 0x47, 0x74, 0x37, 0x77, 0x6e, 0x44, 0x4c, 0x50, 0x45, 0x62, 0x2b, 0x79, 0x4d, 0x68, 0x4e, 0x6f, 0x65, + 0x35, 0x75, 0x79, 0x6a, 0x61, 0x76, 0x6f, 0x6a, 0x58, 0x7a, 0x6f, 0x66, 0x66, 0x76, 0x76, 0x70, 0x65, 0x2f, + 0x7a, 0x5c, 0x0a, + 0x09, 0x75, 0x78, 0x38, 0x49, 0x41, 0x33, 0x2b, 0x31, 0x37, 0x64, 0x4f, 0x42, 0x47, 0x77, 0x45, 0x44, 0x42, + 0x6e, 0x38, 0x47, 0x54, 0x67, 0x6b, 0x6b, 0x46, 0x59, 0x51, 0x4c, 0x49, 0x4f, 0x61, 0x6d, 0x35, 0x77, 0x49, + 0x6e, 0x70, 0x47, 0x6d, 0x71, 0x6d, 0x4f, 0x48, 0x4a, 0x73, 0x39, 0x78, 0x75, 0x32, 0x77, 0x34, 0x42, 0x70, + 0x63, 0x42, 0x39, 0x57, 0x4a, 0x6d, 0x2f, 0x48, 0x6a, 0x6f, 0x42, 0x44, 0x61, 0x67, 0x47, 0x4b, 0x6d, 0x33, + 0x37, 0x5c, 0x0a, + 0x09, 0x58, 0x77, 0x46, 0x4f, 0x6a, 0x66, 0x37, 0x73, 0x6d, 0x45, 0x41, 0x72, 0x30, 0x41, 0x45, 0x30, 0x41, + 0x51, 0x65, 0x41, 0x77, 0x37, 0x45, 0x43, 0x47, 0x51, 0x70, 0x42, 0x43, 0x50, 0x38, 0x45, 0x52, 0x47, 0x39, + 0x4b, 0x77, 0x38, 0x6f, 0x73, 0x33, 0x65, 0x48, 0x59, 0x78, 0x55, 0x59, 0x66, 0x72, 0x63, 0x41, 0x48, 0x77, + 0x48, 0x2b, 0x77, 0x53, 0x68, 0x46, 0x37, 0x65, 0x77, 0x37, 0x45, 0x43, 0x73, 0x48, 0x52, 0x4f, 0x42, 0x4d, + 0x70, 0x5c, 0x0a, + 0x09, 0x41, 0x4a, 0x75, 0x69, 0x56, 0x77, 0x42, 0x33, 0x4f, 0x33, 0x61, 0x68, 0x30, 0x55, 0x38, 0x45, 0x36, + 0x31, 0x4f, 0x79, 0x6c, 0x47, 0x6a, 0x6d, 0x30, 0x53, 0x34, 0x43, 0x4a, 0x2b, 0x4e, 0x73, 0x4b, 0x4a, 0x4c, + 0x55, 0x4b, 0x75, 0x43, 0x75, 0x49, 0x62, 0x6a, 0x4f, 0x61, 0x4d, 0x49, 0x46, 0x4c, 0x4d, 0x61, 0x71, 0x4f, + 0x33, 0x43, 0x4c, 0x76, 0x70, 0x41, 0x51, 0x62, 0x47, 0x2f, 0x2f, 0x63, 0x67, 0x54, 0x66, 0x78, 0x43, 0x68, + 0x6d, 0x5c, 0x0a, + 0x09, 0x4c, 0x6c, 0x59, 0x6d, 0x56, 0x42, 0x69, 0x69, 0x55, 0x34, 0x41, 0x53, 0x59, 0x49, 0x48, 0x67, 0x61, + 0x34, 0x78, 0x32, 0x7a, 0x68, 0x64, 0x70, 0x58, 0x4c, 0x51, 0x41, 0x76, 0x6f, 0x31, 0x36, 0x2b, 0x7a, 0x4f, + 0x6c, 0x63, 0x76, 0x41, 0x67, 0x36, 0x53, 0x4f, 0x36, 0x47, 0x48, 0x68, 0x61, 0x4d, 0x6f, 0x47, 0x4f, 0x4e, + 0x4c, 0x66, 0x79, 0x35, 0x71, 0x61, 0x74, 0x62, 0x4b, 0x37, 0x35, 0x6c, 0x4c, 0x71, 0x47, 0x4a, 0x67, 0x4b, + 0x36, 0x5c, 0x0a, + 0x09, 0x7a, 0x74, 0x67, 0x79, 0x50, 0x37, 0x4f, 0x6e, 0x54, 0x65, 0x62, 0x43, 0x63, 0x2b, 0x59, 0x77, 0x59, + 0x38, 0x6f, 0x45, 0x77, 0x57, 0x36, 0x4b, 0x34, 0x55, 0x68, 0x7a, 0x4b, 0x32, 0x39, 0x73, 0x66, 0x4a, 0x39, + 0x33, 0x50, 0x39, 0x7a, 0x4a, 0x77, 0x66, 0x70, 0x47, 0x39, 0x46, 0x43, 0x59, 0x69, 0x72, 0x49, 0x53, 0x71, + 0x71, 0x5a, 0x50, 0x59, 0x66, 0x34, 0x35, 0x63, 0x35, 0x67, 0x78, 0x4f, 0x61, 0x6b, 0x53, 0x73, 0x53, 0x37, + 0x53, 0x5c, 0x0a, + 0x09, 0x52, 0x32, 0x47, 0x6c, 0x67, 0x47, 0x67, 0x65, 0x59, 0x44, 0x56, 0x57, 0x4b, 0x39, 0x71, 0x41, 0x68, + 0x4d, 0x4a, 0x68, 0x56, 0x6a, 0x32, 0x33, 0x6a, 0x69, 0x64, 0x65, 0x65, 0x6f, 0x76, 0x75, 0x59, 0x50, 0x7a, + 0x37, 0x6e, 0x48, 0x66, 0x6d, 0x62, 0x4f, 0x36, 0x36, 0x39, 0x56, 0x71, 0x4f, 0x48, 0x54, 0x66, 0x47, 0x4d, + 0x56, 0x39, 0x46, 0x6f, 0x6f, 0x66, 0x43, 0x50, 0x50, 0x4c, 0x73, 0x79, 0x7a, 0x7a, 0x31, 0x79, 0x72, 0x38, + 0x4a, 0x5c, 0x0a, + 0x09, 0x36, 0x71, 0x47, 0x34, 0x34, 0x63, 0x34, 0x2f, 0x71, 0x34, 0x72, 0x66, 0x4c, 0x76, 0x6b, 0x78, 0x34, + 0x79, 0x76, 0x4b, 0x45, 0x70, 0x6c, 0x37, 0x42, 0x62, 0x67, 0x38, 0x57, 0x30, 0x73, 0x42, 0x68, 0x66, 0x45, + 0x4f, 0x64, 0x48, 0x52, 0x31, 0x73, 0x32, 0x6a, 0x35, 0x53, 0x6c, 0x59, 0x39, 0x76, 0x79, 0x35, 0x68, 0x35, + 0x41, 0x4f, 0x73, 0x33, 0x37, 0x4b, 0x44, 0x42, 0x58, 0x66, 0x65, 0x77, 0x34, 0x65, 0x66, 0x37, 0x58, 0x48, + 0x63, 0x5c, 0x0a, + 0x09, 0x51, 0x61, 0x64, 0x70, 0x37, 0x2b, 0x7a, 0x6d, 0x68, 0x74, 0x38, 0x38, 0x79, 0x4b, 0x4e, 0x72, 0x33, + 0x30, 0x67, 0x59, 0x2b, 0x51, 0x42, 0x76, 0x76, 0x31, 0x66, 0x44, 0x67, 0x6a, 0x74, 0x57, 0x55, 0x4c, 0x74, + 0x37, 0x62, 0x36, 0x4a, 0x67, 0x63, 0x5a, 0x2b, 0x68, 0x45, 0x34, 0x67, 0x57, 0x67, 0x44, 0x2f, 0x65, 0x67, + 0x57, 0x55, 0x72, 0x48, 0x2b, 0x57, 0x44, 0x32, 0x6c, 0x31, 0x4a, 0x47, 0x32, 0x70, 0x74, 0x37, 0x2b, 0x53, + 0x57, 0x5c, 0x0a, + 0x09, 0x75, 0x78, 0x2b, 0x6d, 0x72, 0x71, 0x48, 0x4a, 0x45, 0x63, 0x64, 0x45, 0x59, 0x4a, 0x6f, 0x6d, 0x53, + 0x78, 0x39, 0x59, 0x52, 0x63, 0x33, 0x4f, 0x33, 0x55, 0x6d, 0x66, 0x30, 0x39, 0x7a, 0x57, 0x77, 0x65, 0x4b, + 0x37, 0x48, 0x36, 0x61, 0x68, 0x71, 0x54, 0x56, 0x65, 0x6b, 0x48, 0x47, 0x4f, 0x4f, 0x42, 0x65, 0x48, 0x6f, + 0x53, 0x67, 0x46, 0x39, 0x4f, 0x4f, 0x74, 0x54, 0x64, 0x75, 0x6f, 0x66, 0x76, 0x2f, 0x44, 0x6c, 0x49, 0x32, + 0x31, 0x5c, 0x0a, + 0x09, 0x74, 0x48, 0x65, 0x77, 0x63, 0x73, 0x33, 0x61, 0x6a, 0x4a, 0x30, 0x53, 0x78, 0x65, 0x73, 0x62, 0x33, + 0x32, 0x66, 0x54, 0x39, 0x74, 0x71, 0x55, 0x7a, 0x32, 0x74, 0x73, 0x61, 0x57, 0x50, 0x6c, 0x45, 0x33, 0x48, + 0x76, 0x71, 0x77, 0x4c, 0x45, 0x74, 0x61, 0x55, 0x4d, 0x69, 0x77, 0x42, 0x57, 0x76, 0x2f, 0x42, 0x36, 0x32, + 0x67, 0x5a, 0x66, 0x33, 0x37, 0x69, 0x46, 0x2f, 0x59, 0x63, 0x61, 0x30, 0x6a, 0x35, 0x66, 0x4a, 0x4a, 0x6e, + 0x63, 0x5c, 0x0a, + 0x09, 0x31, 0x36, 0x76, 0x56, 0x37, 0x33, 0x4b, 0x77, 0x6f, 0x58, 0x47, 0x67, 0x51, 0x78, 0x55, 0x49, 0x6a, + 0x43, 0x66, 0x52, 0x41, 0x69, 0x69, 0x4e, 0x33, 0x56, 0x48, 0x58, 0x30, 0x45, 0x54, 0x74, 0x46, 0x31, 0x39, + 0x6c, 0x5a, 0x48, 0x54, 0x39, 0x6c, 0x68, 0x30, 0x5a, 0x6e, 0x53, 0x2b, 0x43, 0x66, 0x58, 0x58, 0x31, 0x66, + 0x4c, 0x37, 0x33, 0x36, 0x37, 0x54, 0x50, 0x4e, 0x30, 0x32, 0x54, 0x64, 0x77, 0x5a, 0x4f, 0x46, 0x56, 0x31, + 0x41, 0x5c, 0x0a, + 0x09, 0x65, 0x64, 0x71, 0x47, 0x42, 0x30, 0x47, 0x49, 0x41, 0x47, 0x7a, 0x4a, 0x56, 0x55, 0x58, 0x73, 0x73, + 0x53, 0x2f, 0x32, 0x31, 0x32, 0x56, 0x73, 0x66, 0x34, 0x38, 0x44, 0x4e, 0x70, 0x78, 0x6d, 0x37, 0x34, 0x48, + 0x44, 0x47, 0x64, 0x76, 0x59, 0x76, 0x65, 0x39, 0x67, 0x76, 0x45, 0x4e, 0x78, 0x38, 0x31, 0x4b, 0x5a, 0x49, + 0x6a, 0x49, 0x46, 0x38, 0x41, 0x4f, 0x2b, 0x32, 0x4a, 0x33, 0x74, 0x6e, 0x5a, 0x6c, 0x33, 0x6a, 0x47, 0x6c, + 0x70, 0x5c, 0x0a, + 0x09, 0x37, 0x38, 0x7a, 0x59, 0x68, 0x74, 0x4f, 0x30, 0x74, 0x48, 0x64, 0x6b, 0x62, 0x4b, 0x4d, 0x74, 0x2f, + 0x72, 0x50, 0x4a, 0x53, 0x67, 0x45, 0x4d, 0x6d, 0x48, 0x73, 0x74, 0x39, 0x78, 0x64, 0x6e, 0x62, 0x4c, 0x69, + 0x69, 0x64, 0x4d, 0x43, 0x73, 0x78, 0x62, 0x41, 0x79, 0x78, 0x67, 0x47, 0x66, 0x45, 0x74, 0x78, 0x58, 0x76, + 0x30, 0x2b, 0x70, 0x55, 0x34, 0x67, 0x55, 0x77, 0x4e, 0x69, 0x42, 0x64, 0x70, 0x34, 0x30, 0x6f, 0x52, 0x4b, + 0x33, 0x5c, 0x0a, + 0x09, 0x4f, 0x37, 0x50, 0x4c, 0x7a, 0x6a, 0x67, 0x78, 0x33, 0x54, 0x34, 0x6c, 0x34, 0x70, 0x67, 0x32, 0x38, + 0x54, 0x68, 0x63, 0x47, 0x58, 0x61, 0x4a, 0x4f, 0x7a, 0x6c, 0x2b, 0x7a, 0x61, 0x41, 0x66, 0x78, 0x4a, 0x51, + 0x45, 0x48, 0x4b, 0x38, 0x4b, 0x74, 0x6a, 0x6b, 0x35, 0x66, 0x71, 0x44, 0x6a, 0x4a, 0x55, 0x55, 0x46, 0x6e, + 0x48, 0x76, 0x71, 0x4b, 0x57, 0x7a, 0x59, 0x2b, 0x6c, 0x46, 0x61, 0x39, 0x6e, 0x4e, 0x38, 0x58, 0x75, 0x61, + 0x64, 0x5c, 0x0a, + 0x09, 0x4d, 0x54, 0x75, 0x6c, 0x63, 0x77, 0x34, 0x32, 0x4e, 0x4c, 0x4c, 0x70, 0x67, 0x30, 0x2f, 0x34, 0x71, + 0x71, 0x36, 0x65, 0x6c, 0x72, 0x59, 0x4f, 0x75, 0x67, 0x4a, 0x42, 0x79, 0x35, 0x62, 0x58, 0x69, 0x38, 0x75, + 0x6c, 0x55, 0x5a, 0x43, 0x66, 0x52, 0x32, 0x6c, 0x78, 0x49, 0x65, 0x50, 0x4b, 0x53, 0x7a, 0x6c, 0x2b, 0x2f, + 0x46, 0x69, 0x6d, 0x54, 0x54, 0x79, 0x4f, 0x6f, 0x6f, 0x4b, 0x38, 0x51, 0x61, 0x7a, 0x32, 0x70, 0x61, 0x79, + 0x6b, 0x5c, 0x0a, + 0x09, 0x69, 0x4c, 0x4f, 0x72, 0x54, 0x6b, 0x36, 0x72, 0x47, 0x41, 0x69, 0x51, 0x6c, 0x2b, 0x50, 0x6a, 0x76, + 0x4e, 0x4e, 0x6e, 0x78, 0x54, 0x73, 0x38, 0x43, 0x2f, 0x67, 0x6e, 0x59, 0x44, 0x67, 0x74, 0x41, 0x6b, 0x63, + 0x46, 0x59, 0x48, 0x4e, 0x75, 0x46, 0x76, 0x31, 0x37, 0x30, 0x68, 0x37, 0x6c, 0x7a, 0x75, 0x73, 0x75, 0x5a, + 0x2b, 0x4f, 0x32, 0x6a, 0x39, 0x4f, 0x71, 0x30, 0x76, 0x7a, 0x70, 0x67, 0x67, 0x73, 0x70, 0x4b, 0x53, 0x70, + 0x49, 0x5c, 0x0a, + 0x09, 0x4f, 0x6e, 0x77, 0x6f, 0x48, 0x4f, 0x62, 0x79, 0x32, 0x31, 0x66, 0x51, 0x6d, 0x6b, 0x4b, 0x2b, 0x51, + 0x64, 0x4d, 0x30, 0x4c, 0x6a, 0x33, 0x76, 0x4c, 0x46, 0x59, 0x75, 0x57, 0x35, 0x79, 0x53, 0x62, 0x33, 0x64, + 0x63, 0x74, 0x79, 0x42, 0x74, 0x41, 0x64, 0x78, 0x38, 0x31, 0x66, 0x63, 0x53, 0x69, 0x57, 0x34, 0x35, 0x63, + 0x41, 0x50, 0x77, 0x4b, 0x2b, 0x42, 0x35, 0x6f, 0x37, 0x62, 0x61, 0x73, 0x53, 0x46, 0x6d, 0x6a, 0x6e, 0x30, + 0x43, 0x5c, 0x0a, + 0x09, 0x62, 0x47, 0x50, 0x6e, 0x48, 0x73, 0x44, 0x71, 0x43, 0x54, 0x73, 0x2f, 0x58, 0x74, 0x67, 0x5a, 0x55, + 0x79, 0x5a, 0x77, 0x36, 0x38, 0x4a, 0x4c, 0x55, 0x72, 0x37, 0x47, 0x39, 0x45, 0x6e, 0x48, 0x73, 0x2b, 0x53, + 0x48, 0x33, 0x30, 0x2f, 0x70, 0x6e, 0x4b, 0x62, 0x57, 0x39, 0x70, 0x51, 0x69, 0x48, 0x36, 0x77, 0x69, 0x32, + 0x61, 0x76, 0x56, 0x37, 0x31, 0x4c, 0x66, 0x31, 0x4a, 0x4c, 0x53, 0x65, 0x62, 0x4e, 0x4f, 0x6d, 0x73, 0x54, + 0x4e, 0x5c, 0x0a, + 0x09, 0x56, 0x31, 0x34, 0x30, 0x65, 0x4d, 0x41, 0x59, 0x5a, 0x6b, 0x36, 0x64, 0x79, 0x4f, 0x4b, 0x72, 0x4c, + 0x68, 0x34, 0x73, 0x57, 0x43, 0x58, 0x57, 0x61, 0x4b, 0x51, 0x4a, 0x4b, 0x56, 0x38, 0x67, 0x41, 0x55, 0x37, + 0x6e, 0x41, 0x61, 0x34, 0x44, 0x66, 0x6f, 0x33, 0x56, 0x42, 0x7a, 0x41, 0x68, 0x53, 0x36, 0x39, 0x66, 0x77, + 0x45, 0x31, 0x58, 0x4a, 0x50, 0x2b, 0x77, 0x5a, 0x6b, 0x36, 0x64, 0x79, 0x4a, 0x72, 0x37, 0x66, 0x6b, 0x6d, + 0x75, 0x5c, 0x0a, + 0x09, 0x72, 0x31, 0x2f, 0x42, 0x49, 0x69, 0x48, 0x6a, 0x79, 0x6b, 0x75, 0x70, 0x54, 0x4b, 0x4d, 0x52, 0x36, + 0x5a, 0x69, 0x78, 0x35, 0x57, 0x6c, 0x6c, 0x4e, 0x70, 0x66, 0x39, 0x35, 0x47, 0x6f, 0x57, 0x58, 0x5a, 0x62, + 0x38, 0x43, 0x4c, 0x43, 0x71, 0x61, 0x5a, 0x4e, 0x35, 0x64, 0x4d, 0x56, 0x53, 0x63, 0x6e, 0x7a, 0x65, 0x5a, + 0x49, 0x4c, 0x6e, 0x41, 0x41, 0x2b, 0x6c, 0x37, 0x46, 0x51, 0x43, 0x48, 0x47, 0x73, 0x4e, 0x6a, 0x4b, 0x59, + 0x41, 0x5c, 0x0a, + 0x09, 0x37, 0x77, 0x46, 0x6e, 0x70, 0x6e, 0x4c, 0x65, 0x66, 0x32, 0x74, 0x71, 0x57, 0x62, 0x6c, 0x6d, 0x4c, + 0x54, 0x76, 0x33, 0x37, 0x42, 0x76, 0x77, 0x75, 0x4c, 0x2b, 0x6f, 0x6b, 0x4d, 0x56, 0x58, 0x58, 0x38, 0x79, + 0x69, 0x79, 0x79, 0x37, 0x41, 0x36, 0x30, 0x6e, 0x76, 0x69, 0x2f, 0x57, 0x76, 0x54, 0x56, 0x75, 0x35, 0x38, + 0x34, 0x39, 0x2f, 0x54, 0x6a, 0x71, 0x38, 0x53, 0x39, 0x4e, 0x59, 0x76, 0x57, 0x49, 0x70, 0x33, 0x7a, 0x6c, + 0x74, 0x5c, 0x0a, + 0x09, 0x35, 0x75, 0x43, 0x42, 0x34, 0x37, 0x42, 0x78, 0x32, 0x38, 0x63, 0x38, 0x39, 0x4f, 0x53, 0x4c, 0x2f, + 0x4f, 0x2f, 0x4c, 0x2f, 0x51, 0x4d, 0x65, 0x39, 0x78, 0x63, 0x56, 0x73, 0x75, 0x53, 0x61, 0x53, 0x37, 0x6a, + 0x2b, 0x30, 0x67, 0x76, 0x77, 0x65, 0x46, 0x4c, 0x71, 0x4d, 0x74, 0x45, 0x4e, 0x35, 0x44, 0x76, 0x31, 0x43, + 0x58, 0x42, 0x61, 0x41, 0x44, 0x71, 0x51, 0x6c, 0x4a, 0x52, 0x6a, 0x32, 0x62, 0x6c, 0x6e, 0x48, 0x35, 0x74, + 0x33, 0x5c, 0x0a, + 0x09, 0x66, 0x45, 0x70, 0x64, 0x66, 0x52, 0x4e, 0x36, 0x4b, 0x4d, 0x53, 0x59, 0x30, 0x68, 0x4b, 0x71, 0x70, + 0x6b, 0x2f, 0x6d, 0x7a, 0x47, 0x39, 0x4f, 0x78, 0x2b, 0x66, 0x4e, 0x50, 0x4b, 0x76, 0x79, 0x7a, 0x4c, 0x71, + 0x33, 0x2b, 0x63, 0x4e, 0x6a, 0x7a, 0x32, 0x45, 0x59, 0x6b, 0x59, 0x54, 0x68, 0x78, 0x70, 0x62, 0x35, 0x75, + 0x66, 0x66, 0x32, 0x52, 0x63, 0x77, 0x39, 0x49, 0x32, 0x36, 0x47, 0x4c, 0x47, 0x6c, 0x4d, 0x30, 0x32, 0x54, + 0x6e, 0x5c, 0x0a, + 0x09, 0x6e, 0x76, 0x31, 0x73, 0x72, 0x71, 0x6e, 0x6c, 0x30, 0x4a, 0x46, 0x6d, 0x39, 0x46, 0x43, 0x49, 0x69, + 0x6a, 0x49, 0x2f, 0x73, 0x36, 0x64, 0x4e, 0x79, 0x76, 0x53, 0x2b, 0x74, 0x4a, 0x45, 0x71, 0x67, 0x42, 0x47, + 0x39, 0x46, 0x76, 0x32, 0x65, 0x72, 0x2b, 0x74, 0x34, 0x2f, 0x4d, 0x55, 0x33, 0x57, 0x62, 0x39, 0x6c, 0x42, + 0x38, 0x31, 0x74, 0x76, 0x52, 0x55, 0x33, 0x65, 0x62, 0x6b, 0x35, 0x7a, 0x44, 0x70, 0x70, 0x45, 0x76, 0x50, + 0x50, 0x5c, 0x0a, + 0x09, 0x6e, 0x73, 0x4f, 0x56, 0x38, 0x38, 0x39, 0x4e, 0x2b, 0x54, 0x4d, 0x7a, 0x78, 0x4f, 0x77, 0x43, 0x70, + 0x6f, 0x35, 0x55, 0x41, 0x65, 0x77, 0x44, 0x6a, 0x6e, 0x50, 0x45, 0x6f, 0x47, 0x43, 0x4f, 0x4e, 0x4c, 0x63, + 0x53, 0x31, 0x45, 0x50, 0x6b, 0x35, 0x76, 0x67, 0x63, 0x71, 0x5a, 0x77, 0x61, 0x51, 0x6d, 0x34, 0x45, 0x6e, + 0x68, 0x70, 0x78, 0x70, 0x59, 0x41, 0x6f, 0x54, 0x7a, 0x6c, 0x73, 0x54, 0x78, 0x68, 0x6a, 0x53, 0x6b, 0x73, + 0x34, 0x5c, 0x0a, + 0x09, 0x64, 0x74, 0x79, 0x59, 0x62, 0x49, 0x72, 0x38, 0x49, 0x50, 0x41, 0x4c, 0x48, 0x48, 0x37, 0x47, 0x54, + 0x6c, 0x63, 0x45, 0x2f, 0x52, 0x35, 0x72, 0x54, 0x50, 0x7a, 0x50, 0x36, 0x54, 0x73, 0x32, 0x58, 0x70, 0x45, + 0x5a, 0x6e, 0x77, 0x49, 0x58, 0x41, 0x48, 0x58, 0x67, 0x37, 0x44, 0x51, 0x7a, 0x54, 0x71, 0x63, 0x41, 0x4f, + 0x72, 0x43, 0x4d, 0x4a, 0x44, 0x75, 0x44, 0x4b, 0x70, 0x4a, 0x6d, 0x46, 0x39, 0x48, 0x49, 0x64, 0x33, 0x71, + 0x38, 0x5c, 0x0a, + 0x09, 0x6f, 0x47, 0x4d, 0x43, 0x63, 0x4d, 0x2b, 0x59, 0x61, 0x33, 0x63, 0x75, 0x61, 0x39, 0x4c, 0x56, 0x62, + 0x45, 0x4c, 0x45, 0x59, 0x46, 0x46, 0x52, 0x6a, 0x55, 0x48, 0x43, 0x6d, 0x69, 0x38, 0x6c, 0x4a, 0x53, 0x6a, + 0x4b, 0x73, 0x42, 0x4a, 0x41, 0x64, 0x74, 0x41, 0x74, 0x79, 0x72, 0x44, 0x6a, 0x41, 0x6a, 0x41, 0x30, 0x4e, + 0x79, 0x67, 0x42, 0x4f, 0x45, 0x33, 0x32, 0x43, 0x43, 0x44, 0x67, 0x4b, 0x79, 0x62, 0x6f, 0x7a, 0x5a, 0x38, + 0x51, 0x5c, 0x0a, + 0x09, 0x30, 0x64, 0x54, 0x38, 0x55, 0x77, 0x34, 0x69, 0x37, 0x42, 0x50, 0x67, 0x65, 0x48, 0x2b, 0x41, 0x7a, + 0x6c, 0x77, 0x2f, 0x59, 0x58, 0x66, 0x75, 0x54, 0x4e, 0x32, 0x54, 0x69, 0x79, 0x2f, 0x63, 0x54, 0x55, 0x36, + 0x6f, 0x4d, 0x2f, 0x72, 0x72, 0x77, 0x6d, 0x73, 0x45, 0x6e, 0x4c, 0x36, 0x63, 0x4c, 0x41, 0x6a, 0x72, 0x42, + 0x75, 0x32, 0x34, 0x41, 0x41, 0x4c, 0x65, 0x59, 0x69, 0x49, 0x75, 0x64, 0x77, 0x65, 0x41, 0x37, 0x73, 0x6c, + 0x48, 0x5c, 0x0a, + 0x09, 0x39, 0x2b, 0x54, 0x54, 0x6e, 0x6d, 0x66, 0x31, 0x44, 0x58, 0x57, 0x5a, 0x42, 0x72, 0x35, 0x51, 0x46, + 0x7a, 0x6e, 0x68, 0x4c, 0x6e, 0x4a, 0x43, 0x6e, 0x66, 0x6a, 0x43, 0x58, 0x58, 0x67, 0x4d, 0x6f, 0x55, 0x50, + 0x66, 0x52, 0x67, 0x73, 0x62, 0x75, 0x6e, 0x4c, 0x45, 0x64, 0x49, 0x4e, 0x7a, 0x58, 0x41, 0x41, 0x52, 0x6c, + 0x78, 0x75, 0x73, 0x5a, 0x73, 0x76, 0x2b, 0x78, 0x7a, 0x51, 0x33, 0x41, 0x56, 0x38, 0x52, 0x41, 0x56, 0x2f, + 0x76, 0x5c, 0x0a, + 0x09, 0x6e, 0x45, 0x75, 0x75, 0x53, 0x42, 0x68, 0x66, 0x75, 0x4e, 0x76, 0x32, 0x36, 0x38, 0x4a, 0x72, 0x42, + 0x4e, 0x48, 0x4d, 0x78, 0x49, 0x30, 0x32, 0x32, 0x59, 0x6a, 0x68, 0x38, 0x68, 0x44, 0x52, 0x50, 0x45, 0x52, + 0x63, 0x48, 0x69, 0x4b, 0x61, 0x47, 0x38, 0x50, 0x6c, 0x4a, 0x71, 0x4b, 0x35, 0x69, 0x66, 0x54, 0x38, 0x31, + 0x54, 0x79, 0x39, 0x32, 0x30, 0x66, 0x33, 0x75, 0x55, 0x30, 0x30, 0x7a, 0x5a, 0x38, 0x58, 0x6a, 0x44, 0x74, + 0x79, 0x5c, 0x0a, + 0x09, 0x4b, 0x43, 0x4f, 0x47, 0x66, 0x5a, 0x37, 0x41, 0x69, 0x4d, 0x76, 0x54, 0x54, 0x78, 0x51, 0x41, 0x48, + 0x6b, 0x50, 0x48, 0x61, 0x77, 0x54, 0x77, 0x47, 0x67, 0x45, 0x38, 0x68, 0x6f, 0x37, 0x62, 0x43, 0x4f, 0x47, + 0x4a, 0x36, 0x48, 0x67, 0x4d, 0x48, 0x5a, 0x63, 0x5a, 0x52, 0x6e, 0x4e, 0x77, 0x67, 0x47, 0x53, 0x6d, 0x68, + 0x4e, 0x30, 0x2b, 0x51, 0x75, 0x35, 0x63, 0x77, 0x6d, 0x34, 0x66, 0x68, 0x73, 0x73, 0x62, 0x2f, 0x56, 0x6b, + 0x52, 0x5c, 0x0a, + 0x09, 0x33, 0x52, 0x50, 0x70, 0x68, 0x69, 0x76, 0x39, 0x6c, 0x6a, 0x39, 0x67, 0x59, 0x57, 0x64, 0x4f, 0x71, + 0x5a, 0x43, 0x5a, 0x52, 0x6b, 0x55, 0x4a, 0x6f, 0x44, 0x6c, 0x54, 0x41, 0x32, 0x47, 0x33, 0x6a, 0x37, 0x44, + 0x62, 0x52, 0x33, 0x65, 0x63, 0x4f, 0x69, 0x58, 0x4e, 0x6a, 0x4b, 0x43, 0x6c, 0x30, 0x50, 0x69, 0x6f, 0x6d, + 0x5a, 0x45, 0x2b, 0x6f, 0x6e, 0x47, 0x5a, 0x52, 0x6d, 0x4a, 0x62, 0x70, 0x6f, 0x6b, 0x72, 0x51, 0x53, 0x6f, + 0x55, 0x5c, 0x0a, + 0x09, 0x63, 0x62, 0x6b, 0x78, 0x30, 0x51, 0x69, 0x35, 0x63, 0x34, 0x69, 0x6b, 0x48, 0x37, 0x6e, 0x4a, 0x55, + 0x6f, 0x57, 0x67, 0x4f, 0x52, 0x68, 0x46, 0x65, 0x66, 0x36, 0x6c, 0x49, 0x4c, 0x74, 0x48, 0x4d, 0x54, 0x56, + 0x58, 0x61, 0x6d, 0x33, 0x50, 0x57, 0x6c, 0x62, 0x50, 0x55, 0x31, 0x45, 0x30, 0x65, 0x4a, 0x44, 0x30, 0x45, + 0x46, 0x56, 0x57, 0x57, 0x79, 0x66, 0x49, 0x72, 0x71, 0x77, 0x63, 0x45, 0x47, 0x56, 0x59, 0x6c, 0x41, 0x42, + 0x71, 0x5c, 0x0a, + 0x09, 0x67, 0x41, 0x32, 0x43, 0x62, 0x4d, 0x76, 0x49, 0x64, 0x6c, 0x47, 0x47, 0x48, 0x52, 0x66, 0x41, 0x6c, + 0x4c, 0x46, 0x48, 0x4b, 0x77, 0x47, 0x58, 0x4f, 0x32, 0x31, 0x62, 0x59, 0x6f, 0x53, 0x39, 0x54, 0x43, 0x4b, + 0x72, 0x36, 0x7a, 0x59, 0x44, 0x4c, 0x77, 0x69, 0x30, 0x4c, 0x77, 0x73, 0x6d, 0x73, 0x46, 0x47, 0x55, 0x63, + 0x53, 0x45, 0x43, 0x73, 0x4b, 0x55, 0x43, 0x74, 0x77, 0x46, 0x48, 0x52, 0x46, 0x78, 0x44, 0x49, 0x72, 0x59, + 0x44, 0x5c, 0x0a, + 0x09, 0x39, 0x61, 0x4b, 0x4d, 0x69, 0x36, 0x36, 0x77, 0x62, 0x79, 0x44, 0x42, 0x4a, 0x46, 0x47, 0x4b, 0x70, + 0x48, 0x67, 0x4e, 0x2b, 0x72, 0x78, 0x55, 0x6a, 0x69, 0x4a, 0x4d, 0x41, 0x44, 0x61, 0x48, 0x58, 0x77, 0x49, + 0x65, 0x46, 0x48, 0x57, 0x64, 0x55, 0x59, 0x36, 0x42, 0x34, 0x48, 0x36, 0x57, 0x51, 0x6c, 0x4f, 0x41, 0x6d, + 0x41, 0x7a, 0x68, 0x79, 0x4a, 0x33, 0x63, 0x5a, 0x2b, 0x54, 0x79, 0x4f, 0x49, 0x4c, 0x72, 0x56, 0x49, 0x61, + 0x71, 0x5c, 0x0a, + 0x09, 0x7a, 0x64, 0x59, 0x41, 0x66, 0x6f, 0x51, 0x31, 0x61, 0x62, 0x52, 0x71, 0x2f, 0x55, 0x6d, 0x4f, 0x74, + 0x56, 0x69, 0x39, 0x67, 0x49, 0x55, 0x6c, 0x2f, 0x7a, 0x41, 0x45, 0x41, 0x72, 0x41, 0x35, 0x62, 0x32, 0x43, + 0x74, 0x71, 0x6e, 0x45, 0x69, 0x38, 0x42, 0x63, 0x45, 0x64, 0x6e, 0x4c, 0x49, 0x59, 0x68, 0x71, 0x42, 0x52, + 0x37, 0x42, 0x47, 0x56, 0x79, 0x39, 0x6b, 0x43, 0x4e, 0x59, 0x5a, 0x47, 0x74, 0x49, 0x31, 0x67, 0x33, 0x62, + 0x58, 0x5c, 0x0a, + 0x09, 0x39, 0x78, 0x6c, 0x74, 0x57, 0x77, 0x70, 0x63, 0x44, 0x56, 0x79, 0x44, 0x4e, 0x53, 0x76, 0x32, 0x36, + 0x46, 0x70, 0x77, 0x4b, 0x48, 0x6b, 0x61, 0x73, 0x47, 0x70, 0x4f, 0x31, 0x77, 0x4a, 0x76, 0x59, 0x36, 0x31, + 0x4b, 0x41, 0x73, 0x52, 0x2f, 0x38, 0x37, 0x4e, 0x6d, 0x77, 0x59, 0x68, 0x34, 0x32, 0x49, 0x56, 0x51, 0x45, + 0x47, 0x6a, 0x45, 0x33, 0x33, 0x56, 0x34, 0x56, 0x64, 0x42, 0x62, 0x38, 0x4c, 0x4d, 0x75, 0x58, 0x77, 0x6b, + 0x42, 0x5c, 0x0a, + 0x09, 0x58, 0x7a, 0x47, 0x6a, 0x76, 0x54, 0x65, 0x52, 0x68, 0x74, 0x6c, 0x67, 0x6f, 0x72, 0x32, 0x49, 0x4e, + 0x65, 0x6e, 0x44, 0x4f, 0x30, 0x54, 0x58, 0x46, 0x4f, 0x70, 0x68, 0x73, 0x43, 0x51, 0x2f, 0x4b, 0x78, 0x65, + 0x4e, 0x73, 0x6d, 0x4f, 0x2f, 0x51, 0x62, 0x33, 0x32, 0x48, 0x56, 0x78, 0x6d, 0x52, 0x50, 0x65, 0x47, 0x41, + 0x78, 0x52, 0x32, 0x4e, 0x32, 0x4b, 0x69, 0x45, 0x66, 0x51, 0x57, 0x48, 0x47, 0x30, 0x69, 0x44, 0x6e, 0x6f, + 0x4b, 0x5c, 0x0a, + 0x09, 0x4d, 0x45, 0x66, 0x42, 0x61, 0x6d, 0x54, 0x65, 0x63, 0x49, 0x42, 0x38, 0x76, 0x59, 0x58, 0x38, 0x59, + 0x43, 0x75, 0x2b, 0x63, 0x50, 0x63, 0x31, 0x6a, 0x59, 0x57, 0x56, 0x31, 0x52, 0x31, 0x35, 0x76, 0x63, 0x50, + 0x57, 0x52, 0x58, 0x37, 0x6e, 0x45, 0x7a, 0x48, 0x73, 0x2f, 0x51, 0x47, 0x69, 0x54, 0x61, 0x35, 0x48, 0x35, + 0x31, 0x62, 0x56, 0x4d, 0x4d, 0x6b, 0x4e, 0x64, 0x5a, 0x41, 0x62, 0x36, 0x6f, 0x44, 0x4f, 0x4f, 0x6b, 0x78, + 0x4e, 0x5c, 0x0a, + 0x09, 0x51, 0x2f, 0x66, 0x6b, 0x30, 0x31, 0x49, 0x77, 0x2f, 0x6d, 0x2f, 0x64, 0x76, 0x75, 0x4a, 0x43, 0x34, + 0x47, 0x77, 0x45, 0x54, 0x35, 0x2f, 0x71, 0x46, 0x4c, 0x6c, 0x36, 0x4f, 0x2f, 0x6c, 0x36, 0x4b, 0x2f, 0x6e, + 0x42, 0x56, 0x6a, 0x78, 0x47, 0x6e, 0x32, 0x35, 0x39, 0x2b, 0x38, 0x76, 0x62, 0x39, 0x2f, 0x4f, 0x4e, 0x45, + 0x36, 0x59, 0x4d, 0x6c, 0x32, 0x74, 0x48, 0x47, 0x58, 0x59, 0x42, 0x52, 0x46, 0x6d, 0x4c, 0x4e, 0x61, 0x79, + 0x73, 0x5c, 0x0a, + 0x09, 0x33, 0x32, 0x75, 0x67, 0x6d, 0x61, 0x61, 0x5a, 0x45, 0x2b, 0x71, 0x38, 0x4e, 0x30, 0x66, 0x76, 0x57, + 0x4b, 0x46, 0x37, 0x38, 0x6a, 0x42, 0x63, 0x58, 0x6f, 0x42, 0x6a, 0x73, 0x65, 0x59, 0x68, 0x6d, 0x42, 0x50, + 0x39, 0x7a, 0x57, 0x5a, 0x6b, 0x69, 0x43, 0x4b, 0x51, 0x70, 0x37, 0x64, 0x36, 0x43, 0x77, 0x49, 0x74, 0x37, + 0x6e, 0x79, 0x39, 0x46, 0x56, 0x63, 0x6b, 0x50, 0x46, 0x43, 0x59, 0x44, 0x63, 0x44, 0x75, 0x56, 0x50, 0x6f, + 0x79, 0x5c, 0x0a, + 0x09, 0x69, 0x47, 0x54, 0x59, 0x46, 0x34, 0x36, 0x30, 0x7a, 0x53, 0x74, 0x55, 0x68, 0x62, 0x58, 0x65, 0x37, + 0x72, 0x6c, 0x59, 0x77, 0x6a, 0x79, 0x45, 0x74, 0x51, 0x44, 0x6a, 0x49, 0x31, 0x69, 0x72, 0x61, 0x65, 0x45, + 0x35, 0x5a, 0x56, 0x35, 0x73, 0x52, 0x74, 0x4a, 0x4f, 0x47, 0x54, 0x41, 0x64, 0x4f, 0x42, 0x6c, 0x72, 0x55, + 0x63, 0x64, 0x4b, 0x4c, 0x4b, 0x45, 0x63, 0x45, 0x39, 0x30, 0x65, 0x73, 0x4a, 0x74, 0x61, 0x6d, 0x68, 0x68, + 0x59, 0x5c, 0x0a, + 0x09, 0x51, 0x37, 0x57, 0x2b, 0x77, 0x68, 0x6f, 0x52, 0x2f, 0x54, 0x6e, 0x57, 0x67, 0x70, 0x4c, 0x56, 0x45, + 0x2b, 0x71, 0x33, 0x50, 0x30, 0x44, 0x66, 0x64, 0x59, 0x62, 0x74, 0x31, 0x41, 0x43, 0x58, 0x41, 0x67, 0x63, + 0x79, 0x47, 0x65, 0x57, 0x54, 0x39, 0x5a, 0x6e, 0x41, 0x57, 0x47, 0x4a, 0x6d, 0x76, 0x76, 0x4a, 0x67, 0x72, + 0x5a, 0x72, 0x56, 0x70, 0x7a, 0x74, 0x4f, 0x6f, 0x67, 0x65, 0x57, 0x51, 0x42, 0x52, 0x32, 0x43, 0x72, 0x46, + 0x6d, 0x5c, 0x0a, + 0x09, 0x4c, 0x69, 0x32, 0x33, 0x2f, 0x66, 0x78, 0x59, 0x67, 0x31, 0x69, 0x4c, 0x67, 0x49, 0x4c, 0x6f, 0x64, + 0x73, 0x2f, 0x30, 0x37, 0x47, 0x31, 0x59, 0x53, 0x37, 0x6e, 0x56, 0x59, 0x2b, 0x58, 0x55, 0x44, 0x30, 0x64, + 0x2f, 0x44, 0x56, 0x6a, 0x74, 0x47, 0x2f, 0x30, 0x65, 0x6e, 0x4c, 0x2b, 0x7a, 0x44, 0x6e, 0x39, 0x6e, 0x6e, + 0x51, 0x39, 0x72, 0x6c, 0x62, 0x51, 0x62, 0x73, 0x57, 0x5a, 0x4b, 0x36, 0x77, 0x53, 0x32, 0x59, 0x69, 0x30, + 0x66, 0x5c, 0x0a, + 0x09, 0x2f, 0x7a, 0x54, 0x52, 0x58, 0x50, 0x36, 0x6f, 0x46, 0x45, 0x43, 0x6d, 0x32, 0x43, 0x61, 0x61, 0x41, + 0x70, 0x77, 0x62, 0x42, 0x66, 0x74, 0x46, 0x67, 0x35, 0x67, 0x4f, 0x6c, 0x5a, 0x4d, 0x72, 0x2b, 0x76, 0x62, + 0x55, 0x6a, 0x66, 0x55, 0x2f, 0x48, 0x6b, 0x36, 0x4f, 0x37, 0x73, 0x32, 0x55, 0x45, 0x53, 0x55, 0x41, 0x78, + 0x64, 0x41, 0x7a, 0x75, 0x67, 0x76, 0x63, 0x69, 0x6b, 0x46, 0x52, 0x41, 0x70, 0x41, 0x63, 0x4a, 0x51, 0x44, + 0x4a, 0x5c, 0x0a, + 0x09, 0x55, 0x51, 0x4b, 0x51, 0x48, 0x43, 0x55, 0x41, 0x79, 0x56, 0x45, 0x43, 0x6b, 0x42, 0x77, 0x6c, 0x41, + 0x4d, 0x6c, 0x52, 0x41, 0x70, 0x41, 0x63, 0x4a, 0x51, 0x44, 0x4a, 0x55, 0x51, 0x4b, 0x51, 0x48, 0x43, 0x55, + 0x41, 0x79, 0x56, 0x45, 0x43, 0x6b, 0x42, 0x77, 0x6c, 0x41, 0x4d, 0x6c, 0x52, 0x41, 0x70, 0x41, 0x63, 0x4a, + 0x51, 0x44, 0x4a, 0x55, 0x51, 0x4b, 0x51, 0x48, 0x43, 0x55, 0x41, 0x79, 0x56, 0x45, 0x43, 0x6b, 0x42, 0x77, + 0x6c, 0x5c, 0x0a, + 0x09, 0x41, 0x4d, 0x6c, 0x52, 0x41, 0x70, 0x41, 0x63, 0x4a, 0x51, 0x44, 0x4a, 0x55, 0x51, 0x4b, 0x51, 0x48, + 0x43, 0x55, 0x41, 0x79, 0x56, 0x45, 0x43, 0x6b, 0x42, 0x77, 0x6c, 0x41, 0x4d, 0x6c, 0x52, 0x41, 0x70, 0x41, + 0x63, 0x4a, 0x51, 0x44, 0x4a, 0x55, 0x51, 0x4b, 0x51, 0x48, 0x43, 0x55, 0x41, 0x79, 0x56, 0x45, 0x43, 0x6b, + 0x4a, 0x7a, 0x2f, 0x41, 0x37, 0x77, 0x33, 0x68, 0x35, 0x77, 0x31, 0x62, 0x6c, 0x36, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x5c, 0x0a, + 0x09, 0x41, 0x45, 0x6c, 0x46, 0x54, 0x6b, 0x53, 0x75, 0x51, 0x6d, 0x43, 0x43, 0x5c, 0x0a, + 0x09, 0x22, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, + 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x0a, + 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x4e, + 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x43, 0x41, + 0x59, 0x41, 0x41, 0x41, 0x44, 0x30, 0x65, 0x4e, 0x54, 0x36, 0x41, 0x41, 0x41, 0x67, 0x41, 0x45, 0x6c, 0x45, + 0x51, 0x56, 0x52, 0x34, 0x6e, 0x4f, 0x33, 0x64, 0x65, 0x5a, 0x52, 0x65, 0x64, 0x5a, 0x33, 0x6e, 0x38, 0x58, + 0x63, 0x71, 0x5c, 0x0a, + 0x09, 0x53, 0x55, 0x57, 0x54, 0x6b, 0x41, 0x55, 0x54, 0x49, 0x4c, 0x49, 0x4a, 0x52, 0x43, 0x56, 0x73, 0x41, + 0x72, 0x49, 0x6f, 0x71, 0x43, 0x6a, 0x64, 0x49, 0x4c, 0x59, 0x47, 0x48, 0x52, 0x5a, 0x62, 0x41, 0x52, 0x63, + 0x34, 0x4d, 0x77, 0x67, 0x32, 0x67, 0x69, 0x6a, 0x30, 0x64, 0x47, 0x50, 0x50, 0x61, 0x62, 0x46, 0x48, 0x50, + 0x45, 0x64, 0x45, 0x46, 0x42, 0x64, 0x55, 0x5a, 0x68, 0x6f, 0x50, 0x41, 0x71, 0x32, 0x79, 0x71, 0x4b, 0x67, + 0x6a, 0x5c, 0x0a, + 0x09, 0x41, 0x72, 0x49, 0x70, 0x74, 0x69, 0x41, 0x43, 0x43, 0x67, 0x46, 0x55, 0x61, 0x43, 0x55, 0x43, 0x67, + 0x59, 0x51, 0x6c, 0x4f, 0x34, 0x5a, 0x51, 0x71, 0x66, 0x6e, 0x6a, 0x57, 0x30, 0x55, 0x71, 0x53, 0x53, 0x33, + 0x50, 0x63, 0x75, 0x2f, 0x39, 0x33, 0x65, 0x58, 0x39, 0x4f, 0x75, 0x63, 0x35, 0x57, 0x61, 0x72, 0x79, 0x33, + 0x45, 0x2f, 0x51, 0x33, 0x4f, 0x2f, 0x33, 0x2b, 0x66, 0x37, 0x75, 0x2f, 0x64, 0x31, 0x78, 0x2f, 0x66, 0x33, + 0x39, 0x5c, 0x0a, + 0x09, 0x53, 0x43, 0x71, 0x74, 0x38, 0x63, 0x44, 0x73, 0x49, 0x61, 0x39, 0x5a, 0x77, 0x4f, 0x62, 0x41, 0x54, + 0x47, 0x41, 0x36, 0x4d, 0x41, 0x50, 0x59, 0x44, 0x48, 0x6a, 0x70, 0x77, 0x49, 0x38, 0x76, 0x47, 0x66, 0x4c, + 0x7a, 0x43, 0x51, 0x50, 0x66, 0x4e, 0x39, 0x54, 0x67, 0x31, 0x34, 0x64, 0x36, 0x44, 0x76, 0x6a, 0x72, 0x52, + 0x72, 0x2f, 0x33, 0x4c, 0x50, 0x41, 0x43, 0x73, 0x47, 0x4c, 0x49, 0x31, 0x77, 0x64, 0x2f, 0x76, 0x67, 0x4a, + 0x59, 0x5c, 0x0a, + 0x09, 0x43, 0x69, 0x77, 0x62, 0x2b, 0x4c, 0x35, 0x6e, 0x67, 0x4b, 0x65, 0x41, 0x4a, 0x55, 0x4e, 0x65, 0x66, + 0x52, 0x33, 0x2f, 0x6a, 0x53, 0x55, 0x56, 0x59, 0x70, 0x77, 0x4e, 0x67, 0x4a, 0x54, 0x4d, 0x44, 0x47, 0x43, + 0x37, 0x67, 0x64, 0x65, 0x32, 0x77, 0x44, 0x59, 0x44, 0x50, 0x32, 0x34, 0x4e, 0x62, 0x4d, 0x48, 0x36, 0x6f, + 0x74, 0x2b, 0x54, 0x4b, 0x6d, 0x43, 0x48, 0x2b, 0x6f, 0x48, 0x46, 0x52, 0x43, 0x4f, 0x77, 0x47, 0x48, 0x67, + 0x4d, 0x5c, 0x0a, + 0x09, 0x2b, 0x41, 0x76, 0x77, 0x36, 0x4d, 0x43, 0x50, 0x43, 0x77, 0x64, 0x2b, 0x66, 0x44, 0x5a, 0x56, 0x51, + 0x45, 0x6b, 0x32, 0x41, 0x46, 0x4b, 0x65, 0x78, 0x68, 0x46, 0x46, 0x66, 0x65, 0x36, 0x51, 0x31, 0x34, 0x34, + 0x44, 0x50, 0x2b, 0x35, 0x45, 0x66, 0x45, 0x70, 0x76, 0x73, 0x68, 0x58, 0x41, 0x77, 0x30, 0x4e, 0x65, 0x44, + 0x77, 0x31, 0x35, 0x50, 0x55, 0x6f, 0x30, 0x45, 0x70, 0x4a, 0x79, 0x59, 0x67, 0x4d, 0x67, 0x64, 0x61, 0x38, + 0x48, 0x5c, 0x0a, + 0x09, 0x65, 0x41, 0x57, 0x77, 0x43, 0x37, 0x41, 0x72, 0x4d, 0x41, 0x2f, 0x59, 0x44, 0x64, 0x67, 0x5a, 0x6d, + 0x4a, 0x49, 0x75, 0x56, 0x71, 0x57, 0x74, 0x41, 0x68, 0x34, 0x45, 0x37, 0x67, 0x4d, 0x65, 0x41, 0x42, 0x59, + 0x41, 0x39, 0x77, 0x4e, 0x2f, 0x42, 0x74, 0x61, 0x6c, 0x69, 0x79, 0x58, 0x56, 0x68, 0x77, 0x32, 0x41, 0x31, + 0x4a, 0x35, 0x65, 0x6f, 0x72, 0x6a, 0x76, 0x42, 0x65, 0x77, 0x4e, 0x37, 0x41, 0x6e, 0x73, 0x41, 0x55, 0x78, + 0x4e, 0x5c, 0x0a, + 0x09, 0x47, 0x61, 0x70, 0x42, 0x56, 0x67, 0x4b, 0x2f, 0x41, 0x2b, 0x34, 0x42, 0x37, 0x67, 0x62, 0x75, 0x49, + 0x70, 0x71, 0x45, 0x35, 0x31, 0x4f, 0x47, 0x6b, 0x71, 0x72, 0x49, 0x42, 0x6b, 0x41, 0x61, 0x57, 0x51, 0x2f, + 0x78, 0x4b, 0x66, 0x35, 0x31, 0x77, 0x50, 0x37, 0x41, 0x66, 0x73, 0x51, 0x6e, 0x2f, 0x49, 0x6b, 0x70, 0x51, + 0x32, 0x6b, 0x54, 0x61, 0x34, 0x6e, 0x70, 0x77, 0x4f, 0x30, 0x44, 0x72, 0x31, 0x38, 0x52, 0x30, 0x77, 0x4d, + 0x6e, 0x5c, 0x0a, + 0x09, 0x42, 0x64, 0x49, 0x6f, 0x62, 0x41, 0x43, 0x6b, 0x39, 0x61, 0x59, 0x43, 0x42, 0x77, 0x42, 0x76, 0x49, + 0x49, 0x72, 0x2b, 0x66, 0x73, 0x53, 0x56, 0x39, 0x71, 0x71, 0x65, 0x5a, 0x63, 0x41, 0x64, 0x52, 0x45, 0x50, + 0x77, 0x43, 0x2b, 0x41, 0x32, 0x59, 0x6e, 0x6f, 0x67, 0x61, 0x59, 0x41, 0x4e, 0x67, 0x4a, 0x70, 0x73, 0x42, + 0x76, 0x42, 0x47, 0x34, 0x45, 0x30, 0x44, 0x72, 0x37, 0x32, 0x4a, 0x57, 0x2b, 0x64, 0x55, 0x50, 0x79, 0x38, + 0x51, 0x5c, 0x0a, + 0x09, 0x79, 0x77, 0x57, 0x33, 0x44, 0x72, 0x78, 0x2b, 0x54, 0x74, 0x7a, 0x4b, 0x4b, 0x44, 0x57, 0x57, 0x44, + 0x59, 0x43, 0x61, 0x70, 0x4a, 0x66, 0x34, 0x64, 0x50, 0x2b, 0x33, 0x77, 0x43, 0x46, 0x45, 0x77, 0x61, 0x2f, + 0x61, 0x4c, 0x58, 0x62, 0x4b, 0x78, 0x6a, 0x71, 0x69, 0x49, 0x62, 0x67, 0x65, 0x75, 0x49, 0x47, 0x59, 0x45, + 0x4b, 0x78, 0x4a, 0x6d, 0x6b, 0x67, 0x71, 0x6d, 0x41, 0x32, 0x41, 0x36, 0x6d, 0x35, 0x6e, 0x34, 0x47, 0x31, + 0x45, 0x5c, 0x0a, + 0x09, 0x77, 0x54, 0x38, 0x49, 0x6d, 0x4a, 0x77, 0x32, 0x6a, 0x6b, 0x70, 0x71, 0x4e, 0x58, 0x41, 0x4c, 0x30, + 0x52, 0x42, 0x63, 0x53, 0x39, 0x78, 0x35, 0x49, 0x4e, 0x57, 0x61, 0x44, 0x59, 0x44, 0x71, 0x70, 0x70, 0x63, + 0x6f, 0x39, 0x47, 0x38, 0x48, 0x33, 0x6b, 0x48, 0x63, 0x62, 0x79, 0x2b, 0x31, 0x36, 0x32, 0x48, 0x67, 0x78, + 0x38, 0x43, 0x50, 0x69, 0x4d, 0x62, 0x41, 0x75, 0x77, 0x78, 0x55, 0x4f, 0x7a, 0x59, 0x41, 0x71, 0x6f, 0x4f, + 0x5a, 0x5c, 0x0a, + 0x09, 0x77, 0x4f, 0x48, 0x41, 0x66, 0x4f, 0x42, 0x51, 0x33, 0x47, 0x42, 0x48, 0x32, 0x56, 0x6f, 0x4a, 0x2f, + 0x42, 0x54, 0x34, 0x49, 0x58, 0x41, 0x4e, 0x37, 0x6d, 0x43, 0x6f, 0x6d, 0x72, 0x41, 0x42, 0x55, 0x46, 0x58, + 0x4e, 0x41, 0x74, 0x34, 0x46, 0x48, 0x41, 0x48, 0x38, 0x44, 0x66, 0x48, 0x4a, 0x58, 0x38, 0x72, 0x62, 0x57, + 0x75, 0x41, 0x6d, 0x34, 0x41, 0x72, 0x67, 0x2b, 0x38, 0x51, 0x7a, 0x45, 0x4b, 0x52, 0x4b, 0x73, 0x67, 0x46, + 0x51, 0x5c, 0x0a, + 0x09, 0x6c, 0x62, 0x77, 0x4d, 0x65, 0x44, 0x64, 0x77, 0x46, 0x44, 0x48, 0x6d, 0x48, 0x35, 0x38, 0x32, 0x6a, + 0x68, 0x71, 0x75, 0x6a, 0x31, 0x67, 0x65, 0x75, 0x42, 0x4c, 0x34, 0x4c, 0x76, 0x42, 0x30, 0x32, 0x6a, 0x68, + 0x53, 0x65, 0x32, 0x77, 0x41, 0x56, 0x48, 0x5a, 0x54, 0x67, 0x48, 0x63, 0x43, 0x78, 0x78, 0x44, 0x6a, 0x66, + 0x54, 0x66, 0x68, 0x55, 0x52, 0x6d, 0x74, 0x42, 0x61, 0x34, 0x44, 0x4c, 0x69, 0x65, 0x57, 0x43, 0x64, 0x78, + 0x7a, 0x5c, 0x0a, + 0x09, 0x51, 0x4b, 0x56, 0x6e, 0x41, 0x36, 0x41, 0x79, 0x47, 0x67, 0x2b, 0x38, 0x46, 0x54, 0x69, 0x57, 0x4b, + 0x50, 0x37, 0x75, 0x70, 0x36, 0x38, 0x71, 0x57, 0x51, 0x58, 0x38, 0x41, 0x4c, 0x69, 0x4d, 0x75, 0x48, 0x62, + 0x41, 0x52, 0x79, 0x4f, 0x72, 0x6c, 0x47, 0x77, 0x41, 0x56, 0x43, 0x59, 0x37, 0x41, 0x52, 0x38, 0x45, 0x54, + 0x67, 0x42, 0x65, 0x6e, 0x6a, 0x61, 0x4b, 0x6c, 0x49, 0x6e, 0x48, 0x67, 0x59, 0x73, 0x48, 0x58, 0x67, 0x38, + 0x6e, 0x5c, 0x0a, + 0x09, 0x7a, 0x69, 0x4a, 0x74, 0x77, 0x41, 0x5a, 0x41, 0x71, 0x55, 0x30, 0x42, 0x6a, 0x67, 0x61, 0x4f, 0x4a, + 0x33, 0x62, 0x6c, 0x47, 0x35, 0x63, 0x32, 0x6a, 0x70, 0x53, 0x4c, 0x66, 0x6d, 0x4c, 0x33, 0x77, 0x59, 0x75, + 0x4a, 0x43, 0x77, 0x68, 0x58, 0x70, 0x59, 0x30, 0x6a, 0x32, 0x51, 0x41, 0x6f, 0x6e, 0x56, 0x32, 0x41, 0x6b, + 0x34, 0x44, 0x33, 0x34, 0x33, 0x37, 0x37, 0x61, 0x70, 0x5a, 0x6c, 0x77, 0x43, 0x58, 0x41, 0x31, 0x34, 0x69, + 0x48, 0x5c, 0x0a, + 0x09, 0x47, 0x45, 0x6c, 0x4a, 0x32, 0x41, 0x43, 0x6f, 0x53, 0x4a, 0x4f, 0x49, 0x32, 0x2f, 0x5a, 0x4f, 0x49, + 0x76, 0x62, 0x65, 0x6c, 0x35, 0x72, 0x75, 0x56, 0x71, 0x49, 0x52, 0x75, 0x42, 0x71, 0x33, 0x49, 0x6c, 0x62, + 0x42, 0x62, 0x41, 0x42, 0x55, 0x68, 0x4b, 0x32, 0x41, 0x44, 0x77, 0x4d, 0x6e, 0x41, 0x6c, 0x73, 0x6d, 0x7a, + 0x69, 0x4b, 0x56, 0x30, 0x5a, 0x50, 0x41, 0x4e, 0x34, 0x43, 0x76, 0x41, 0x6b, 0x38, 0x6b, 0x7a, 0x71, 0x4b, + 0x47, 0x5c, 0x0a, + 0x09, 0x73, 0x41, 0x46, 0x51, 0x6e, 0x76, 0x59, 0x47, 0x54, 0x67, 0x50, 0x2b, 0x6e, 0x76, 0x6a, 0x30, 0x4c, + 0x32, 0x6c, 0x30, 0x61, 0x34, 0x44, 0x76, 0x41, 0x46, 0x38, 0x6b, 0x48, 0x6c, 0x59, 0x6b, 0x35, 0x63, 0x59, + 0x47, 0x51, 0x46, 0x6e, 0x72, 0x49, 0x62, 0x62, 0x6b, 0x50, 0x5a, 0x33, 0x59, 0x72, 0x45, 0x64, 0x53, 0x5a, + 0x32, 0x34, 0x42, 0x7a, 0x69, 0x65, 0x32, 0x49, 0x46, 0x36, 0x58, 0x4f, 0x49, 0x74, 0x71, 0x79, 0x41, 0x5a, + 0x41, 0x5c, 0x0a, + 0x09, 0x57, 0x65, 0x6b, 0x6c, 0x37, 0x74, 0x73, 0x2f, 0x45, 0x35, 0x69, 0x58, 0x4f, 0x49, 0x74, 0x55, 0x4a, + 0x77, 0x38, 0x41, 0x35, 0x78, 0x4c, 0x37, 0x43, 0x76, 0x68, 0x51, 0x49, 0x6d, 0x58, 0x47, 0x42, 0x6b, 0x44, + 0x64, 0x32, 0x67, 0x7a, 0x34, 0x48, 0x38, 0x51, 0x6e, 0x2f, 0x6d, 0x30, 0x53, 0x5a, 0x35, 0x48, 0x71, 0x37, + 0x46, 0x46, 0x69, 0x49, 0x6e, 0x41, 0x52, 0x73, 0x43, 0x4a, 0x78, 0x46, 0x74, 0x57, 0x41, 0x44, 0x59, 0x41, + 0x36, 0x5c, 0x0a, + 0x09, 0x4e, 0x52, 0x33, 0x34, 0x4b, 0x48, 0x41, 0x71, 0x73, 0x48, 0x6e, 0x69, 0x4c, 0x46, 0x4b, 0x54, 0x50, + 0x41, 0x4e, 0x63, 0x51, 0x46, 0x77, 0x6e, 0x73, 0x44, 0x52, 0x78, 0x46, 0x6c, 0x57, 0x59, 0x44, 0x59, 0x44, + 0x61, 0x4e, 0x5a, 0x4f, 0x34, 0x73, 0x4f, 0x38, 0x30, 0x59, 0x45, 0x62, 0x69, 0x4c, 0x46, 0x4b, 0x54, 0x4c, + 0x53, 0x57, 0x61, 0x67, 0x43, 0x2f, 0x69, 0x49, 0x34, 0x72, 0x56, 0x41, 0x52, 0x73, 0x41, 0x74, 0x57, 0x6f, + 0x6d, 0x5c, 0x0a, + 0x09, 0x4d, 0x65, 0x59, 0x2f, 0x46, 0x54, 0x66, 0x75, 0x6b, 0x63, 0x70, 0x6b, 0x47, 0x54, 0x45, 0x52, 0x2b, + 0x41, 0x49, 0x78, 0x48, 0x5a, 0x42, 0x61, 0x59, 0x67, 0x4f, 0x67, 0x73, 0x55, 0x77, 0x6c, 0x52, 0x76, 0x30, + 0x66, 0x78, 0x30, 0x2f, 0x38, 0x55, 0x70, 0x6b, 0x74, 0x42, 0x63, 0x34, 0x6a, 0x47, 0x67, 0x47, 0x66, 0x52, + 0x71, 0x67, 0x78, 0x32, 0x51, 0x42, 0x6f, 0x4a, 0x4c, 0x33, 0x45, 0x6a, 0x6e, 0x31, 0x6e, 0x34, 0x65, 0x59, + 0x39, 0x5c, 0x0a, + 0x09, 0x55, 0x70, 0x55, 0x73, 0x42, 0x6a, 0x35, 0x4e, 0x37, 0x44, 0x44, 0x6f, 0x58, 0x51, 0x4d, 0x61, 0x6b, + 0x51, 0x32, 0x41, 0x4e, 0x74, 0x59, 0x44, 0x76, 0x41, 0x38, 0x34, 0x47, 0x39, 0x67, 0x2b, 0x63, 0x52, 0x5a, + 0x4a, 0x6e, 0x58, 0x73, 0x45, 0x2b, 0x43, 0x54, 0x78, 0x33, 0x41, 0x48, 0x33, 0x45, 0x64, 0x41, 0x6d, 0x62, + 0x41, 0x41, 0x30, 0x31, 0x47, 0x48, 0x41, 0x5a, 0x34, 0x41, 0x39, 0x55, 0x77, 0x65, 0x52, 0x6c, 0x4a, 0x6c, + 0x37, 0x5c, 0x0a, + 0x09, 0x67, 0x58, 0x38, 0x45, 0x72, 0x6b, 0x30, 0x64, 0x52, 0x4f, 0x56, 0x69, 0x41, 0x79, 0x43, 0x49, 0x4a, + 0x2f, 0x4f, 0x64, 0x52, 0x7a, 0x51, 0x41, 0x6b, 0x75, 0x72, 0x70, 0x57, 0x75, 0x4a, 0x61, 0x48, 0x70, 0x39, + 0x41, 0x4b, 0x43, 0x44, 0x47, 0x76, 0x57, 0x71, 0x75, 0x4f, 0x63, 0x42, 0x58, 0x67, 0x4e, 0x39, 0x69, 0x38, + 0x5a, 0x66, 0x71, 0x37, 0x6a, 0x44, 0x69, 0x33, 0x2f, 0x72, 0x58, 0x69, 0x58, 0x2f, 0x37, 0x61, 0x6a, 0x67, + 0x6e, 0x5c, 0x0a, + 0x09, 0x41, 0x4d, 0x30, 0x30, 0x67, 0x62, 0x69, 0x64, 0x37, 0x33, 0x2f, 0x68, 0x6c, 0x66, 0x31, 0x53, 0x45, + 0x79, 0x30, 0x44, 0x2f, 0x6f, 0x33, 0x59, 0x51, 0x2b, 0x43, 0x46, 0x78, 0x46, 0x6d, 0x55, 0x69, 0x41, 0x31, + 0x41, 0x38, 0x78, 0x77, 0x4d, 0x66, 0x49, 0x6b, 0x59, 0x2b, 0x30, 0x74, 0x71, 0x74, 0x76, 0x75, 0x4a, 0x44, + 0x77, 0x4d, 0x2f, 0x53, 0x78, 0x31, 0x45, 0x78, 0x58, 0x4d, 0x4a, 0x6f, 0x44, 0x6d, 0x32, 0x41, 0x36, 0x34, + 0x67, 0x5c, 0x0a, + 0x09, 0x2f, 0x71, 0x46, 0x62, 0x2f, 0x43, 0x56, 0x42, 0x6e, 0x41, 0x74, 0x75, 0x41, 0x4b, 0x34, 0x6b, 0x7a, + 0x68, 0x46, 0x71, 0x45, 0x42, 0x75, 0x41, 0x2b, 0x70, 0x73, 0x41, 0x66, 0x49, 0x78, 0x34, 0x6f, 0x74, 0x68, + 0x52, 0x69, 0x62, 0x4e, 0x49, 0x4b, 0x71, 0x63, 0x6a, 0x69, 0x58, 0x50, 0x45, 0x78, 0x34, 0x6c, 0x7a, 0x68, + 0x68, 0x72, 0x41, 0x4a, 0x59, 0x42, 0x36, 0x65, 0x77, 0x33, 0x77, 0x66, 0x34, 0x42, 0x39, 0x55, 0x67, 0x65, + 0x52, 0x5c, 0x0a, + 0x09, 0x56, 0x42, 0x6c, 0x33, 0x45, 0x6b, 0x2f, 0x34, 0x76, 0x43, 0x64, 0x31, 0x45, 0x4f, 0x58, 0x4c, 0x43, + 0x55, 0x41, 0x39, 0x76, 0x52, 0x51, 0x34, 0x68, 0x2f, 0x69, 0x48, 0x62, 0x50, 0x47, 0x58, 0x31, 0x49, 0x35, + 0x39, 0x67, 0x46, 0x38, 0x54, 0x65, 0x34, 0x4b, 0x38, 0x4e, 0x48, 0x45, 0x57, 0x35, 0x63, 0x67, 0x4a, 0x51, + 0x50, 0x32, 0x38, 0x6d, 0x62, 0x6a, 0x4e, 0x35, 0x31, 0x57, 0x4a, 0x63, 0x30, 0x69, 0x71, 0x76, 0x6a, 0x38, + 0x41, 0x5c, 0x0a, + 0x09, 0x48, 0x77, 0x4a, 0x75, 0x54, 0x70, 0x78, 0x44, 0x4f, 0x58, 0x41, 0x43, 0x55, 0x42, 0x38, 0x7a, 0x67, + 0x49, 0x75, 0x41, 0x47, 0x37, 0x48, 0x34, 0x53, 0x38, 0x72, 0x47, 0x71, 0x34, 0x68, 0x7a, 0x79, 0x6b, 0x56, + 0x34, 0x79, 0x33, 0x44, 0x74, 0x4f, 0x41, 0x47, 0x6f, 0x68, 0x79, 0x4f, 0x49, 0x57, 0x2f, 0x74, 0x65, 0x6e, + 0x6a, 0x71, 0x49, 0x70, 0x4e, 0x70, 0x61, 0x42, 0x4a, 0x77, 0x43, 0x58, 0x4a, 0x30, 0x36, 0x69, 0x4c, 0x4a, + 0x68, 0x5c, 0x0a, + 0x09, 0x41, 0x31, 0x42, 0x74, 0x67, 0x7a, 0x76, 0x35, 0x2f, 0x62, 0x66, 0x55, 0x51, 0x53, 0x51, 0x31, 0x78, + 0x76, 0x65, 0x42, 0x44, 0x78, 0x4d, 0x4e, 0x67, 0x53, 0x72, 0x4d, 0x42, 0x71, 0x43, 0x36, 0x6a, 0x67, 0x49, + 0x75, 0x42, 0x47, 0x61, 0x6c, 0x44, 0x69, 0x4b, 0x70, 0x63, 0x5a, 0x34, 0x43, 0x54, 0x69, 0x62, 0x32, 0x44, + 0x31, 0x42, 0x46, 0x65, 0x51, 0x31, 0x41, 0x39, 0x55, 0x77, 0x6e, 0x48, 0x75, 0x39, 0x35, 0x42, 0x52, 0x5a, + 0x2f, 0x5c, 0x0a, + 0x09, 0x53, 0x57, 0x6e, 0x4d, 0x49, 0x73, 0x35, 0x42, 0x6c, 0x78, 0x44, 0x6e, 0x4a, 0x46, 0x57, 0x51, 0x45, + 0x34, 0x42, 0x71, 0x65, 0x51, 0x74, 0x77, 0x4d, 0x62, 0x42, 0x39, 0x36, 0x69, 0x43, 0x53, 0x4e, 0x47, 0x41, + 0x68, 0x38, 0x45, 0x48, 0x67, 0x70, 0x73, 0x51, 0x35, 0x31, 0x43, 0x59, 0x6e, 0x41, 0x4e, 0x55, 0x77, 0x45, + 0x66, 0x67, 0x73, 0x73, 0x57, 0x57, 0x6e, 0x78, 0x56, 0x39, 0x53, 0x6d, 0x57, 0x78, 0x48, 0x6e, 0x4a, 0x73, + 0x2b, 0x5c, 0x0a, + 0x09, 0x53, 0x35, 0x79, 0x72, 0x56, 0x42, 0x46, 0x4f, 0x41, 0x4d, 0x70, 0x76, 0x4a, 0x2b, 0x41, 0x2f, 0x67, + 0x48, 0x31, 0x54, 0x42, 0x35, 0x47, 0x6b, 0x4d, 0x66, 0x77, 0x61, 0x65, 0x43, 0x2f, 0x77, 0x63, 0x4f, 0x6f, + 0x67, 0x47, 0x70, 0x73, 0x54, 0x67, 0x48, 0x49, 0x37, 0x42, 0x72, 0x67, 0x4c, 0x69, 0x37, 0x2b, 0x6b, 0x61, + 0x74, 0x69, 0x58, 0x4f, 0x47, 0x63, 0x64, 0x6b, 0x7a, 0x71, 0x49, 0x78, 0x6d, 0x59, 0x44, 0x55, 0x45, 0x35, + 0x54, 0x5c, 0x0a, + 0x09, 0x67, 0x57, 0x38, 0x43, 0x6c, 0x77, 0x48, 0x54, 0x30, 0x6b, 0x61, 0x52, 0x70, 0x4c, 0x5a, 0x4d, 0x49, + 0x38, 0x35, 0x64, 0x33, 0x79, 0x54, 0x4f, 0x5a, 0x53, 0x6f, 0x70, 0x6c, 0x77, 0x44, 0x4b, 0x5a, 0x78, 0x36, + 0x78, 0x30, 0x63, 0x62, 0x4f, 0x71, 0x59, 0x4e, 0x49, 0x55, 0x70, 0x63, 0x65, 0x4a, 0x4a, 0x34, 0x30, 0x65, + 0x48, 0x2f, 0x71, 0x49, 0x4e, 0x71, 0x55, 0x45, 0x34, 0x42, 0x79, 0x4f, 0x52, 0x61, 0x34, 0x41, 0x34, 0x75, + 0x2f, 0x5c, 0x0a, + 0x09, 0x70, 0x48, 0x72, 0x59, 0x47, 0x62, 0x69, 0x64, 0x4f, 0x4c, 0x65, 0x70, 0x5a, 0x47, 0x77, 0x41, 0x79, + 0x6d, 0x45, 0x53, 0x73, 0x61, 0x50, 0x66, 0x70, 0x54, 0x67, 0x79, 0x6b, 0x31, 0x51, 0x76, 0x55, 0x34, 0x6c, + 0x7a, 0x32, 0x31, 0x65, 0x49, 0x63, 0x35, 0x31, 0x4b, 0x77, 0x69, 0x57, 0x41, 0x39, 0x4c, 0x59, 0x6e, 0x64, + 0x74, 0x50, 0x79, 0x73, 0x62, 0x32, 0x53, 0x36, 0x75, 0x35, 0x4f, 0x59, 0x68, 0x66, 0x54, 0x52, 0x31, 0x49, + 0x48, 0x5c, 0x0a, + 0x09, 0x6b, 0x52, 0x4f, 0x41, 0x31, 0x41, 0x34, 0x69, 0x62, 0x70, 0x75, 0x78, 0x2b, 0x45, 0x74, 0x71, 0x67, + 0x6e, 0x32, 0x49, 0x63, 0x39, 0x35, 0x42, 0x71, 0x59, 0x50, 0x49, 0x42, 0x69, 0x43, 0x6c, 0x55, 0x34, 0x44, + 0x72, 0x67, 0x64, 0x6d, 0x70, 0x67, 0x30, 0x68, 0x53, 0x67, 0x57, 0x59, 0x54, 0x35, 0x37, 0x36, 0x50, 0x70, + 0x41, 0x37, 0x53, 0x64, 0x43, 0x34, 0x42, 0x46, 0x47, 0x38, 0x53, 0x38, 0x52, 0x43, 0x66, 0x34, 0x31, 0x4d, + 0x48, 0x5c, 0x0a, + 0x09, 0x6b, 0x61, 0x54, 0x45, 0x4c, 0x69, 0x59, 0x65, 0x4b, 0x72, 0x51, 0x6d, 0x64, 0x5a, 0x41, 0x6d, 0x73, + 0x67, 0x45, 0x6f, 0x31, 0x6c, 0x62, 0x41, 0x39, 0x34, 0x44, 0x58, 0x70, 0x51, 0x34, 0x69, 0x53, 0x53, 0x58, + 0x78, 0x4b, 0x2b, 0x4b, 0x52, 0x35, 0x6b, 0x2b, 0x6b, 0x44, 0x74, 0x49, 0x30, 0x4e, 0x67, 0x44, 0x46, 0x32, + 0x51, 0x58, 0x34, 0x45, 0x62, 0x42, 0x44, 0x36, 0x69, 0x43, 0x53, 0x56, 0x44, 0x4a, 0x2f, 0x41, 0x75, 0x59, + 0x44, 0x5c, 0x0a, + 0x09, 0x43, 0x31, 0x49, 0x48, 0x61, 0x52, 0x4b, 0x76, 0x41, 0x53, 0x6a, 0x47, 0x57, 0x34, 0x42, 0x66, 0x59, + 0x50, 0x47, 0x58, 0x70, 0x4f, 0x48, 0x73, 0x41, 0x50, 0x77, 0x63, 0x4f, 0x44, 0x68, 0x31, 0x6b, 0x43, 0x61, + 0x78, 0x41, 0x63, 0x6a, 0x66, 0x42, 0x34, 0x42, 0x72, 0x67, 0x5a, 0x6d, 0x70, 0x67, 0x30, 0x68, 0x53, 0x69, + 0x63, 0x30, 0x45, 0x66, 0x6b, 0x4b, 0x63, 0x4d, 0x31, 0x55, 0x41, 0x47, 0x34, 0x44, 0x38, 0x6a, 0x41, 0x4d, + 0x2b, 0x5c, 0x0a, + 0x09, 0x53, 0x56, 0x7a, 0x6b, 0x30, 0x70, 0x73, 0x32, 0x69, 0x69, 0x52, 0x56, 0x51, 0x69, 0x39, 0x78, 0x7a, + 0x76, 0x77, 0x6b, 0x63, 0x51, 0x35, 0x56, 0x6a, 0x72, 0x77, 0x47, 0x49, 0x42, 0x2b, 0x39, 0x77, 0x45, 0x58, + 0x41, 0x2b, 0x31, 0x4d, 0x48, 0x6b, 0x61, 0x53, 0x4b, 0x2b, 0x68, 0x62, 0x77, 0x33, 0x34, 0x48, 0x6e, 0x55, + 0x77, 0x65, 0x70, 0x4b, 0x78, 0x75, 0x41, 0x37, 0x4d, 0x30, 0x45, 0x72, 0x69, 0x4c, 0x57, 0x2f, 0x53, 0x56, + 0x4a, 0x5c, 0x0a, + 0x09, 0x6e, 0x62, 0x73, 0x5a, 0x4f, 0x41, 0x4a, 0x34, 0x4e, 0x6e, 0x47, 0x4f, 0x57, 0x72, 0x49, 0x42, 0x79, + 0x4e, 0x59, 0x4f, 0x77, 0x49, 0x2b, 0x4a, 0x4a, 0x2f, 0x70, 0x4a, 0x6b, 0x72, 0x72, 0x33, 0x41, 0x50, 0x42, + 0x32, 0x34, 0x6b, 0x34, 0x42, 0x5a, 0x63, 0x68, 0x72, 0x41, 0x4c, 0x4c, 0x7a, 0x57, 0x75, 0x41, 0x2f, 0x73, + 0x66, 0x68, 0x4c, 0x55, 0x70, 0x62, 0x6d, 0x45, 0x65, 0x64, 0x57, 0x74, 0x30, 0x7a, 0x50, 0x6d, 0x41, 0x31, + 0x41, 0x5c, 0x0a, + 0x09, 0x4e, 0x74, 0x34, 0x4d, 0x33, 0x41, 0x68, 0x73, 0x6d, 0x54, 0x69, 0x48, 0x4a, 0x4e, 0x58, 0x52, 0x6c, + 0x73, 0x44, 0x50, 0x69, 0x48, 0x4f, 0x74, 0x4d, 0x6d, 0x49, 0x44, 0x30, 0x4c, 0x33, 0x35, 0x77, 0x50, 0x38, + 0x44, 0x70, 0x71, 0x55, 0x4f, 0x49, 0x6b, 0x6b, 0x31, 0x4e, 0x6f, 0x32, 0x34, 0x54, 0x58, 0x42, 0x2b, 0x36, + 0x69, 0x42, 0x31, 0x59, 0x51, 0x50, 0x51, 0x6e, 0x57, 0x4f, 0x42, 0x71, 0x34, 0x47, 0x58, 0x70, 0x67, 0x34, + 0x69, 0x5c, 0x0a, + 0x09, 0x53, 0x51, 0x33, 0x77, 0x45, 0x75, 0x4b, 0x63, 0x65, 0x31, 0x7a, 0x71, 0x49, 0x48, 0x56, 0x67, 0x41, + 0x39, 0x43, 0x35, 0x66, 0x79, 0x42, 0x75, 0x55, 0x35, 0x6d, 0x51, 0x4f, 0x6f, 0x67, 0x6b, 0x4e, 0x63, 0x67, + 0x45, 0x34, 0x42, 0x4c, 0x69, 0x48, 0x4b, 0x77, 0x75, 0x32, 0x41, 0x42, 0x30, 0x35, 0x75, 0x50, 0x41, 0x6c, + 0x33, 0x47, 0x6a, 0x43, 0x6b, 0x6c, 0x4b, 0x59, 0x52, 0x78, 0x78, 0x44, 0x6a, 0x34, 0x6a, 0x64, 0x5a, 0x41, + 0x71, 0x5c, 0x0a, + 0x09, 0x73, 0x77, 0x46, 0x6f, 0x33, 0x7a, 0x38, 0x44, 0x6e, 0x30, 0x73, 0x64, 0x51, 0x70, 0x4c, 0x45, 0x75, + 0x63, 0x51, 0x35, 0x57, 0x52, 0x32, 0x77, 0x41, 0x57, 0x6a, 0x50, 0x76, 0x77, 0x4c, 0x6e, 0x70, 0x41, 0x34, + 0x68, 0x53, 0x58, 0x72, 0x52, 0x4f, 0x63, 0x44, 0x5a, 0x71, 0x55, 0x4e, 0x55, 0x6b, 0x52, 0x73, 0x42, 0x74, + 0x65, 0x34, 0x63, 0x37, 0x44, 0x51, 0x6c, 0x71, 0x61, 0x77, 0x2b, 0x41, 0x35, 0x79, 0x56, 0x4f, 0x6b, 0x53, + 0x56, 0x5c, 0x0a, + 0x09, 0x4f, 0x41, 0x46, 0x6f, 0x7a, 0x61, 0x65, 0x78, 0x2b, 0x45, 0x74, 0x53, 0x6d, 0x66, 0x30, 0x7a, 0x63, + 0x61, 0x35, 0x57, 0x69, 0x32, 0x77, 0x41, 0x78, 0x76, 0x61, 0x76, 0x32, 0x46, 0x56, 0x4b, 0x55, 0x68, 0x57, + 0x63, 0x52, 0x54, 0x78, 0x4a, 0x55, 0x43, 0x31, 0x77, 0x43, 0x57, 0x42, 0x30, 0x5a, 0x32, 0x46, 0x48, 0x4b, + 0x55, 0x6c, 0x56, 0x38, 0x77, 0x6d, 0x38, 0x58, 0x6d, 0x74, 0x4d, 0x4e, 0x67, 0x41, 0x6a, 0x2b, 0x78, 0x68, + 0x77, 0x5c, 0x0a, + 0x09, 0x58, 0x75, 0x6f, 0x51, 0x6b, 0x71, 0x53, 0x4f, 0x6e, 0x49, 0x48, 0x6e, 0x38, 0x46, 0x48, 0x5a, 0x41, + 0x41, 0x7a, 0x76, 0x48, 0x34, 0x68, 0x37, 0x54, 0x43, 0x56, 0x4a, 0x31, 0x58, 0x55, 0x4b, 0x38, 0x4a, 0x58, + 0x55, 0x49, 0x63, 0x72, 0x4b, 0x42, 0x6d, 0x42, 0x54, 0x78, 0x78, 0x49, 0x37, 0x2f, 0x4c, 0x6e, 0x4a, 0x6a, + 0x79, 0x52, 0x56, 0x57, 0x7a, 0x2f, 0x77, 0x50, 0x75, 0x43, 0x79, 0x31, 0x45, 0x48, 0x4b, 0x79, 0x41, 0x5a, + 0x67, 0x5c, 0x0a, + 0x09, 0x51, 0x34, 0x63, 0x44, 0x56, 0x2b, 0x48, 0x32, 0x76, 0x70, 0x4a, 0x55, 0x46, 0x79, 0x38, 0x41, 0x52, + 0x77, 0x4c, 0x58, 0x70, 0x41, 0x35, 0x53, 0x4e, 0x6a, 0x59, 0x41, 0x36, 0x78, 0x30, 0x4d, 0x2f, 0x42, 0x43, + 0x59, 0x6e, 0x44, 0x71, 0x49, 0x4a, 0x43, 0x6c, 0x54, 0x71, 0x34, 0x6d, 0x6e, 0x43, 0x4e, 0x36, 0x59, 0x4f, + 0x6b, 0x69, 0x5a, 0x32, 0x41, 0x43, 0x45, 0x66, 0x59, 0x48, 0x72, 0x67, 0x65, 0x6d, 0x70, 0x67, 0x30, 0x69, + 0x53, 0x5c, 0x0a, + 0x09, 0x63, 0x72, 0x45, 0x4d, 0x4f, 0x42, 0x53, 0x34, 0x49, 0x33, 0x57, 0x51, 0x73, 0x72, 0x41, 0x42, 0x67, + 0x4c, 0x6e, 0x41, 0x4c, 0x34, 0x48, 0x5a, 0x71, 0x59, 0x4e, 0x49, 0x6b, 0x6e, 0x4b, 0x31, 0x42, 0x44, 0x67, + 0x41, 0x65, 0x43, 0x68, 0x31, 0x6b, 0x44, 0x4a, 0x6f, 0x2b, 0x6b, 0x5a, 0x41, 0x73, 0x34, 0x47, 0x66, 0x59, + 0x50, 0x47, 0x58, 0x70, 0x43, 0x62, 0x77, 0x6e, 0x44, 0x39, 0x45, 0x6b, 0x78, 0x75, 0x41, 0x79, 0x63, 0x53, + 0x61, 0x5c, 0x0a, + 0x09, 0x2f, 0x39, 0x7a, 0x55, 0x51, 0x53, 0x52, 0x4a, 0x68, 0x5a, 0x6d, 0x4c, 0x31, 0x33, 0x73, 0x42, 0x7a, + 0x57, 0x30, 0x41, 0x78, 0x67, 0x50, 0x2f, 0x41, 0x65, 0x79, 0x66, 0x4f, 0x6f, 0x67, 0x6b, 0x71, 0x58, 0x44, + 0x37, 0x45, 0x7a, 0x56, 0x67, 0x66, 0x4f, 0x6f, 0x67, 0x4b, 0x54, 0x57, 0x31, 0x41, 0x66, 0x67, 0x53, 0x63, + 0x63, 0x75, 0x66, 0x4a, 0x4b, 0x6d, 0x5a, 0x44, 0x69, 0x64, 0x71, 0x51, 0x57, 0x4d, 0x31, 0x73, 0x51, 0x45, + 0x34, 0x5c, 0x0a, + 0x09, 0x48, 0x54, 0x67, 0x35, 0x64, 0x51, 0x68, 0x4a, 0x55, 0x6e, 0x49, 0x6e, 0x45, 0x39, 0x75, 0x2b, 0x4e, + 0x31, 0x4c, 0x54, 0x37, 0x67, 0x49, 0x34, 0x48, 0x4c, 0x69, 0x61, 0x68, 0x6f, 0x39, 0x39, 0x4a, 0x45, 0x6b, + 0x76, 0x36, 0x67, 0x4f, 0x4f, 0x6f, 0x49, 0x45, 0x62, 0x42, 0x54, 0x57, 0x70, 0x41, 0x64, 0x67, 0x64, 0x75, + 0x41, 0x33, 0x59, 0x4c, 0x48, 0x55, 0x51, 0x53, 0x56, 0x4b, 0x70, 0x72, 0x43, 0x52, 0x75, 0x44, 0x37, 0x77, + 0x33, 0x5c, 0x0a, + 0x09, 0x64, 0x5a, 0x41, 0x69, 0x4e, 0x61, 0x55, 0x42, 0x32, 0x41, 0x72, 0x34, 0x4e, 0x62, 0x42, 0x4e, 0x36, + 0x69, 0x43, 0x53, 0x70, 0x46, 0x4a, 0x36, 0x46, 0x4e, 0x67, 0x50, 0x57, 0x4a, 0x51, 0x36, 0x53, 0x46, 0x47, + 0x61, 0x63, 0x41, 0x31, 0x41, 0x4c, 0x2f, 0x41, 0x39, 0x4c, 0x50, 0x36, 0x53, 0x70, 0x4a, 0x46, 0x74, 0x51, + 0x39, 0x53, 0x4b, 0x33, 0x74, 0x52, 0x42, 0x69, 0x74, 0x4b, 0x45, 0x42, 0x75, 0x42, 0x43, 0x34, 0x48, 0x57, + 0x70, 0x5c, 0x0a, + 0x09, 0x51, 0x30, 0x69, 0x53, 0x53, 0x6d, 0x39, 0x2f, 0x6f, 0x6d, 0x59, 0x30, 0x51, 0x74, 0x30, 0x62, 0x67, + 0x49, 0x38, 0x41, 0x4a, 0x36, 0x51, 0x4f, 0x49, 0x55, 0x6d, 0x71, 0x6a, 0x42, 0x4f, 0x49, 0x32, 0x6c, 0x46, + 0x37, 0x64, 0x62, 0x34, 0x47, 0x34, 0x43, 0x44, 0x67, 0x4f, 0x68, 0x6f, 0x30, 0x7a, 0x70, 0x45, 0x6b, 0x5a, + 0x65, 0x4a, 0x35, 0x34, 0x73, 0x46, 0x42, 0x74, 0x36, 0x51, 0x4f, 0x6b, 0x71, 0x65, 0x36, 0x4e, 0x67, 0x44, + 0x62, 0x5c, 0x0a, + 0x09, 0x41, 0x72, 0x2f, 0x42, 0x2f, 0x5a, 0x34, 0x6c, 0x53, 0x5a, 0x31, 0x5a, 0x41, 0x75, 0x77, 0x44, 0x4c, + 0x45, 0x77, 0x64, 0x4a, 0x43, 0x39, 0x31, 0x58, 0x41, 0x4c, 0x6f, 0x42, 0x61, 0x37, 0x43, 0x34, 0x69, 0x39, + 0x4a, 0x36, 0x74, 0x78, 0x73, 0x34, 0x45, 0x70, 0x71, 0x50, 0x45, 0x57, 0x75, 0x59, 0x77, 0x4e, 0x77, 0x50, + 0x72, 0x42, 0x76, 0x36, 0x68, 0x43, 0x53, 0x70, 0x4d, 0x72, 0x62, 0x6c, 0x36, 0x67, 0x70, 0x74, 0x56, 0x53, + 0x33, 0x5c, 0x0a, + 0x09, 0x4a, 0x59, 0x44, 0x33, 0x41, 0x70, 0x65, 0x6e, 0x44, 0x69, 0x46, 0x4a, 0x71, 0x70, 0x56, 0x6a, 0x69, + 0x49, 0x63, 0x48, 0x31, 0x55, 0x71, 0x64, 0x47, 0x6f, 0x42, 0x35, 0x77, 0x42, 0x33, 0x41, 0x31, 0x4e, 0x52, + 0x42, 0x4a, 0x45, 0x6d, 0x31, 0x73, 0x6f, 0x71, 0x59, 0x42, 0x6a, 0x79, 0x51, 0x4f, 0x6b, 0x69, 0x57, 0x36, + 0x72, 0x49, 0x45, 0x4d, 0x49, 0x56, 0x59, 0x39, 0x37, 0x66, 0x34, 0x53, 0x35, 0x4b, 0x79, 0x56, 0x73, 0x73, + 0x61, 0x5c, 0x0a, + 0x09, 0x55, 0x35, 0x63, 0x47, 0x34, 0x4d, 0x76, 0x45, 0x42, 0x45, 0x43, 0x53, 0x70, 0x44, 0x7a, 0x4d, 0x6f, + 0x32, 0x61, 0x50, 0x44, 0x36, 0x37, 0x44, 0x45, 0x73, 0x41, 0x78, 0x77, 0x47, 0x57, 0x70, 0x51, 0x30, 0x69, + 0x53, 0x47, 0x75, 0x45, 0x34, 0x61, 0x6c, 0x4a, 0x7a, 0x71, 0x74, 0x34, 0x41, 0x37, 0x41, 0x54, 0x63, 0x42, + 0x55, 0x78, 0x4c, 0x48, 0x55, 0x53, 0x53, 0x31, 0x41, 0x6a, 0x4c, 0x67, 0x62, 0x32, 0x42, 0x68, 0x31, 0x4d, + 0x48, 0x5c, 0x0a, + 0x09, 0x36, 0x56, 0x61, 0x56, 0x6c, 0x77, 0x42, 0x36, 0x69, 0x61, 0x73, 0x79, 0x4c, 0x66, 0x36, 0x53, 0x70, + 0x4b, 0x4a, 0x4d, 0x41, 0x37, 0x35, 0x4e, 0x44, 0x66, 0x59, 0x48, 0x71, 0x48, 0x49, 0x44, 0x38, 0x4c, 0x2f, + 0x78, 0x66, 0x6e, 0x39, 0x4a, 0x55, 0x76, 0x48, 0x32, 0x49, 0x57, 0x70, 0x51, 0x70, 0x56, 0x56, 0x31, 0x43, + 0x65, 0x41, 0x74, 0x77, 0x41, 0x31, 0x55, 0x75, 0x34, 0x47, 0x52, 0x4a, 0x46, 0x56, 0x58, 0x50, 0x2f, 0x41, + 0x33, 0x5c, 0x0a, + 0x09, 0x77, 0x45, 0x32, 0x70, 0x67, 0x33, 0x53, 0x71, 0x69, 0x67, 0x33, 0x41, 0x44, 0x4f, 0x43, 0x33, 0x77, + 0x48, 0x61, 0x70, 0x67, 0x30, 0x69, 0x53, 0x47, 0x6d, 0x30, 0x68, 0x38, 0x42, 0x70, 0x67, 0x61, 0x65, 0x6f, + 0x67, 0x6e, 0x61, 0x6a, 0x69, 0x4a, 0x2b, 0x67, 0x4c, 0x73, 0x50, 0x68, 0x4c, 0x6b, 0x74, 0x4c, 0x62, 0x6a, + 0x71, 0x68, 0x4a, 0x6c, 0x56, 0x53, 0x31, 0x43, 0x63, 0x42, 0x52, 0x77, 0x42, 0x57, 0x70, 0x51, 0x30, 0x69, + 0x53, 0x5c, 0x0a, + 0x09, 0x4e, 0x4d, 0x54, 0x52, 0x78, 0x49, 0x4f, 0x44, 0x4b, 0x71, 0x56, 0x4b, 0x44, 0x63, 0x41, 0x63, 0x34, + 0x46, 0x37, 0x67, 0x5a, 0x61, 0x6d, 0x44, 0x53, 0x4a, 0x49, 0x30, 0x78, 0x4e, 0x50, 0x41, 0x37, 0x73, 0x43, + 0x69, 0x31, 0x45, 0x48, 0x61, 0x55, 0x61, 0x55, 0x6c, 0x67, 0x4b, 0x39, 0x6a, 0x38, 0x5a, 0x63, 0x6b, 0x6c, + 0x63, 0x2f, 0x4c, 0x69, 0x42, 0x70, 0x56, 0x4b, 0x56, 0x56, 0x70, 0x41, 0x4e, 0x34, 0x44, 0x7a, 0x45, 0x38, + 0x64, 0x5c, 0x0a, + 0x09, 0x51, 0x70, 0x4b, 0x6b, 0x45, 0x63, 0x77, 0x6e, 0x64, 0x71, 0x61, 0x74, 0x6a, 0x43, 0x6f, 0x73, 0x41, + 0x57, 0x77, 0x42, 0x4c, 0x41, 0x42, 0x6d, 0x70, 0x51, 0x34, 0x69, 0x53, 0x64, 0x49, 0x6f, 0x6e, 0x67, 0x4a, + 0x32, 0x42, 0x52, 0x61, 0x6e, 0x44, 0x74, 0x4b, 0x4b, 0x4b, 0x6b, 0x77, 0x41, 0x76, 0x6f, 0x4c, 0x46, 0x58, + 0x35, 0x4a, 0x55, 0x66, 0x72, 0x4f, 0x49, 0x6d, 0x6c, 0x55, 0x4a, 0x5a, 0x57, 0x38, 0x41, 0x6a, 0x68, 0x70, + 0x34, 0x5c, 0x0a, + 0x09, 0x53, 0x5a, 0x4a, 0x55, 0x42, 0x5a, 0x57, 0x70, 0x57, 0x32, 0x56, 0x65, 0x41, 0x70, 0x67, 0x42, 0x33, + 0x45, 0x39, 0x63, 0x2f, 0x53, 0x39, 0x4a, 0x55, 0x6c, 0x55, 0x73, 0x41, 0x6e, 0x61, 0x68, 0x35, 0x42, 0x73, + 0x45, 0x6c, 0x58, 0x6b, 0x43, 0x63, 0x41, 0x34, 0x57, 0x66, 0x30, 0x6c, 0x53, 0x39, 0x63, 0x77, 0x42, 0x50, + 0x70, 0x4d, 0x36, 0x78, 0x46, 0x6a, 0x4b, 0x4f, 0x67, 0x46, 0x34, 0x50, 0x66, 0x41, 0x4c, 0x79, 0x74, 0x32, + 0x67, 0x5c, 0x0a, + 0x09, 0x53, 0x4a, 0x49, 0x30, 0x6b, 0x6e, 0x58, 0x41, 0x47, 0x34, 0x46, 0x66, 0x70, 0x67, 0x34, 0x79, 0x6b, + 0x6a, 0x49, 0x32, 0x41, 0x42, 0x4f, 0x42, 0x4f, 0x34, 0x45, 0x39, 0x55, 0x67, 0x65, 0x52, 0x4a, 0x4b, 0x6b, + 0x4c, 0x76, 0x79, 0x4f, 0x65, 0x48, 0x4c, 0x67, 0x32, 0x64, 0x5a, 0x44, 0x68, 0x6c, 0x50, 0x45, 0x54, 0x39, + 0x75, 0x6c, 0x59, 0x2f, 0x43, 0x56, 0x4a, 0x31, 0x62, 0x63, 0x48, 0x38, 0x4c, 0x48, 0x55, 0x49, 0x55, 0x5a, + 0x53, 0x5c, 0x0a, + 0x09, 0x74, 0x67, 0x6e, 0x41, 0x64, 0x73, 0x41, 0x44, 0x77, 0x4f, 0x54, 0x55, 0x51, 0x53, 0x52, 0x4a, 0x79, + 0x73, 0x42, 0x71, 0x59, 0x42, 0x37, 0x78, 0x35, 0x4d, 0x42, 0x53, 0x4b, 0x64, 0x73, 0x45, 0x34, 0x48, 0x4e, + 0x59, 0x2f, 0x43, 0x56, 0x4a, 0x39, 0x54, 0x47, 0x5a, 0x71, 0x47, 0x32, 0x6c, 0x55, 0x36, 0x59, 0x4a, 0x77, + 0x46, 0x75, 0x41, 0x47, 0x31, 0x4f, 0x48, 0x6b, 0x43, 0x51, 0x70, 0x42, 0x34, 0x63, 0x41, 0x4e, 0x36, 0x51, + 0x4f, 0x5c, 0x0a, + 0x09, 0x4d, 0x56, 0x52, 0x5a, 0x47, 0x6f, 0x43, 0x4a, 0x77, 0x44, 0x33, 0x45, 0x66, 0x5a, 0x4f, 0x53, 0x4a, + 0x4e, 0x58, 0x4e, 0x67, 0x38, 0x51, 0x31, 0x41, 0x61, 0x57, 0x35, 0x49, 0x4c, 0x41, 0x73, 0x53, 0x77, 0x43, + 0x6e, 0x59, 0x76, 0x47, 0x58, 0x4a, 0x4e, 0x58, 0x58, 0x7a, 0x6b, 0x53, 0x74, 0x4b, 0x34, 0x30, 0x79, 0x54, + 0x41, 0x43, 0x32, 0x42, 0x50, 0x34, 0x41, 0x54, 0x45, 0x73, 0x64, 0x52, 0x4a, 0x4b, 0x6b, 0x48, 0x43, 0x30, + 0x48, 0x5c, 0x0a, + 0x09, 0x58, 0x67, 0x30, 0x38, 0x6b, 0x54, 0x6f, 0x49, 0x6c, 0x47, 0x4d, 0x43, 0x63, 0x44, 0x59, 0x57, 0x66, + 0x30, 0x6c, 0x53, 0x2f, 0x55, 0x30, 0x6a, 0x61, 0x6c, 0x34, 0x70, 0x70, 0x4a, 0x34, 0x41, 0x37, 0x45, 0x71, + 0x73, 0x2f, 0x55, 0x39, 0x49, 0x47, 0x55, 0x4b, 0x53, 0x70, 0x49, 0x4c, 0x30, 0x41, 0x58, 0x73, 0x43, 0x39, + 0x36, 0x55, 0x4f, 0x6b, 0x6e, 0x6f, 0x43, 0x38, 0x44, 0x6b, 0x73, 0x2f, 0x70, 0x4b, 0x6b, 0x35, 0x68, 0x67, + 0x50, 0x5c, 0x0a, + 0x09, 0x6e, 0x4a, 0x73, 0x36, 0x42, 0x4b, 0x52, 0x74, 0x41, 0x41, 0x34, 0x42, 0x44, 0x6b, 0x74, 0x34, 0x66, + 0x45, 0x6d, 0x53, 0x55, 0x6a, 0x67, 0x4d, 0x65, 0x47, 0x76, 0x71, 0x45, 0x4b, 0x6d, 0x57, 0x41, 0x4d, 0x59, + 0x44, 0x64, 0x77, 0x4f, 0x37, 0x70, 0x7a, 0x69, 0x34, 0x4a, 0x45, 0x6d, 0x4a, 0x33, 0x55, 0x63, 0x73, 0x42, + 0x66, 0x53, 0x6c, 0x43, 0x70, 0x42, 0x71, 0x41, 0x76, 0x41, 0x2b, 0x4c, 0x50, 0x36, 0x53, 0x70, 0x4f, 0x62, + 0x61, 0x5c, 0x0a, + 0x09, 0x6a, 0x61, 0x69, 0x46, 0x79, 0x61, 0x53, 0x59, 0x41, 0x45, 0x77, 0x43, 0x66, 0x67, 0x39, 0x73, 0x58, + 0x2f, 0x53, 0x42, 0x4a, 0x55, 0x6b, 0x71, 0x6b, 0x55, 0x65, 0x49, 0x32, 0x77, 0x4c, 0x58, 0x70, 0x44, 0x68, + 0x34, 0x69, 0x67, 0x6e, 0x41, 0x69, 0x56, 0x6a, 0x38, 0x4a, 0x55, 0x6e, 0x61, 0x48, 0x6a, 0x67, 0x70, 0x31, + 0x63, 0x47, 0x4c, 0x6e, 0x67, 0x42, 0x4d, 0x41, 0x52, 0x34, 0x6d, 0x4e, 0x76, 0x2b, 0x52, 0x4a, 0x4b, 0x6e, + 0x70, 0x5c, 0x0a, + 0x09, 0x46, 0x67, 0x4e, 0x7a, 0x67, 0x52, 0x56, 0x46, 0x48, 0x37, 0x6a, 0x6f, 0x43, 0x63, 0x42, 0x48, 0x73, + 0x66, 0x68, 0x4c, 0x6b, 0x6a, 0x52, 0x6f, 0x43, 0x2b, 0x43, 0x30, 0x46, 0x41, 0x63, 0x75, 0x63, 0x67, 0x49, + 0x77, 0x45, 0x2f, 0x67, 0x54, 0x4d, 0x4c, 0x32, 0x6f, 0x41, 0x30, 0x71, 0x53, 0x56, 0x41, 0x48, 0x4c, 0x67, + 0x42, 0x32, 0x41, 0x5a, 0x34, 0x73, 0x38, 0x61, 0x4a, 0x45, 0x54, 0x67, 0x4e, 0x4f, 0x78, 0x2b, 0x45, 0x75, + 0x53, 0x5c, 0x0a, + 0x09, 0x74, 0x4c, 0x48, 0x70, 0x77, 0x4d, 0x65, 0x4b, 0x50, 0x6d, 0x68, 0x52, 0x45, 0x34, 0x41, 0x5a, 0x77, + 0x4a, 0x2b, 0x78, 0x41, 0x5a, 0x41, 0x6b, 0x61, 0x54, 0x69, 0x46, 0x54, 0x77, 0x47, 0x4b, 0x6d, 0x67, 0x42, + 0x38, 0x46, 0x49, 0x75, 0x2f, 0x4a, 0x45, 0x6b, 0x6a, 0x6d, 0x55, 0x37, 0x55, 0x79, 0x73, 0x49, 0x55, 0x4d, + 0x51, 0x47, 0x59, 0x51, 0x61, 0x7a, 0x39, 0x7a, 0x38, 0x6a, 0x37, 0x51, 0x4a, 0x49, 0x6b, 0x56, 0x64, 0x67, + 0x79, 0x5c, 0x0a, + 0x09, 0x34, 0x42, 0x58, 0x41, 0x30, 0x69, 0x49, 0x4f, 0x56, 0x73, 0x51, 0x45, 0x34, 0x44, 0x51, 0x73, 0x2f, + 0x70, 0x49, 0x6b, 0x6a, 0x57, 0x55, 0x36, 0x63, 0x62, 0x31, 0x63, 0x49, 0x66, 0x4b, 0x65, 0x41, 0x45, 0x77, + 0x46, 0x46, 0x68, 0x4a, 0x33, 0x41, 0x45, 0x69, 0x53, 0x70, 0x4e, 0x45, 0x74, 0x42, 0x62, 0x59, 0x46, 0x56, + 0x75, 0x5a, 0x39, 0x6f, 0x4c, 0x77, 0x6e, 0x41, 0x43, 0x64, 0x69, 0x38, 0x5a, 0x63, 0x6b, 0x71, 0x56, 0x55, + 0x7a, 0x5c, 0x0a, + 0x09, 0x67, 0x41, 0x38, 0x56, 0x63, 0x61, 0x41, 0x38, 0x4a, 0x77, 0x43, 0x39, 0x78, 0x4b, 0x35, 0x2f, 0x32, + 0x2b, 0x52, 0x31, 0x41, 0x45, 0x6d, 0x53, 0x61, 0x75, 0x67, 0x78, 0x59, 0x45, 0x66, 0x67, 0x2b, 0x54, 0x77, + 0x50, 0x6b, 0x75, 0x63, 0x45, 0x34, 0x46, 0x67, 0x73, 0x2f, 0x70, 0x49, 0x6b, 0x74, 0x57, 0x74, 0x72, 0x34, + 0x4c, 0x69, 0x38, 0x44, 0x35, 0x4c, 0x58, 0x42, 0x4b, 0x43, 0x48, 0x65, 0x4e, 0x62, 0x78, 0x76, 0x44, 0x7a, + 0x65, 0x5c, 0x0a, + 0x09, 0x58, 0x4a, 0x4b, 0x6b, 0x6d, 0x6e, 0x73, 0x51, 0x32, 0x42, 0x56, 0x59, 0x6c, 0x39, 0x63, 0x42, 0x38, + 0x70, 0x6f, 0x41, 0x7a, 0x4d, 0x66, 0x69, 0x4c, 0x30, 0x6c, 0x53, 0x70, 0x33, 0x59, 0x6d, 0x61, 0x6d, 0x6c, + 0x75, 0x38, 0x6d, 0x6f, 0x41, 0x43, 0x74, 0x33, 0x4d, 0x51, 0x4a, 0x4b, 0x6b, 0x47, 0x73, 0x71, 0x31, 0x6c, + 0x75, 0x61, 0x78, 0x42, 0x4c, 0x41, 0x58, 0x63, 0x46, 0x66, 0x57, 0x62, 0x79, 0x70, 0x4a, 0x55, 0x67, 0x50, + 0x74, 0x5c, 0x0a, + 0x09, 0x44, 0x64, 0x79, 0x64, 0x78, 0x78, 0x76, 0x6e, 0x4d, 0x51, 0x48, 0x77, 0x30, 0x37, 0x38, 0x6b, 0x53, + 0x64, 0x6e, 0x49, 0x72, 0x61, 0x5a, 0x6d, 0x50, 0x51, 0x47, 0x59, 0x51, 0x7a, 0x7a, 0x30, 0x70, 0x7a, 0x66, + 0x4c, 0x4e, 0x35, 0x55, 0x6b, 0x71, 0x61, 0x47, 0x65, 0x4a, 0x37, 0x59, 0x48, 0x58, 0x70, 0x54, 0x31, 0x47, + 0x32, 0x63, 0x39, 0x41, 0x66, 0x67, 0x77, 0x46, 0x6e, 0x39, 0x4a, 0x6b, 0x72, 0x4c, 0x53, 0x53, 0x39, 0x54, + 0x57, 0x5c, 0x0a, + 0x09, 0x7a, 0x47, 0x55, 0x35, 0x41, 0x65, 0x67, 0x46, 0x48, 0x67, 0x56, 0x6d, 0x5a, 0x2f, 0x57, 0x47, 0x6b, + 0x69, 0x53, 0x4a, 0x4a, 0x63, 0x53, 0x2b, 0x4f, 0x70, 0x6c, 0x75, 0x44, 0x4a, 0x54, 0x6c, 0x42, 0x4f, 0x42, + 0x49, 0x4c, 0x50, 0x36, 0x53, 0x4a, 0x47, 0x56, 0x74, 0x4e, 0x6c, 0x46, 0x6a, 0x4d, 0x35, 0x56, 0x6c, 0x41, + 0x33, 0x42, 0x53, 0x68, 0x75, 0x38, 0x6c, 0x53, 0x5a, 0x4c, 0x57, 0x4f, 0x7a, 0x6e, 0x72, 0x4e, 0x38, 0x78, + 0x71, 0x5c, 0x0a, + 0x09, 0x43, 0x57, 0x41, 0x58, 0x59, 0x45, 0x45, 0x57, 0x62, 0x79, 0x52, 0x4a, 0x6b, 0x6f, 0x61, 0x31, 0x47, + 0x78, 0x6e, 0x57, 0x32, 0x71, 0x77, 0x6d, 0x41, 0x4a, 0x6c, 0x33, 0x4a, 0x70, 0x49, 0x6b, 0x61, 0x51, 0x4f, + 0x5a, 0x54, 0x74, 0x71, 0x7a, 0x6d, 0x41, 0x42, 0x4d, 0x49, 0x53, 0x37, 0x2b, 0x6d, 0x39, 0x46, 0x39, 0x48, + 0x45, 0x6d, 0x53, 0x4e, 0x49, 0x4b, 0x6c, 0x77, 0x4c, 0x62, 0x41, 0x79, 0x69, 0x7a, 0x65, 0x4c, 0x49, 0x73, + 0x4a, 0x5c, 0x0a, + 0x09, 0x77, 0x4e, 0x46, 0x59, 0x2f, 0x43, 0x56, 0x4a, 0x79, 0x74, 0x73, 0x4d, 0x6f, 0x75, 0x5a, 0x6d, 0x49, + 0x6f, 0x73, 0x47, 0x34, 0x50, 0x67, 0x4d, 0x33, 0x6b, 0x4f, 0x53, 0x4a, 0x49, 0x33, 0x74, 0x68, 0x4b, 0x7a, + 0x65, 0x71, 0x4e, 0x73, 0x6c, 0x67, 0x46, 0x63, 0x43, 0x76, 0x77, 0x66, 0x47, 0x5a, 0x52, 0x4e, 0x48, 0x6b, + 0x69, 0x53, 0x4e, 0x6f, 0x68, 0x39, 0x34, 0x4e, 0x66, 0x44, 0x48, 0x62, 0x74, 0x2b, 0x6f, 0x32, 0x77, 0x6e, + 0x41, 0x5c, 0x0a, + 0x09, 0x42, 0x37, 0x48, 0x34, 0x53, 0x35, 0x4a, 0x55, 0x6c, 0x48, 0x46, 0x45, 0x37, 0x65, 0x33, 0x2b, 0x6a, + 0x62, 0x71, 0x59, 0x41, 0x50, 0x51, 0x41, 0x6a, 0x78, 0x43, 0x37, 0x45, 0x30, 0x6d, 0x53, 0x70, 0x47, 0x49, + 0x38, 0x42, 0x6d, 0x77, 0x50, 0x39, 0x48, 0x58, 0x7a, 0x4a, 0x74, 0x31, 0x4d, 0x41, 0x41, 0x37, 0x42, 0x34, + 0x69, 0x39, 0x4a, 0x55, 0x74, 0x47, 0x32, 0x42, 0x67, 0x37, 0x74, 0x39, 0x6b, 0x32, 0x36, 0x61, 0x51, 0x44, + 0x65, 0x5c, 0x0a, + 0x09, 0x33, 0x2b, 0x33, 0x42, 0x4a, 0x55, 0x6c, 0x53, 0x52, 0x34, 0x37, 0x72, 0x39, 0x67, 0x30, 0x36, 0x58, + 0x51, 0x4b, 0x59, 0x41, 0x6a, 0x77, 0x35, 0x38, 0x4b, 0x4d, 0x6b, 0x53, 0x53, 0x72, 0x57, 0x4b, 0x6d, 0x44, + 0x4c, 0x67, 0x52, 0x38, 0x37, 0x30, 0x75, 0x6b, 0x45, 0x34, 0x4a, 0x31, 0x59, 0x2f, 0x43, 0x56, 0x4a, 0x53, + 0x6d, 0x55, 0x4b, 0x55, 0x59, 0x73, 0x37, 0x31, 0x6d, 0x6b, 0x44, 0x63, 0x45, 0x77, 0x33, 0x42, 0x35, 0x55, + 0x6b, 0x5c, 0x0a, + 0x09, 0x53, 0x56, 0x33, 0x72, 0x71, 0x68, 0x5a, 0x33, 0x73, 0x67, 0x51, 0x77, 0x43, 0x33, 0x67, 0x63, 0x6d, + 0x4e, 0x6a, 0x4e, 0x67, 0x53, 0x56, 0x4a, 0x55, 0x6c, 0x66, 0x57, 0x41, 0x69, 0x38, 0x48, 0x6e, 0x75, 0x72, + 0x6b, 0x44, 0x33, 0x63, 0x79, 0x41, 0x54, 0x67, 0x61, 0x69, 0x37, 0x38, 0x6b, 0x53, 0x61, 0x6c, 0x4e, 0x70, + 0x49, 0x75, 0x74, 0x67, 0x54, 0x74, 0x70, 0x41, 0x49, 0x37, 0x71, 0x39, 0x47, 0x43, 0x53, 0x4a, 0x43, 0x6c, + 0x54, 0x5c, 0x0a, + 0x09, 0x48, 0x64, 0x66, 0x6b, 0x64, 0x70, 0x63, 0x41, 0x5a, 0x67, 0x4f, 0x4c, 0x67, 0x50, 0x47, 0x64, 0x48, + 0x6c, 0x43, 0x53, 0x4a, 0x47, 0x57, 0x6d, 0x44, 0x35, 0x67, 0x44, 0x4c, 0x47, 0x6e, 0x33, 0x44, 0x37, 0x59, + 0x37, 0x41, 0x54, 0x67, 0x63, 0x69, 0x37, 0x38, 0x6b, 0x53, 0x57, 0x55, 0x78, 0x6e, 0x67, 0x37, 0x76, 0x42, + 0x6d, 0x69, 0x33, 0x41, 0x58, 0x44, 0x38, 0x4c, 0x30, 0x6c, 0x53, 0x75, 0x52, 0x7a, 0x5a, 0x79, 0x52, 0x39, + 0x71, 0x5c, 0x0a, + 0x09, 0x5a, 0x77, 0x6c, 0x67, 0x42, 0x72, 0x48, 0x35, 0x54, 0x32, 0x38, 0x6e, 0x42, 0x35, 0x49, 0x6b, 0x53, + 0x62, 0x6c, 0x59, 0x43, 0x32, 0x77, 0x42, 0x4c, 0x47, 0x33, 0x6e, 0x44, 0x37, 0x55, 0x7a, 0x41, 0x5a, 0x69, + 0x50, 0x78, 0x56, 0x2b, 0x53, 0x70, 0x4c, 0x4b, 0x5a, 0x53, 0x43, 0x7a, 0x52, 0x74, 0x36, 0x58, 0x64, 0x42, + 0x6b, 0x43, 0x53, 0x4a, 0x4a, 0x56, 0x50, 0x32, 0x7a, 0x57, 0x36, 0x31, 0x53, 0x57, 0x41, 0x53, 0x63, 0x54, + 0x34, 0x5c, 0x0a, + 0x09, 0x66, 0x33, 0x71, 0x37, 0x42, 0x35, 0x41, 0x6b, 0x53, 0x62, 0x6c, 0x62, 0x53, 0x57, 0x7a, 0x55, 0x74, + 0x36, 0x62, 0x56, 0x50, 0x39, 0x44, 0x71, 0x42, 0x4f, 0x41, 0x67, 0x4c, 0x50, 0x36, 0x53, 0x4a, 0x4a, 0x58, + 0x56, 0x56, 0x4b, 0x4a, 0x57, 0x74, 0x36, 0x7a, 0x56, 0x42, 0x75, 0x44, 0x74, 0x37, 0x57, 0x65, 0x52, 0x4a, + 0x45, 0x6b, 0x46, 0x61, 0x71, 0x74, 0x57, 0x74, 0x37, 0x6f, 0x45, 0x38, 0x42, 0x43, 0x77, 0x55, 0x30, 0x64, + 0x78, 0x5c, 0x0a, + 0x09, 0x4a, 0x45, 0x6c, 0x53, 0x45, 0x52, 0x34, 0x47, 0x35, 0x72, 0x62, 0x36, 0x7a, 0x61, 0x31, 0x4d, 0x41, + 0x48, 0x62, 0x47, 0x34, 0x69, 0x39, 0x4a, 0x55, 0x74, 0x6e, 0x74, 0x42, 0x4f, 0x7a, 0x61, 0x36, 0x6a, 0x65, + 0x33, 0x30, 0x67, 0x43, 0x38, 0x72, 0x66, 0x4d, 0x73, 0x6b, 0x69, 0x53, 0x70, 0x51, 0x47, 0x39, 0x74, 0x39, + 0x52, 0x74, 0x62, 0x61, 0x51, 0x41, 0x4f, 0x36, 0x53, 0x4b, 0x49, 0x4a, 0x45, 0x6b, 0x71, 0x54, 0x73, 0x73, + 0x31, 0x5c, 0x0a, + 0x09, 0x65, 0x36, 0x78, 0x72, 0x41, 0x43, 0x59, 0x42, 0x54, 0x77, 0x4e, 0x54, 0x75, 0x6b, 0x30, 0x6b, 0x53, + 0x5a, 0x4a, 0x79, 0x39, 0x78, 0x77, 0x77, 0x6b, 0x78, 0x5a, 0x75, 0x42, 0x78, 0x78, 0x72, 0x41, 0x76, 0x42, + 0x36, 0x4c, 0x50, 0x36, 0x53, 0x4a, 0x46, 0x58, 0x46, 0x53, 0x34, 0x45, 0x44, 0x57, 0x2f, 0x6e, 0x47, 0x73, + 0x52, 0x71, 0x41, 0x51, 0x37, 0x76, 0x50, 0x49, 0x6b, 0x6d, 0x53, 0x43, 0x74, 0x54, 0x53, 0x4d, 0x73, 0x42, + 0x59, 0x5c, 0x0a, + 0x09, 0x44, 0x59, 0x44, 0x72, 0x2f, 0x35, 0x49, 0x6b, 0x56, 0x55, 0x74, 0x4c, 0x74, 0x58, 0x75, 0x30, 0x61, + 0x77, 0x42, 0x6d, 0x45, 0x4f, 0x76, 0x2f, 0x37, 0x54, 0x34, 0x79, 0x57, 0x4a, 0x49, 0x6b, 0x70, 0x62, 0x4f, + 0x4f, 0x32, 0x42, 0x62, 0x34, 0x32, 0x64, 0x47, 0x2b, 0x61, 0x62, 0x54, 0x69, 0x66, 0x75, 0x41, 0x59, 0x58, + 0x35, 0x63, 0x6b, 0x53, 0x65, 0x58, 0x54, 0x41, 0x37, 0x79, 0x68, 0x6c, 0x57, 0x38, 0x61, 0x53, 0x56, 0x74, + 0x37, 0x5c, 0x0a, + 0x09, 0x43, 0x6b, 0x75, 0x53, 0x70, 0x4e, 0x4a, 0x34, 0x30, 0x31, 0x6a, 0x66, 0x4d, 0x46, 0x6f, 0x44, 0x4d, + 0x4f, 0x59, 0x66, 0x6c, 0x69, 0x52, 0x4a, 0x70, 0x54, 0x52, 0x6d, 0x44, 0x52, 0x2f, 0x70, 0x47, 0x6f, 0x43, + 0x70, 0x78, 0x4e, 0x72, 0x42, 0x68, 0x4b, 0x77, 0x54, 0x53, 0x5a, 0x4b, 0x6b, 0x33, 0x4c, 0x30, 0x41, 0x62, + 0x41, 0x36, 0x73, 0x47, 0x4f, 0x6b, 0x62, 0x52, 0x70, 0x6f, 0x41, 0x48, 0x49, 0x6a, 0x46, 0x58, 0x35, 0x4b, + 0x6b, 0x5c, 0x0a, + 0x09, 0x71, 0x70, 0x6f, 0x41, 0x48, 0x44, 0x44, 0x61, 0x4e, 0x34, 0x7a, 0x55, 0x41, 0x49, 0x7a, 0x36, 0x68, + 0x79, 0x52, 0x4a, 0x55, 0x75, 0x6c, 0x31, 0x31, 0x41, 0x43, 0x38, 0x50, 0x6f, 0x63, 0x67, 0x6b, 0x69, 0x53, + 0x70, 0x4f, 0x4b, 0x50, 0x57, 0x38, 0x75, 0x47, 0x75, 0x41, 0x65, 0x67, 0x42, 0x6e, 0x67, 0x47, 0x6d, 0x35, + 0x35, 0x56, 0x49, 0x6b, 0x69, 0x54, 0x6c, 0x62, 0x68, 0x6c, 0x78, 0x48, 0x63, 0x43, 0x36, 0x34, 0x62, 0x34, + 0x34, 0x5c, 0x0a, + 0x09, 0x33, 0x41, 0x52, 0x67, 0x48, 0x68, 0x5a, 0x2f, 0x53, 0x5a, 0x4b, 0x71, 0x62, 0x6a, 0x70, 0x52, 0x30, + 0x34, 0x63, 0x31, 0x58, 0x41, 0x4f, 0x77, 0x58, 0x33, 0x35, 0x5a, 0x4a, 0x45, 0x6c, 0x53, 0x67, 0x56, 0x34, + 0x33, 0x30, 0x68, 0x65, 0x47, 0x61, 0x77, 0x44, 0x32, 0x7a, 0x7a, 0x47, 0x49, 0x4a, 0x45, 0x6b, 0x71, 0x7a, + 0x72, 0x34, 0x6a, 0x66, 0x63, 0x45, 0x4a, 0x67, 0x43, 0x52, 0x4a, 0x39, 0x54, 0x58, 0x69, 0x68, 0x2f, 0x71, + 0x4e, 0x5c, 0x0a, + 0x09, 0x4c, 0x77, 0x4b, 0x63, 0x52, 0x47, 0x77, 0x61, 0x4d, 0x44, 0x48, 0x76, 0x52, 0x4a, 0x49, 0x6b, 0x4b, + 0x58, 0x64, 0x72, 0x67, 0x63, 0x32, 0x41, 0x4e, 0x52, 0x74, 0x2f, 0x59, 0x65, 0x4d, 0x4a, 0x77, 0x4b, 0x35, + 0x59, 0x2f, 0x43, 0x56, 0x4a, 0x71, 0x6f, 0x75, 0x4a, 0x77, 0x47, 0x37, 0x44, 0x66, 0x57, 0x48, 0x6a, 0x42, + 0x6d, 0x43, 0x76, 0x2f, 0x4c, 0x4e, 0x49, 0x6b, 0x71, 0x51, 0x43, 0x44, 0x56, 0x76, 0x62, 0x62, 0x51, 0x41, + 0x6b, 0x5c, 0x0a, + 0x09, 0x53, 0x61, 0x6f, 0x33, 0x47, 0x77, 0x42, 0x4a, 0x6b, 0x68, 0x70, 0x6f, 0x37, 0x2b, 0x46, 0x2b, 0x63, + 0x2b, 0x68, 0x46, 0x67, 0x44, 0x33, 0x41, 0x63, 0x6d, 0x42, 0x4b, 0x55, 0x59, 0x6b, 0x6b, 0x53, 0x56, 0x4c, + 0x75, 0x56, 0x67, 0x48, 0x54, 0x32, 0x47, 0x68, 0x48, 0x77, 0x4b, 0x45, 0x54, 0x67, 0x42, 0x32, 0x78, 0x2b, + 0x45, 0x75, 0x53, 0x56, 0x44, 0x64, 0x54, 0x67, 0x42, 0x30, 0x32, 0x2f, 0x73, 0x32, 0x68, 0x44, 0x63, 0x43, + 0x75, 0x5c, 0x0a, + 0x09, 0x78, 0x57, 0x57, 0x52, 0x4a, 0x45, 0x6b, 0x46, 0x32, 0x6d, 0x58, 0x6a, 0x33, 0x78, 0x6a, 0x61, 0x41, + 0x41, 0x78, 0x37, 0x6d, 0x34, 0x41, 0x6b, 0x53, 0x61, 0x71, 0x38, 0x54, 0x54, 0x37, 0x6b, 0x44, 0x32, 0x30, + 0x41, 0x4e, 0x75, 0x6b, 0x4f, 0x4a, 0x45, 0x6c, 0x53, 0x4c, 0x59, 0x7a, 0x61, 0x41, 0x49, 0x7a, 0x34, 0x78, + 0x43, 0x42, 0x4a, 0x6b, 0x6c, 0x52, 0x70, 0x6d, 0x33, 0x7a, 0x49, 0x48, 0x37, 0x77, 0x4c, 0x6f, 0x49, 0x66, + 0x59, 0x5c, 0x0a, + 0x09, 0x41, 0x6e, 0x68, 0x79, 0x30, 0x59, 0x6b, 0x6b, 0x53, 0x56, 0x4c, 0x75, 0x56, 0x68, 0x4e, 0x62, 0x41, + 0x72, 0x39, 0x34, 0x4a, 0x38, 0x44, 0x67, 0x42, 0x47, 0x42, 0x72, 0x4c, 0x50, 0x36, 0x53, 0x4a, 0x4e, 0x58, + 0x56, 0x5a, 0x47, 0x44, 0x62, 0x6f, 0x62, 0x38, 0x78, 0x32, 0x41, 0x44, 0x73, 0x56, 0x48, 0x77, 0x57, 0x53, + 0x5a, 0x4a, 0x55, 0x6f, 0x41, 0x31, 0x71, 0x2f, 0x57, 0x41, 0x44, 0x38, 0x4b, 0x6f, 0x45, 0x51, 0x53, 0x52, + 0x4a, 0x5c, 0x0a, + 0x09, 0x55, 0x6e, 0x48, 0x6d, 0x44, 0x76, 0x33, 0x46, 0x59, 0x41, 0x4f, 0x77, 0x59, 0x34, 0x49, 0x67, 0x6b, + 0x69, 0x53, 0x70, 0x4f, 0x4d, 0x4d, 0x32, 0x41, 0x48, 0x4f, 0x48, 0x2b, 0x55, 0x5a, 0x4a, 0x6b, 0x6c, 0x51, + 0x66, 0x4e, 0x67, 0x43, 0x53, 0x4a, 0x44, 0x58, 0x51, 0x42, 0x74, 0x63, 0x41, 0x44, 0x4e, 0x34, 0x47, 0x75, + 0x4a, 0x79, 0x34, 0x50, 0x55, 0x43, 0x53, 0x4a, 0x4e, 0x58, 0x54, 0x4b, 0x6d, 0x44, 0x71, 0x34, 0x43, 0x39, + 0x36, 0x5c, 0x0a, + 0x09, 0x67, 0x4a, 0x6c, 0x59, 0x2f, 0x43, 0x56, 0x4a, 0x71, 0x72, 0x73, 0x70, 0x77, 0x4f, 0x61, 0x44, 0x76, + 0x2b, 0x68, 0x68, 0x6f, 0x2f, 0x73, 0x43, 0x4a, 0x55, 0x6c, 0x53, 0x62, 0x62, 0x31, 0x59, 0x38, 0x32, 0x30, + 0x41, 0x4a, 0x45, 0x6c, 0x71, 0x44, 0x68, 0x73, 0x41, 0x53, 0x5a, 0x49, 0x61, 0x61, 0x4c, 0x76, 0x42, 0x6e, + 0x2f, 0x51, 0x4d, 0x2f, 0x59, 0x55, 0x6b, 0x53, 0x61, 0x71, 0x31, 0x62, 0x51, 0x5a, 0x2f, 0x30, 0x6a, 0x50, + 0x30, 0x5c, 0x0a, + 0x09, 0x46, 0x35, 0x49, 0x6b, 0x71, 0x64, 0x59, 0x32, 0x6d, 0x41, 0x44, 0x4d, 0x53, 0x52, 0x68, 0x45, 0x6b, + 0x69, 0x51, 0x56, 0x5a, 0x36, 0x76, 0x42, 0x6e, 0x2f, 0x51, 0x41, 0x57, 0x79, 0x51, 0x4d, 0x49, 0x6b, 0x6d, + 0x53, 0x69, 0x72, 0x50, 0x6c, 0x34, 0x45, 0x39, 0x36, 0x47, 0x4e, 0x49, 0x4e, 0x53, 0x4a, 0x4b, 0x6b, 0x57, + 0x6e, 0x76, 0x78, 0x51, 0x2f, 0x2b, 0x34, 0x2f, 0x76, 0x37, 0x2b, 0x50, 0x74, 0x5a, 0x76, 0x43, 0x53, 0x78, + 0x4a, 0x5c, 0x0a, + 0x09, 0x6b, 0x75, 0x70, 0x72, 0x48, 0x64, 0x41, 0x4c, 0x39, 0x50, 0x56, 0x67, 0x38, 0x5a, 0x63, 0x6b, 0x71, + 0x53, 0x6c, 0x36, 0x67, 0x46, 0x6d, 0x44, 0x50, 0x35, 0x45, 0x6b, 0x53, 0x63, 0x30, 0x78, 0x42, 0x32, 0x77, + 0x41, 0x4a, 0x45, 0x6c, 0x71, 0x47, 0x69, 0x63, 0x41, 0x6b, 0x69, 0x51, 0x31, 0x30, 0x41, 0x79, 0x77, 0x41, + 0x5a, 0x41, 0x6b, 0x71, 0x57, 0x6c, 0x73, 0x41, 0x43, 0x52, 0x4a, 0x61, 0x69, 0x41, 0x62, 0x41, 0x45, 0x6d, + 0x53, 0x5c, 0x0a, + 0x09, 0x47, 0x73, 0x67, 0x47, 0x51, 0x4a, 0x4b, 0x6b, 0x42, 0x72, 0x49, 0x42, 0x6b, 0x43, 0x53, 0x70, 0x67, + 0x57, 0x77, 0x41, 0x4a, 0x45, 0x6c, 0x71, 0x6f, 0x47, 0x6c, 0x67, 0x41, 0x79, 0x42, 0x4a, 0x55, 0x74, 0x4e, + 0x4d, 0x41, 0x68, 0x73, 0x41, 0x53, 0x5a, 0x4b, 0x61, 0x5a, 0x6a, 0x4c, 0x59, 0x41, 0x45, 0x69, 0x53, 0x31, + 0x44, 0x52, 0x54, 0x77, 0x51, 0x5a, 0x41, 0x6b, 0x71, 0x53, 0x6d, 0x63, 0x51, 0x6c, 0x41, 0x6b, 0x71, 0x51, + 0x47, 0x5c, 0x0a, + 0x09, 0x6d, 0x67, 0x49, 0x32, 0x41, 0x4a, 0x49, 0x6b, 0x4e, 0x59, 0x30, 0x4e, 0x67, 0x43, 0x52, 0x4a, 0x44, + 0x54, 0x51, 0x42, 0x62, 0x41, 0x41, 0x6b, 0x53, 0x57, 0x6f, 0x6b, 0x47, 0x77, 0x42, 0x4a, 0x6b, 0x68, 0x72, + 0x49, 0x42, 0x6b, 0x43, 0x53, 0x70, 0x47, 0x62, 0x70, 0x42, 0x52, 0x6a, 0x58, 0x33, 0x39, 0x2f, 0x66, 0x6e, + 0x7a, 0x71, 0x4a, 0x4a, 0x45, 0x6b, 0x71, 0x31, 0x44, 0x67, 0x6e, 0x41, 0x4a, 0x49, 0x6b, 0x4e, 0x5a, 0x41, + 0x4e, 0x5c, 0x0a, + 0x09, 0x67, 0x43, 0x52, 0x4a, 0x44, 0x57, 0x51, 0x44, 0x49, 0x45, 0x6c, 0x53, 0x41, 0x39, 0x6b, 0x41, 0x53, + 0x4a, 0x4c, 0x55, 0x4c, 0x4d, 0x2b, 0x42, 0x44, 0x59, 0x41, 0x6b, 0x53, 0x55, 0x33, 0x7a, 0x50, 0x4e, 0x67, + 0x41, 0x53, 0x4a, 0x4c, 0x55, 0x53, 0x44, 0x59, 0x41, 0x6b, 0x69, 0x51, 0x31, 0x6b, 0x41, 0x32, 0x41, 0x4a, + 0x45, 0x6e, 0x4e, 0x38, 0x67, 0x4c, 0x59, 0x41, 0x45, 0x69, 0x53, 0x31, 0x44, 0x53, 0x72, 0x77, 0x41, 0x5a, + 0x41, 0x5c, 0x0a, + 0x09, 0x6b, 0x71, 0x53, 0x6d, 0x73, 0x51, 0x47, 0x51, 0x4a, 0x4b, 0x6d, 0x42, 0x31, 0x6f, 0x41, 0x4e, 0x67, + 0x43, 0x52, 0x4a, 0x54, 0x62, 0x4d, 0x53, 0x62, 0x41, 0x41, 0x6b, 0x53, 0x57, 0x71, 0x61, 0x31, 0x57, 0x41, + 0x44, 0x49, 0x45, 0x6c, 0x53, 0x30, 0x37, 0x67, 0x45, 0x49, 0x45, 0x6c, 0x53, 0x41, 0x79, 0x30, 0x48, 0x47, + 0x77, 0x42, 0x4a, 0x6b, 0x70, 0x70, 0x6d, 0x4b, 0x64, 0x67, 0x41, 0x53, 0x4a, 0x4c, 0x55, 0x4e, 0x44, 0x59, + 0x41, 0x5c, 0x0a, + 0x09, 0x6b, 0x69, 0x51, 0x31, 0x6b, 0x41, 0x32, 0x41, 0x4a, 0x45, 0x6b, 0x4e, 0x5a, 0x41, 0x4d, 0x67, 0x53, + 0x56, 0x49, 0x44, 0x32, 0x51, 0x42, 0x49, 0x6b, 0x74, 0x52, 0x41, 0x4e, 0x67, 0x43, 0x53, 0x4a, 0x44, 0x58, + 0x51, 0x55, 0x32, 0x41, 0x44, 0x49, 0x45, 0x6c, 0x53, 0x30, 0x7a, 0x77, 0x42, 0x4d, 0x4b, 0x36, 0x2f, 0x76, + 0x37, 0x38, 0x50, 0x47, 0x77, 0x46, 0x4a, 0x6b, 0x70, 0x70, 0x67, 0x48, 0x64, 0x41, 0x4c, 0x39, 0x50, 0x55, + 0x77, 0x5c, 0x0a, + 0x09, 0x4d, 0x41, 0x71, 0x51, 0x4a, 0x45, 0x6d, 0x31, 0x39, 0x78, 0x54, 0x51, 0x42, 0x2f, 0x48, 0x4a, 0x2f, + 0x38, 0x6d, 0x30, 0x57, 0x53, 0x52, 0x4a, 0x55, 0x6b, 0x45, 0x57, 0x44, 0x2f, 0x37, 0x45, 0x42, 0x6b, 0x43, + 0x53, 0x70, 0x4f, 0x5a, 0x34, 0x73, 0x65, 0x62, 0x33, 0x41, 0x49, 0x73, 0x53, 0x42, 0x70, 0x45, 0x6b, 0x53, + 0x63, 0x56, 0x35, 0x59, 0x76, 0x41, 0x6e, 0x50, 0x63, 0x43, 0x6a, 0x43, 0x59, 0x4e, 0x49, 0x6b, 0x71, 0x54, + 0x69, 0x5c, 0x0a, + 0x09, 0x4c, 0x42, 0x7a, 0x38, 0x53, 0x63, 0x2f, 0x51, 0x58, 0x30, 0x69, 0x53, 0x70, 0x46, 0x70, 0x37, 0x38, + 0x55, 0x4f, 0x2f, 0x45, 0x77, 0x42, 0x4a, 0x6b, 0x70, 0x72, 0x44, 0x43, 0x59, 0x41, 0x6b, 0x53, 0x51, 0x32, + 0x30, 0x77, 0x51, 0x54, 0x67, 0x4c, 0x77, 0x6d, 0x44, 0x53, 0x4a, 0x4b, 0x6b, 0x34, 0x72, 0x7a, 0x34, 0x6f, + 0x58, 0x39, 0x63, 0x66, 0x33, 0x38, 0x2f, 0x77, 0x48, 0x4a, 0x67, 0x73, 0x32, 0x52, 0x78, 0x4a, 0x45, 0x6c, + 0x53, 0x5c, 0x0a, + 0x09, 0x33, 0x6c, 0x59, 0x42, 0x55, 0x77, 0x64, 0x2f, 0x4d, 0x62, 0x67, 0x46, 0x38, 0x4a, 0x2b, 0x54, 0x52, + 0x4a, 0x45, 0x6b, 0x53, 0x55, 0x56, 0x35, 0x65, 0x4f, 0x67, 0x76, 0x42, 0x68, 0x75, 0x41, 0x2f, 0x30, 0x6f, + 0x51, 0x52, 0x4a, 0x49, 0x6b, 0x46, 0x57, 0x66, 0x59, 0x42, 0x75, 0x44, 0x68, 0x59, 0x62, 0x35, 0x52, 0x6b, + 0x69, 0x54, 0x56, 0x78, 0x30, 0x4e, 0x44, 0x66, 0x32, 0x45, 0x44, 0x49, 0x45, 0x6c, 0x53, 0x4d, 0x77, 0x7a, + 0x62, 0x5c, 0x0a, + 0x09, 0x41, 0x50, 0x77, 0x78, 0x51, 0x52, 0x42, 0x4a, 0x6b, 0x6c, 0x53, 0x63, 0x59, 0x52, 0x75, 0x41, 0x50, + 0x79, 0x51, 0x49, 0x49, 0x6b, 0x6d, 0x53, 0x69, 0x72, 0x50, 0x42, 0x74, 0x48, 0x2f, 0x77, 0x4e, 0x73, 0x41, + 0x65, 0x59, 0x41, 0x55, 0x77, 0x4f, 0x55, 0x55, 0x69, 0x53, 0x5a, 0x4b, 0x55, 0x71, 0x39, 0x58, 0x45, 0x37, + 0x66, 0x37, 0x72, 0x42, 0x6e, 0x39, 0x6a, 0x63, 0x41, 0x4b, 0x77, 0x44, 0x76, 0x68, 0x39, 0x69, 0x6b, 0x53, + 0x53, 0x5c, 0x0a, + 0x09, 0x4a, 0x43, 0x6c, 0x33, 0x44, 0x7a, 0x4b, 0x6b, 0x2b, 0x4d, 0x50, 0x36, 0x42, 0x67, 0x44, 0x67, 0x67, + 0x57, 0x4b, 0x7a, 0x53, 0x4a, 0x4b, 0x6b, 0x67, 0x74, 0x79, 0x2f, 0x38, 0x57, 0x2f, 0x30, 0x6a, 0x50, 0x5a, + 0x46, 0x53, 0x5a, 0x4a, 0x55, 0x43, 0x77, 0x73, 0x32, 0x2f, 0x6f, 0x32, 0x65, 0x30, 0x62, 0x34, 0x6f, 0x53, + 0x5a, 0x4a, 0x71, 0x59, 0x64, 0x51, 0x4a, 0x77, 0x48, 0x30, 0x46, 0x42, 0x70, 0x45, 0x6b, 0x53, 0x63, 0x58, + 0x5a, 0x5c, 0x0a, + 0x09, 0x35, 0x45, 0x50, 0x2b, 0x34, 0x46, 0x30, 0x41, 0x45, 0x4d, 0x33, 0x41, 0x63, 0x6d, 0x42, 0x4b, 0x6b, + 0x59, 0x6b, 0x6b, 0x53, 0x56, 0x4b, 0x75, 0x4e, 0x72, 0x6b, 0x44, 0x41, 0x44, 0x61, 0x63, 0x41, 0x4b, 0x77, + 0x44, 0x66, 0x6c, 0x74, 0x6b, 0x49, 0x6b, 0x6d, 0x53, 0x6c, 0x4c, 0x76, 0x66, 0x73, 0x56, 0x48, 0x78, 0x68, + 0x77, 0x30, 0x62, 0x41, 0x49, 0x43, 0x37, 0x69, 0x38, 0x6b, 0x69, 0x53, 0x5a, 0x49, 0x4b, 0x63, 0x74, 0x64, + 0x77, 0x5c, 0x0a, + 0x09, 0x76, 0x32, 0x6b, 0x44, 0x49, 0x45, 0x6c, 0x53, 0x76, 0x51, 0x31, 0x62, 0x32, 0x32, 0x30, 0x41, 0x4a, + 0x45, 0x6d, 0x71, 0x74, 0x33, 0x75, 0x47, 0x2b, 0x38, 0x32, 0x68, 0x46, 0x77, 0x45, 0x43, 0x54, 0x43, 0x4b, + 0x32, 0x42, 0x4a, 0x35, 0x59, 0x52, 0x43, 0x4a, 0x4a, 0x6b, 0x70, 0x53, 0x72, 0x74, 0x63, 0x51, 0x46, 0x67, + 0x47, 0x73, 0x32, 0x2f, 0x73, 0x4c, 0x47, 0x45, 0x34, 0x41, 0x31, 0x65, 0x44, 0x75, 0x67, 0x4a, 0x45, 0x6c, + 0x31, 0x5c, 0x0a, + 0x09, 0x73, 0x59, 0x42, 0x68, 0x69, 0x6a, 0x39, 0x73, 0x32, 0x67, 0x41, 0x41, 0x33, 0x4a, 0x46, 0x76, 0x46, + 0x6b, 0x6d, 0x53, 0x56, 0x4a, 0x42, 0x66, 0x6a, 0x2f, 0x51, 0x46, 0x47, 0x77, 0x42, 0x4a, 0x6b, 0x75, 0x72, + 0x72, 0x39, 0x70, 0x47, 0x2b, 0x4d, 0x46, 0x77, 0x44, 0x4d, 0x4f, 0x49, 0x33, 0x53, 0x35, 0x4b, 0x6b, 0x53, + 0x76, 0x6e, 0x56, 0x53, 0x46, 0x2f, 0x59, 0x2b, 0x43, 0x4a, 0x41, 0x69, 0x4b, 0x62, 0x67, 0x47, 0x57, 0x42, + 0x36, 0x5c, 0x0a, + 0x09, 0x6e, 0x6f, 0x6b, 0x6b, 0x53, 0x56, 0x4b, 0x75, 0x6c, 0x67, 0x47, 0x62, 0x4d, 0x38, 0x77, 0x6d, 0x51, + 0x44, 0x44, 0x38, 0x42, 0x47, 0x41, 0x64, 0x4c, 0x67, 0x4e, 0x49, 0x6b, 0x6c, 0x52, 0x31, 0x64, 0x7a, 0x42, + 0x43, 0x38, 0x59, 0x66, 0x68, 0x47, 0x77, 0x41, 0x59, 0x5a, 0x57, 0x51, 0x67, 0x53, 0x5a, 0x49, 0x71, 0x59, + 0x64, 0x52, 0x61, 0x50, 0x6c, 0x49, 0x44, 0x63, 0x46, 0x73, 0x4f, 0x51, 0x53, 0x52, 0x4a, 0x55, 0x6e, 0x46, + 0x47, 0x5c, 0x0a, + 0x09, 0x72, 0x65, 0x58, 0x44, 0x58, 0x51, 0x4d, 0x41, 0x73, 0x57, 0x6e, 0x41, 0x4d, 0x38, 0x43, 0x45, 0x50, + 0x42, 0x4a, 0x4a, 0x6b, 0x71, 0x52, 0x63, 0x39, 0x51, 0x45, 0x7a, 0x69, 0x63, 0x33, 0x39, 0x68, 0x6a, 0x58, + 0x53, 0x42, 0x47, 0x41, 0x46, 0x49, 0x7a, 0x77, 0x38, 0x51, 0x4a, 0x49, 0x6b, 0x6c, 0x64, 0x35, 0x64, 0x6a, + 0x46, 0x4c, 0x38, 0x59, 0x65, 0x51, 0x47, 0x41, 0x4f, 0x44, 0x57, 0x62, 0x4c, 0x4e, 0x49, 0x6b, 0x71, 0x53, + 0x43, 0x5c, 0x0a, + 0x09, 0x33, 0x44, 0x4c, 0x57, 0x4e, 0x34, 0x7a, 0x57, 0x41, 0x49, 0x7a, 0x35, 0x68, 0x79, 0x56, 0x4a, 0x55, + 0x69, 0x6d, 0x4e, 0x2b, 0x53, 0x46, 0x2b, 0x70, 0x47, 0x73, 0x41, 0x41, 0x47, 0x59, 0x41, 0x54, 0x7a, 0x4e, + 0x36, 0x6b, 0x79, 0x42, 0x4a, 0x6b, 0x73, 0x70, 0x6c, 0x48, 0x54, 0x41, 0x4c, 0x65, 0x48, 0x61, 0x30, 0x62, + 0x78, 0x71, 0x74, 0x75, 0x43, 0x2f, 0x46, 0x36, 0x77, 0x41, 0x6b, 0x53, 0x61, 0x71, 0x61, 0x75, 0x78, 0x6d, + 0x6a, 0x5c, 0x0a, + 0x09, 0x2b, 0x4d, 0x50, 0x59, 0x6e, 0x2b, 0x36, 0x76, 0x7a, 0x79, 0x61, 0x4c, 0x4a, 0x45, 0x6b, 0x71, 0x79, + 0x41, 0x32, 0x74, 0x66, 0x4a, 0x4d, 0x4e, 0x67, 0x43, 0x52, 0x4a, 0x39, 0x64, 0x4a, 0x53, 0x37, 0x52, 0x37, + 0x74, 0x47, 0x67, 0x43, 0x41, 0x53, 0x63, 0x52, 0x2b, 0x41, 0x4a, 0x4f, 0x7a, 0x53, 0x43, 0x52, 0x4a, 0x6b, + 0x6e, 0x4c, 0x31, 0x48, 0x48, 0x48, 0x2f, 0x2f, 0x35, 0x71, 0x78, 0x76, 0x6e, 0x47, 0x73, 0x43, 0x63, 0x41, + 0x61, 0x5c, 0x0a, + 0x09, 0x76, 0x42, 0x74, 0x41, 0x6b, 0x71, 0x53, 0x71, 0x75, 0x49, 0x55, 0x57, 0x69, 0x6a, 0x2b, 0x30, 0x64, + 0x6f, 0x57, 0x2f, 0x79, 0x77, 0x43, 0x53, 0x4a, 0x46, 0x56, 0x44, 0x79, 0x7a, 0x57, 0x37, 0x6c, 0x51, 0x62, + 0x67, 0x4a, 0x31, 0x30, 0x45, 0x6b, 0x53, 0x52, 0x4a, 0x78, 0x57, 0x6d, 0x35, 0x41, 0x52, 0x6a, 0x72, 0x47, + 0x6f, 0x42, 0x42, 0x44, 0x77, 0x45, 0x37, 0x64, 0x52, 0x78, 0x48, 0x6b, 0x69, 0x54, 0x6c, 0x37, 0x57, 0x46, + 0x67, 0x5c, 0x0a, + 0x09, 0x62, 0x71, 0x76, 0x66, 0x33, 0x4f, 0x6f, 0x6d, 0x50, 0x7a, 0x2f, 0x75, 0x4c, 0x49, 0x73, 0x6b, 0x53, + 0x53, 0x70, 0x49, 0x57, 0x37, 0x58, 0x61, 0x42, 0x6b, 0x43, 0x53, 0x70, 0x48, 0x70, 0x6f, 0x71, 0x31, 0x61, + 0x33, 0x75, 0x67, 0x51, 0x77, 0x43, 0x58, 0x67, 0x4b, 0x6d, 0x4e, 0x70, 0x4a, 0x49, 0x6b, 0x6d, 0x53, 0x6c, + 0x4b, 0x75, 0x56, 0x78, 0x50, 0x61, 0x2f, 0x4c, 0x64, 0x30, 0x42, 0x41, 0x4b, 0x31, 0x50, 0x41, 0x4e, 0x62, + 0x67, 0x5c, 0x0a, + 0x09, 0x78, 0x59, 0x43, 0x53, 0x4a, 0x4a, 0x58, 0x56, 0x64, 0x62, 0x52, 0x52, 0x2f, 0x4b, 0x47, 0x39, 0x42, + 0x2f, 0x33, 0x38, 0x71, 0x4c, 0x30, 0x73, 0x6b, 0x69, 0x53, 0x70, 0x49, 0x44, 0x39, 0x6f, 0x39, 0x77, 0x2b, + 0x30, 0x75, 0x67, 0x51, 0x41, 0x38, 0x58, 0x54, 0x41, 0x78, 0x63, 0x44, 0x45, 0x64, 0x67, 0x38, 0x69, 0x53, + 0x5a, 0x4a, 0x79, 0x73, 0x78, 0x62, 0x59, 0x6b, 0x68, 0x59, 0x65, 0x41, 0x44, 0x52, 0x55, 0x4f, 0x78, 0x4f, + 0x41, 0x5c, 0x0a, + 0x09, 0x70, 0x63, 0x44, 0x50, 0x32, 0x6e, 0x6c, 0x7a, 0x53, 0x5a, 0x4b, 0x55, 0x75, 0x78, 0x74, 0x70, 0x73, + 0x2f, 0x68, 0x44, 0x65, 0x77, 0x30, 0x41, 0x77, 0x46, 0x58, 0x74, 0x48, 0x6b, 0x43, 0x53, 0x4a, 0x4f, 0x57, + 0x71, 0x6f, 0x39, 0x72, 0x63, 0x7a, 0x68, 0x49, 0x41, 0x77, 0x47, 0x78, 0x67, 0x45, 0x54, 0x43, 0x2b, 0x6b, + 0x34, 0x4e, 0x4a, 0x6b, 0x71, 0x52, 0x4d, 0x39, 0x51, 0x46, 0x7a, 0x67, 0x43, 0x58, 0x74, 0x2f, 0x73, 0x46, + 0x32, 0x5c, 0x0a, + 0x09, 0x4a, 0x77, 0x42, 0x4c, 0x38, 0x4f, 0x46, 0x41, 0x6b, 0x69, 0x53, 0x56, 0x78, 0x61, 0x31, 0x30, 0x55, + 0x50, 0x79, 0x68, 0x2f, 0x51, 0x59, 0x41, 0x34, 0x4d, 0x70, 0x4f, 0x44, 0x69, 0x52, 0x4a, 0x6b, 0x6a, 0x4a, + 0x33, 0x52, 0x61, 0x64, 0x2f, 0x73, 0x4e, 0x30, 0x6c, 0x41, 0x49, 0x69, 0x4e, 0x42, 0x68, 0x37, 0x48, 0x75, + 0x77, 0x45, 0x6b, 0x53, 0x55, 0x70, 0x70, 0x4c, 0x66, 0x42, 0x79, 0x59, 0x71, 0x4f, 0x2b, 0x74, 0x6e, 0x55, + 0x79, 0x5c, 0x0a, + 0x09, 0x41, 0x58, 0x69, 0x4b, 0x32, 0x48, 0x42, 0x41, 0x6b, 0x69, 0x53, 0x6c, 0x63, 0x78, 0x30, 0x64, 0x46, + 0x6e, 0x2f, 0x6f, 0x72, 0x41, 0x45, 0x41, 0x75, 0x4c, 0x7a, 0x54, 0x41, 0x30, 0x71, 0x53, 0x70, 0x45, 0x78, + 0x30, 0x56, 0x59, 0x73, 0x37, 0x57, 0x51, 0x49, 0x41, 0x6d, 0x41, 0x49, 0x38, 0x4f, 0x66, 0x43, 0x6a, 0x4a, + 0x45, 0x6b, 0x71, 0x31, 0x69, 0x70, 0x69, 0x38, 0x35, 0x39, 0x56, 0x6e, 0x62, 0x35, 0x42, 0x70, 0x78, 0x4f, + 0x41, 0x5c, 0x0a, + 0x09, 0x56, 0x58, 0x53, 0x77, 0x37, 0x61, 0x41, 0x6b, 0x53, 0x63, 0x72, 0x45, 0x44, 0x2b, 0x69, 0x69, 0x2b, + 0x45, 0x50, 0x6e, 0x44, 0x51, 0x44, 0x41, 0x70, 0x64, 0x30, 0x63, 0x57, 0x4a, 0x49, 0x6b, 0x64, 0x61, 0x7a, + 0x72, 0x47, 0x74, 0x7a, 0x70, 0x45, 0x67, 0x42, 0x45, 0x38, 0x2f, 0x41, 0x49, 0x73, 0x45, 0x32, 0x33, 0x49, + 0x53, 0x52, 0x4a, 0x55, 0x73, 0x73, 0x65, 0x41, 0x37, 0x59, 0x6e, 0x4e, 0x67, 0x48, 0x71, 0x57, 0x44, 0x63, + 0x54, 0x5c, 0x0a, + 0x09, 0x67, 0x48, 0x58, 0x41, 0x4a, 0x64, 0x30, 0x63, 0x58, 0x4a, 0x49, 0x6b, 0x74, 0x65, 0x31, 0x62, 0x64, + 0x46, 0x6e, 0x38, 0x6f, 0x62, 0x73, 0x4a, 0x41, 0x4d, 0x41, 0x72, 0x67, 0x64, 0x38, 0x44, 0x34, 0x37, 0x6f, + 0x4e, 0x49, 0x6b, 0x6d, 0x53, 0x78, 0x74, 0x51, 0x50, 0x76, 0x42, 0x72, 0x34, 0x59, 0x37, 0x64, 0x76, 0x31, + 0x4d, 0x30, 0x45, 0x67, 0x49, 0x45, 0x41, 0x74, 0x33, 0x55, 0x62, 0x51, 0x70, 0x49, 0x6b, 0x74, 0x65, 0x51, + 0x32, 0x5c, 0x0a, + 0x09, 0x4d, 0x69, 0x6a, 0x2b, 0x30, 0x48, 0x30, 0x44, 0x41, 0x48, 0x42, 0x78, 0x42, 0x75, 0x38, 0x68, 0x53, + 0x5a, 0x4c, 0x47, 0x39, 0x73, 0x32, 0x73, 0x33, 0x71, 0x6a, 0x62, 0x4a, 0x51, 0x43, 0x41, 0x71, 0x63, 0x43, + 0x6a, 0x77, 0x50, 0x54, 0x75, 0x34, 0x30, 0x69, 0x53, 0x70, 0x42, 0x45, 0x73, 0x49, 0x79, 0x36, 0x38, 0x58, + 0x35, 0x6e, 0x46, 0x6d, 0x32, 0x55, 0x78, 0x41, 0x56, 0x68, 0x4a, 0x58, 0x4a, 0x41, 0x67, 0x53, 0x5a, 0x4c, + 0x79, 0x5c, 0x0a, + 0x09, 0x63, 0x79, 0x6b, 0x5a, 0x46, 0x58, 0x2f, 0x49, 0x5a, 0x67, 0x49, 0x41, 0x73, 0x43, 0x74, 0x77, 0x58, + 0x78, 0x5a, 0x76, 0x4a, 0x45, 0x6d, 0x53, 0x68, 0x72, 0x55, 0x62, 0x73, 0x43, 0x43, 0x72, 0x4e, 0x38, 0x74, + 0x69, 0x41, 0x67, 0x41, 0x52, 0x36, 0x4f, 0x63, 0x5a, 0x76, 0x5a, 0x63, 0x6b, 0x53, 0x64, 0x72, 0x51, 0x7a, + 0x38, 0x6d, 0x77, 0x2b, 0x45, 0x4e, 0x32, 0x44, 0x51, 0x44, 0x41, 0x68, 0x52, 0x6d, 0x2b, 0x6c, 0x79, 0x52, + 0x4a, 0x5c, 0x0a, + 0x09, 0x57, 0x75, 0x39, 0x72, 0x57, 0x62, 0x39, 0x68, 0x56, 0x6b, 0x73, 0x41, 0x41, 0x4c, 0x33, 0x45, 0x78, + 0x59, 0x43, 0x7a, 0x73, 0x33, 0x70, 0x44, 0x53, 0x5a, 0x4c, 0x45, 0x45, 0x75, 0x4c, 0x69, 0x76, 0x2b, 0x65, + 0x7a, 0x66, 0x4e, 0x4d, 0x73, 0x4a, 0x77, 0x44, 0x50, 0x41, 0x31, 0x2f, 0x50, 0x38, 0x50, 0x30, 0x6b, 0x53, + 0x56, 0x4c, 0x55, 0x31, 0x6b, 0x79, 0x4c, 0x50, 0x32, 0x51, 0x37, 0x41, 0x51, 0x43, 0x59, 0x41, 0x2f, 0x79, + 0x5a, 0x5c, 0x0a, + 0x09, 0x6d, 0x41, 0x5a, 0x49, 0x6b, 0x71, 0x54, 0x75, 0x50, 0x41, 0x2b, 0x38, 0x41, 0x6c, 0x69, 0x55, 0x39, + 0x52, 0x74, 0x6e, 0x4f, 0x51, 0x47, 0x41, 0x43, 0x50, 0x6a, 0x74, 0x6a, 0x4e, 0x39, 0x54, 0x6b, 0x71, 0x53, + 0x6d, 0x2b, 0x6a, 0x59, 0x35, 0x46, 0x48, 0x2f, 0x49, 0x66, 0x67, 0x49, 0x41, 0x73, 0x42, 0x64, 0x77, 0x56, + 0x39, 0x5a, 0x76, 0x4b, 0x6b, 0x6c, 0x53, 0x41, 0x2b, 0x30, 0x4e, 0x33, 0x4a, 0x33, 0x48, 0x47, 0x32, 0x63, + 0x39, 0x5c, 0x0a, + 0x09, 0x41, 0x59, 0x41, 0x49, 0x65, 0x6e, 0x4d, 0x4f, 0x37, 0x79, 0x74, 0x4a, 0x55, 0x70, 0x50, 0x63, 0x54, + 0x45, 0x37, 0x46, 0x48, 0x2f, 0x4a, 0x70, 0x41, 0x41, 0x43, 0x2b, 0x6b, 0x4e, 0x50, 0x37, 0x53, 0x70, 0x4c, + 0x55, 0x46, 0x46, 0x2f, 0x4d, 0x38, 0x38, 0x33, 0x7a, 0x57, 0x41, 0x4b, 0x41, 0x61, 0x43, 0x77, 0x57, 0x41, + 0x44, 0x76, 0x6e, 0x38, 0x65, 0x61, 0x53, 0x4a, 0x4e, 0x58, 0x63, 0x37, 0x34, 0x46, 0x64, 0x67, 0x48, 0x56, + 0x35, 0x5c, 0x0a, + 0x09, 0x48, 0x53, 0x43, 0x76, 0x43, 0x63, 0x41, 0x36, 0x34, 0x4e, 0x79, 0x63, 0x33, 0x6c, 0x75, 0x53, 0x70, + 0x4c, 0x6f, 0x37, 0x6c, 0x78, 0x79, 0x4c, 0x50, 0x2b, 0x51, 0x33, 0x41, 0x59, 0x43, 0x34, 0x46, 0x66, 0x43, + 0x2f, 0x67, 0x4b, 0x33, 0x7a, 0x4f, 0x6f, 0x41, 0x6b, 0x53, 0x54, 0x58, 0x30, 0x4f, 0x4c, 0x41, 0x44, 0x4f, + 0x64, 0x7a, 0x37, 0x50, 0x31, 0x52, 0x65, 0x45, 0x77, 0x43, 0x49, 0x34, 0x4f, 0x66, 0x6e, 0x2b, 0x50, 0x36, + 0x53, 0x5c, 0x0a, + 0x09, 0x4a, 0x4e, 0x58, 0x52, 0x2b, 0x65, 0x52, 0x63, 0x2f, 0x43, 0x48, 0x66, 0x43, 0x51, 0x44, 0x41, 0x56, + 0x47, 0x41, 0x68, 0x4d, 0x44, 0x50, 0x50, 0x67, 0x30, 0x69, 0x53, 0x56, 0x42, 0x4e, 0x4c, 0x67, 0x57, 0x33, + 0x4a, 0x38, 0x4c, 0x47, 0x2f, 0x49, 0x38, 0x6c, 0x7a, 0x41, 0x67, 0x44, 0x78, 0x46, 0x38, 0x6a, 0x31, 0x4b, + 0x6b, 0x5a, 0x4a, 0x6b, 0x6d, 0x72, 0x6b, 0x41, 0x67, 0x6f, 0x6f, 0x2f, 0x70, 0x44, 0x2f, 0x42, 0x41, 0x42, + 0x67, 0x5c, 0x0a, + 0x09, 0x42, 0x76, 0x43, 0x6e, 0x67, 0x52, 0x38, 0x6c, 0x53, 0x64, 0x4c, 0x77, 0x6c, 0x68, 0x46, 0x72, 0x2f, + 0x38, 0x38, 0x57, 0x63, 0x62, 0x43, 0x38, 0x4a, 0x77, 0x41, 0x51, 0x34, 0x34, 0x77, 0x4c, 0x43, 0x6a, 0x69, + 0x4f, 0x4a, 0x45, 0x6c, 0x56, 0x64, 0x67, 0x45, 0x46, 0x46, 0x58, 0x38, 0x6f, 0x5a, 0x67, 0x49, 0x41, 0x63, + 0x51, 0x33, 0x41, 0x6e, 0x34, 0x44, 0x70, 0x52, 0x52, 0x78, 0x4d, 0x6b, 0x71, 0x53, 0x4b, 0x57, 0x55, 0x34, + 0x38, 0x5c, 0x0a, + 0x09, 0x39, 0x4b, 0x65, 0x77, 0x42, 0x71, 0x43, 0x49, 0x43, 0x51, 0x44, 0x45, 0x58, 0x2b, 0x68, 0x4c, 0x42, + 0x52, 0x31, 0x4c, 0x6b, 0x71, 0x53, 0x71, 0x4b, 0x66, 0x54, 0x54, 0x50, 0x78, 0x51, 0x33, 0x41, 0x51, 0x44, + 0x59, 0x6e, 0x4a, 0x67, 0x43, 0x54, 0x43, 0x76, 0x71, 0x67, 0x4a, 0x49, 0x6b, 0x56, 0x63, 0x42, 0x79, 0x59, + 0x75, 0x33, 0x2f, 0x6d, 0x53, 0x49, 0x50, 0x57, 0x74, 0x51, 0x45, 0x41, 0x4f, 0x49, 0x76, 0x64, 0x6c, 0x36, + 0x42, 0x5c, 0x0a, + 0x09, 0x78, 0x35, 0x4d, 0x6b, 0x71, 0x51, 0x72, 0x4f, 0x6f, 0x2b, 0x44, 0x69, 0x44, 0x38, 0x56, 0x4f, 0x41, + 0x41, 0x41, 0x32, 0x41, 0x78, 0x34, 0x43, 0x74, 0x69, 0x6a, 0x79, 0x6f, 0x4a, 0x49, 0x6b, 0x6c, 0x64, 0x52, + 0x69, 0x59, 0x43, 0x36, 0x77, 0x6f, 0x75, 0x67, 0x44, 0x46, 0x7a, 0x6b, 0x42, 0x67, 0x50, 0x67, 0x4c, 0x6e, + 0x6c, 0x50, 0x77, 0x4d, 0x53, 0x56, 0x4a, 0x4b, 0x71, 0x74, 0x7a, 0x53, 0x46, 0x44, 0x38, 0x6f, 0x66, 0x67, + 0x4a, 0x5c, 0x0a, + 0x09, 0x41, 0x4d, 0x41, 0x6b, 0x34, 0x69, 0x6c, 0x48, 0x32, 0x78, 0x64, 0x39, 0x59, 0x45, 0x6d, 0x53, 0x53, + 0x75, 0x51, 0x52, 0x34, 0x4e, 0x58, 0x41, 0x6d, 0x68, 0x51, 0x48, 0x4c, 0x33, 0x6f, 0x43, 0x41, 0x50, 0x45, + 0x58, 0x2f, 0x57, 0x53, 0x43, 0x34, 0x30, 0x71, 0x53, 0x56, 0x43, 0x61, 0x66, 0x4a, 0x46, 0x48, 0x78, 0x68, + 0x7a, 0x51, 0x54, 0x41, 0x49, 0x44, 0x78, 0x77, 0x4e, 0x33, 0x41, 0x37, 0x69, 0x6b, 0x4f, 0x4c, 0x6b, 0x6c, + 0x53, 0x5c, 0x0a, + 0x09, 0x59, 0x76, 0x63, 0x42, 0x65, 0x77, 0x4a, 0x39, 0x71, 0x51, 0x4b, 0x6b, 0x6d, 0x41, 0x42, 0x41, 0x2f, + 0x49, 0x58, 0x50, 0x53, 0x48, 0x52, 0x73, 0x53, 0x5a, 0x4a, 0x53, 0x4f, 0x35, 0x4f, 0x45, 0x78, 0x52, 0x2f, + 0x53, 0x4e, 0x51, 0x41, 0x41, 0x31, 0x77, 0x48, 0x58, 0x4a, 0x6a, 0x79, 0x2b, 0x4a, 0x45, 0x6b, 0x70, 0x2f, + 0x4a, 0x51, 0x53, 0x31, 0x4c, 0x39, 0x55, 0x53, 0x77, 0x43, 0x44, 0x64, 0x67, 0x56, 0x2b, 0x53, 0x79, 0x77, + 0x4a, 0x5c, 0x0a, + 0x09, 0x53, 0x4a, 0x4a, 0x55, 0x64, 0x33, 0x33, 0x41, 0x58, 0x73, 0x43, 0x39, 0x71, 0x59, 0x4f, 0x6b, 0x6e, + 0x41, 0x41, 0x41, 0x4c, 0x41, 0x44, 0x2b, 0x62, 0x2b, 0x49, 0x4d, 0x6b, 0x69, 0x51, 0x56, 0x35, 0x64, 0x38, + 0x70, 0x51, 0x66, 0x47, 0x48, 0x39, 0x42, 0x4d, 0x41, 0x67, 0x43, 0x32, 0x42, 0x50, 0x2b, 0x41, 0x57, 0x77, + 0x5a, 0x4b, 0x6b, 0x65, 0x6c, 0x74, 0x4f, 0x33, 0x50, 0x62, 0x33, 0x52, 0x4f, 0x6f, 0x67, 0x6b, 0x48, 0x34, + 0x43, 0x5c, 0x0a, + 0x09, 0x41, 0x50, 0x41, 0x6b, 0x38, 0x4b, 0x6e, 0x55, 0x49, 0x53, 0x52, 0x4a, 0x79, 0x74, 0x6d, 0x6e, 0x4b, + 0x45, 0x6e, 0x78, 0x68, 0x33, 0x4a, 0x4d, 0x41, 0x41, 0x41, 0x6d, 0x41, 0x72, 0x38, 0x44, 0x64, 0x6b, 0x34, + 0x64, 0x52, 0x4a, 0x4b, 0x6b, 0x48, 0x44, 0x77, 0x49, 0x37, 0x41, 0x47, 0x73, 0x54, 0x52, 0x31, 0x6b, 0x55, + 0x42, 0x6b, 0x6d, 0x41, 0x42, 0x44, 0x2f, 0x51, 0x55, 0x35, 0x4e, 0x48, 0x55, 0x4b, 0x53, 0x70, 0x4a, 0x79, + 0x63, 0x5c, 0x0a, + 0x09, 0x52, 0x6f, 0x6d, 0x4b, 0x50, 0x35, 0x53, 0x6e, 0x41, 0x51, 0x43, 0x34, 0x48, 0x72, 0x67, 0x69, 0x64, + 0x51, 0x68, 0x4a, 0x6b, 0x6a, 0x4a, 0x32, 0x4e, 0x58, 0x48, 0x72, 0x65, 0x36, 0x6d, 0x55, 0x5a, 0x51, 0x6c, + 0x67, 0x30, 0x48, 0x62, 0x41, 0x41, 0x38, 0x44, 0x6b, 0x31, 0x45, 0x45, 0x6b, 0x53, 0x63, 0x72, 0x41, 0x61, + 0x6d, 0x41, 0x65, 0x73, 0x44, 0x42, 0x31, 0x6b, 0x49, 0x32, 0x56, 0x61, 0x51, 0x49, 0x41, 0x38, 0x52, 0x2f, + 0x49, 0x5c, 0x0a, + 0x09, 0x43, 0x77, 0x49, 0x6c, 0x53, 0x58, 0x58, 0x78, 0x62, 0x35, 0x53, 0x77, 0x2b, 0x45, 0x50, 0x35, 0x4a, + 0x67, 0x41, 0x51, 0x46, 0x77, 0x54, 0x2b, 0x42, 0x70, 0x38, 0x54, 0x49, 0x45, 0x6d, 0x71, 0x74, 0x6e, 0x75, + 0x42, 0x31, 0x31, 0x4b, 0x79, 0x74, 0x66, 0x39, 0x42, 0x5a, 0x5a, 0x73, 0x41, 0x51, 0x50, 0x79, 0x48, 0x4f, + 0x67, 0x6c, 0x59, 0x6c, 0x7a, 0x71, 0x49, 0x4a, 0x45, 0x6b, 0x64, 0x36, 0x69, 0x64, 0x71, 0x57, 0x53, 0x6d, + 0x4c, 0x5c, 0x0a, + 0x09, 0x50, 0x35, 0x53, 0x7a, 0x41, 0x51, 0x44, 0x34, 0x4a, 0x58, 0x42, 0x52, 0x36, 0x68, 0x43, 0x53, 0x4a, + 0x48, 0x58, 0x6f, 0x47, 0x30, 0x51, 0x74, 0x4b, 0x36, 0x30, 0x79, 0x4c, 0x67, 0x45, 0x4d, 0x6d, 0x6b, 0x46, + 0x63, 0x45, 0x4c, 0x68, 0x56, 0x36, 0x69, 0x43, 0x53, 0x4a, 0x4c, 0x58, 0x68, 0x53, 0x57, 0x4a, 0x66, 0x6d, + 0x36, 0x57, 0x70, 0x67, 0x34, 0x79, 0x6d, 0x72, 0x42, 0x4d, 0x41, 0x69, 0x50, 0x39, 0x77, 0x48, 0x30, 0x6b, + 0x64, 0x5c, 0x0a, + 0x09, 0x51, 0x70, 0x4b, 0x6b, 0x4e, 0x70, 0x31, 0x43, 0x79, 0x59, 0x73, 0x2f, 0x6c, 0x4c, 0x73, 0x42, 0x41, + 0x4c, 0x68, 0x79, 0x34, 0x43, 0x56, 0x4a, 0x55, 0x68, 0x56, 0x55, 0x70, 0x6d, 0x36, 0x56, 0x65, 0x51, 0x6c, + 0x67, 0x30, 0x42, 0x62, 0x45, 0x55, 0x77, 0x4e, 0x6e, 0x70, 0x51, 0x34, 0x69, 0x53, 0x64, 0x49, 0x6f, 0x6e, + 0x69, 0x48, 0x75, 0x2b, 0x56, 0x2b, 0x63, 0x4f, 0x6b, 0x67, 0x72, 0x79, 0x6a, 0x34, 0x42, 0x67, 0x50, 0x67, + 0x50, 0x5c, 0x0a, + 0x09, 0x65, 0x58, 0x72, 0x71, 0x45, 0x4a, 0x49, 0x6b, 0x6a, 0x65, 0x45, 0x30, 0x4b, 0x6c, 0x4c, 0x38, 0x6f, + 0x52, 0x6f, 0x54, 0x67, 0x45, 0x48, 0x58, 0x41, 0x50, 0x4e, 0x54, 0x68, 0x35, 0x41, 0x6b, 0x61, 0x52, 0x67, + 0x2f, 0x42, 0x41, 0x35, 0x50, 0x48, 0x61, 0x49, 0x64, 0x56, 0x57, 0x6f, 0x41, 0x35, 0x67, 0x44, 0x33, 0x41, + 0x5a, 0x75, 0x6e, 0x44, 0x69, 0x4a, 0x4a, 0x30, 0x68, 0x44, 0x50, 0x41, 0x4c, 0x73, 0x42, 0x69, 0x31, 0x49, + 0x48, 0x5c, 0x0a, + 0x09, 0x61, 0x55, 0x63, 0x56, 0x6c, 0x67, 0x41, 0x47, 0x4c, 0x53, 0x49, 0x32, 0x56, 0x5a, 0x41, 0x6b, 0x71, + 0x55, 0x78, 0x4f, 0x6f, 0x6d, 0x4c, 0x46, 0x48, 0x36, 0x72, 0x56, 0x41, 0x45, 0x41, 0x38, 0x4c, 0x66, 0x42, + 0x62, 0x71, 0x55, 0x4e, 0x49, 0x6b, 0x6a, 0x54, 0x67, 0x55, 0x69, 0x72, 0x36, 0x4a, 0x4e, 0x73, 0x71, 0x4c, + 0x51, 0x45, 0x4d, 0x6d, 0x67, 0x48, 0x38, 0x6c, 0x6e, 0x68, 0x79, 0x6f, 0x43, 0x52, 0x4a, 0x71, 0x66, 0x77, + 0x46, 0x5c, 0x0a, + 0x09, 0x32, 0x49, 0x4d, 0x4b, 0x33, 0x50, 0x4d, 0x2f, 0x6e, 0x4b, 0x70, 0x4e, 0x41, 0x43, 0x44, 0x2b, 0x51, + 0x33, 0x2b, 0x51, 0x32, 0x47, 0x64, 0x5a, 0x6b, 0x71, 0x51, 0x55, 0x2b, 0x6f, 0x6c, 0x61, 0x56, 0x4d, 0x6e, + 0x69, 0x44, 0x39, 0x56, 0x73, 0x41, 0x41, 0x42, 0x75, 0x41, 0x73, 0x35, 0x4c, 0x48, 0x55, 0x4b, 0x53, 0x31, + 0x46, 0x69, 0x66, 0x42, 0x32, 0x35, 0x4d, 0x48, 0x61, 0x49, 0x62, 0x56, 0x56, 0x77, 0x43, 0x47, 0x4e, 0x51, + 0x4c, 0x5c, 0x0a, + 0x09, 0x33, 0x41, 0x62, 0x73, 0x6b, 0x7a, 0x71, 0x49, 0x4a, 0x4b, 0x6c, 0x52, 0x37, 0x67, 0x51, 0x4f, 0x42, + 0x4a, 0x35, 0x50, 0x48, 0x61, 0x51, 0x62, 0x56, 0x57, 0x34, 0x41, 0x41, 0x4f, 0x59, 0x43, 0x64, 0x77, 0x47, + 0x62, 0x70, 0x51, 0x34, 0x69, 0x53, 0x57, 0x71, 0x45, 0x46, 0x63, 0x44, 0x65, 0x77, 0x45, 0x4f, 0x70, 0x67, + 0x33, 0x53, 0x72, 0x71, 0x6b, 0x73, 0x41, 0x67, 0x78, 0x34, 0x43, 0x54, 0x6b, 0x34, 0x64, 0x51, 0x70, 0x4c, + 0x55, 0x5c, 0x0a, + 0x09, 0x47, 0x43, 0x64, 0x54, 0x67, 0x2b, 0x49, 0x50, 0x31, 0x57, 0x38, 0x41, 0x41, 0x43, 0x34, 0x44, 0x4c, + 0x6b, 0x6b, 0x64, 0x51, 0x70, 0x4a, 0x55, 0x65, 0x39, 0x38, 0x69, 0x61, 0x6b, 0x34, 0x74, 0x56, 0x48, 0x30, + 0x4a, 0x59, 0x4e, 0x42, 0x55, 0x34, 0x41, 0x37, 0x69, 0x49, 0x51, 0x79, 0x53, 0x4a, 0x47, 0x58, 0x74, 0x51, + 0x57, 0x42, 0x66, 0x59, 0x47, 0x58, 0x71, 0x49, 0x46, 0x6d, 0x70, 0x77, 0x77, 0x51, 0x41, 0x34, 0x6e, 0x2b, + 0x51, 0x5c, 0x0a, + 0x09, 0x6f, 0x34, 0x42, 0x56, 0x71, 0x59, 0x4e, 0x49, 0x6b, 0x6d, 0x70, 0x6e, 0x46, 0x58, 0x41, 0x6b, 0x4e, + 0x53, 0x72, 0x2b, 0x55, 0x4a, 0x38, 0x47, 0x41, 0x4f, 0x42, 0x2b, 0x34, 0x4d, 0x54, 0x55, 0x49, 0x53, 0x52, + 0x4a, 0x74, 0x66, 0x4d, 0x68, 0x6f, 0x73, 0x62, 0x55, 0x53, 0x70, 0x30, 0x61, 0x41, 0x49, 0x44, 0x4c, 0x67, + 0x61, 0x2b, 0x6d, 0x44, 0x69, 0x46, 0x4a, 0x71, 0x6f, 0x30, 0x4c, 0x71, 0x64, 0x47, 0x36, 0x2f, 0x31, 0x42, + 0x31, 0x5c, 0x0a, + 0x09, 0x75, 0x51, 0x5a, 0x67, 0x4b, 0x50, 0x63, 0x48, 0x6b, 0x43, 0x52, 0x6c, 0x6f, 0x52, 0x62, 0x33, 0x2b, + 0x34, 0x2b, 0x6b, 0x6a, 0x67, 0x30, 0x41, 0x78, 0x48, 0x4d, 0x43, 0x37, 0x67, 0x52, 0x6d, 0x70, 0x77, 0x34, + 0x69, 0x53, 0x61, 0x71, 0x6b, 0x4a, 0x63, 0x51, 0x48, 0x79, 0x59, 0x57, 0x70, 0x67, 0x2b, 0x53, 0x6c, 0x62, + 0x6b, 0x73, 0x41, 0x67, 0x78, 0x59, 0x43, 0x52, 0x77, 0x4e, 0x72, 0x55, 0x77, 0x65, 0x52, 0x4a, 0x46, 0x58, + 0x4f, 0x5c, 0x0a, + 0x09, 0x57, 0x75, 0x44, 0x64, 0x31, 0x4c, 0x6a, 0x34, 0x51, 0x33, 0x30, 0x62, 0x41, 0x49, 0x42, 0x62, 0x67, + 0x49, 0x2b, 0x6e, 0x44, 0x69, 0x46, 0x4a, 0x71, 0x70, 0x77, 0x7a, 0x67, 0x4a, 0x74, 0x54, 0x68, 0x38, 0x68, + 0x62, 0x58, 0x5a, 0x63, 0x41, 0x68, 0x76, 0x70, 0x33, 0x34, 0x50, 0x6a, 0x55, 0x49, 0x53, 0x52, 0x4a, 0x6c, + 0x58, 0x41, 0x78, 0x63, 0x45, 0x4c, 0x71, 0x45, 0x45, 0x56, 0x6f, 0x51, 0x67, 0x50, 0x51, 0x43, 0x39, 0x77, + 0x4b, 0x5c, 0x0a, + 0x09, 0x37, 0x4a, 0x38, 0x36, 0x69, 0x43, 0x53, 0x70, 0x31, 0x47, 0x34, 0x48, 0x33, 0x6b, 0x52, 0x4e, 0x4c, + 0x2f, 0x72, 0x62, 0x57, 0x42, 0x4d, 0x61, 0x41, 0x49, 0x41, 0x35, 0x78, 0x45, 0x36, 0x42, 0x32, 0x36, 0x51, + 0x4f, 0x49, 0x6b, 0x6b, 0x71, 0x70, 0x55, 0x65, 0x4a, 0x44, 0x34, 0x71, 0x50, 0x70, 0x77, 0x35, 0x53, 0x6c, + 0x44, 0x70, 0x66, 0x41, 0x7a, 0x44, 0x55, 0x49, 0x75, 0x44, 0x76, 0x71, 0x4e, 0x6b, 0x75, 0x54, 0x70, 0x4b, + 0x6b, 0x5c, 0x0a, + 0x09, 0x54, 0x4b, 0x77, 0x69, 0x61, 0x6b, 0x52, 0x6a, 0x69, 0x6a, 0x38, 0x30, 0x70, 0x77, 0x45, 0x41, 0x75, + 0x42, 0x63, 0x34, 0x46, 0x75, 0x68, 0x4c, 0x48, 0x55, 0x53, 0x53, 0x56, 0x42, 0x70, 0x39, 0x77, 0x44, 0x46, + 0x45, 0x6a, 0x57, 0x69, 0x55, 0x4a, 0x6a, 0x55, 0x41, 0x41, 0x4e, 0x63, 0x41, 0x2f, 0x7a, 0x4e, 0x31, 0x43, + 0x45, 0x6c, 0x53, 0x61, 0x66, 0x77, 0x54, 0x55, 0x52, 0x73, 0x61, 0x70, 0x79, 0x6e, 0x58, 0x41, 0x47, 0x7a, + 0x73, 0x5c, 0x0a, + 0x09, 0x71, 0x38, 0x51, 0x7a, 0x6e, 0x53, 0x56, 0x4a, 0x7a, 0x58, 0x55, 0x68, 0x38, 0x4f, 0x48, 0x55, 0x49, + 0x56, 0x4a, 0x70, 0x61, 0x67, 0x4d, 0x77, 0x48, 0x72, 0x67, 0x61, 0x4f, 0x44, 0x78, 0x31, 0x45, 0x45, 0x6c, + 0x53, 0x45, 0x74, 0x63, 0x41, 0x52, 0x39, 0x44, 0x67, 0x5a, 0x65, 0x47, 0x6d, 0x4e, 0x67, 0x41, 0x41, 0x6b, + 0x34, 0x45, 0x62, 0x38, 0x66, 0x5a, 0x41, 0x53, 0x57, 0x71, 0x61, 0x32, 0x34, 0x47, 0x44, 0x67, 0x64, 0x57, + 0x70, 0x5c, 0x0a, + 0x09, 0x67, 0x36, 0x54, 0x55, 0x35, 0x41, 0x59, 0x41, 0x34, 0x6c, 0x6b, 0x42, 0x76, 0x77, 0x54, 0x6d, 0x70, + 0x67, 0x34, 0x69, 0x53, 0x53, 0x72, 0x45, 0x51, 0x38, 0x41, 0x42, 0x78, 0x46, 0x37, 0x2f, 0x6a, 0x64, 0x61, + 0x30, 0x69, 0x77, 0x41, 0x33, 0x74, 0x67, 0x52, 0x34, 0x47, 0x2f, 0x34, 0x66, 0x51, 0x5a, 0x4b, 0x61, 0x77, + 0x48, 0x50, 0x2b, 0x45, 0x45, 0x31, 0x76, 0x41, 0x43, 0x43, 0x36, 0x77, 0x58, 0x63, 0x41, 0x79, 0x31, 0x49, + 0x48, 0x5c, 0x0a, + 0x09, 0x6b, 0x53, 0x54, 0x6c, 0x5a, 0x68, 0x6b, 0x77, 0x6e, 0x7a, 0x6a, 0x6e, 0x43, 0x78, 0x75, 0x41, 0x51, + 0x58, 0x63, 0x51, 0x46, 0x34, 0x4d, 0x38, 0x6c, 0x7a, 0x71, 0x49, 0x4a, 0x43, 0x6c, 0x7a, 0x66, 0x79, 0x58, + 0x4f, 0x38, 0x62, 0x65, 0x6e, 0x44, 0x6c, 0x49, 0x6d, 0x4e, 0x67, 0x44, 0x72, 0x33, 0x51, 0x69, 0x38, 0x68, + 0x77, 0x5a, 0x66, 0x45, 0x53, 0x70, 0x4a, 0x4e, 0x64, 0x51, 0x48, 0x2f, 0x44, 0x31, 0x78, 0x6a, 0x74, 0x63, + 0x51, 0x5c, 0x0a, + 0x09, 0x4e, 0x67, 0x41, 0x62, 0x75, 0x67, 0x62, 0x34, 0x41, 0x4e, 0x44, 0x6f, 0x4b, 0x79, 0x4d, 0x6c, 0x71, + 0x53, 0x62, 0x36, 0x69, 0x58, 0x4e, 0x36, 0x49, 0x7a, 0x66, 0x36, 0x47, 0x59, 0x73, 0x4e, 0x77, 0x4b, 0x59, + 0x75, 0x41, 0x30, 0x35, 0x4e, 0x48, 0x55, 0x4b, 0x53, 0x31, 0x4c, 0x56, 0x54, 0x69, 0x58, 0x4f, 0x36, 0x68, + 0x6d, 0x45, 0x44, 0x4d, 0x4c, 0x77, 0x76, 0x41, 0x32, 0x65, 0x6d, 0x44, 0x69, 0x46, 0x4a, 0x36, 0x74, 0x69, + 0x5a, 0x5c, 0x0a, + 0x09, 0x78, 0x4c, 0x6c, 0x63, 0x49, 0x37, 0x41, 0x42, 0x47, 0x4e, 0x6e, 0x6e, 0x67, 0x45, 0x2b, 0x6b, 0x44, + 0x69, 0x46, 0x4a, 0x61, 0x74, 0x75, 0x2f, 0x45, 0x4f, 0x64, 0x77, 0x6a, 0x63, 0x49, 0x47, 0x59, 0x48, 0x54, + 0x6e, 0x41, 0x47, 0x65, 0x6e, 0x44, 0x69, 0x46, 0x4a, 0x61, 0x74, 0x6e, 0x5a, 0x77, 0x4b, 0x64, 0x54, 0x68, + 0x36, 0x69, 0x43, 0x70, 0x75, 0x38, 0x45, 0x32, 0x4b, 0x70, 0x50, 0x41, 0x32, 0x65, 0x6c, 0x44, 0x69, 0x46, + 0x4a, 0x5c, 0x0a, + 0x09, 0x47, 0x74, 0x56, 0x6e, 0x38, 0x46, 0x7a, 0x64, 0x4d, 0x69, 0x63, 0x41, 0x72, 0x66, 0x6b, 0x45, 0x38, + 0x58, 0x38, 0x73, 0x53, 0x56, 0x49, 0x35, 0x57, 0x66, 0x7a, 0x62, 0x5a, 0x41, 0x50, 0x51, 0x75, 0x72, 0x4e, + 0x77, 0x4f, 0x55, 0x43, 0x53, 0x79, 0x75, 0x68, 0x54, 0x57, 0x50, 0x7a, 0x62, 0x35, 0x68, 0x4a, 0x41, 0x2b, + 0x2f, 0x36, 0x5a, 0x75, 0x44, 0x5a, 0x41, 0x6b, 0x70, 0x54, 0x65, 0x4a, 0x2f, 0x43, 0x63, 0x33, 0x42, 0x45, + 0x62, 0x5c, 0x0a, + 0x09, 0x67, 0x4d, 0x36, 0x63, 0x43, 0x58, 0x77, 0x32, 0x64, 0x51, 0x68, 0x4a, 0x61, 0x72, 0x68, 0x2f, 0x42, + 0x4d, 0x35, 0x4e, 0x48, 0x61, 0x4b, 0x71, 0x62, 0x41, 0x41, 0x36, 0x64, 0x77, 0x70, 0x77, 0x41, 0x54, 0x41, + 0x75, 0x64, 0x52, 0x42, 0x4a, 0x61, 0x70, 0x68, 0x2b, 0x59, 0x70, 0x4d, 0x66, 0x37, 0x2f, 0x50, 0x76, 0x67, + 0x67, 0x31, 0x41, 0x64, 0x34, 0x34, 0x44, 0x4c, 0x67, 0x59, 0x6d, 0x70, 0x41, 0x34, 0x69, 0x53, 0x51, 0x33, + 0x78, 0x5c, 0x0a, + 0x09, 0x41, 0x6e, 0x41, 0x38, 0x63, 0x47, 0x6e, 0x71, 0x49, 0x46, 0x56, 0x6e, 0x41, 0x39, 0x43, 0x39, 0x77, + 0x34, 0x48, 0x76, 0x41, 0x43, 0x39, 0x4a, 0x48, 0x55, 0x53, 0x53, 0x61, 0x75, 0x36, 0x76, 0x78, 0x49, 0x4e, + 0x39, 0x33, 0x4e, 0x73, 0x2f, 0x41, 0x7a, 0x59, 0x41, 0x32, 0x58, 0x67, 0x7a, 0x38, 0x58, 0x2f, 0x49, 0x7a, + 0x52, 0x4c, 0x6e, 0x6b, 0x4b, 0x53, 0x36, 0x57, 0x6b, 0x46, 0x38, 0x34, 0x4c, 0x6f, 0x35, 0x63, 0x59, 0x37, + 0x61, 0x5c, 0x0a, + 0x09, 0x73, 0x41, 0x48, 0x49, 0x7a, 0x6a, 0x37, 0x41, 0x6a, 0x34, 0x45, 0x74, 0x55, 0x67, 0x65, 0x52, 0x70, + 0x4a, 0x70, 0x5a, 0x41, 0x76, 0x77, 0x64, 0x63, 0x47, 0x66, 0x71, 0x49, 0x48, 0x56, 0x69, 0x41, 0x35, 0x43, + 0x74, 0x75, 0x63, 0x42, 0x50, 0x42, 0x6e, 0x36, 0x55, 0x4a, 0x48, 0x58, 0x76, 0x49, 0x65, 0x42, 0x74, 0x41, + 0x7a, 0x38, 0x71, 0x51, 0x32, 0x34, 0x45, 0x6c, 0x4b, 0x32, 0x48, 0x67, 0x41, 0x4f, 0x41, 0x4f, 0x31, 0x49, + 0x48, 0x5c, 0x0a, + 0x09, 0x6b, 0x61, 0x51, 0x61, 0x75, 0x41, 0x4d, 0x34, 0x45, 0x49, 0x74, 0x2f, 0x4c, 0x6d, 0x77, 0x41, 0x73, + 0x72, 0x63, 0x45, 0x4f, 0x42, 0x6a, 0x34, 0x55, 0x65, 0x6f, 0x67, 0x6b, 0x6c, 0x52, 0x68, 0x50, 0x38, 0x4c, + 0x4d, 0x37, 0x4a, 0x45, 0x41, 0x41, 0x41, 0x61, 0x70, 0x53, 0x55, 0x52, 0x42, 0x56, 0x43, 0x62, 0x4f, 0x70, + 0x59, 0x74, 0x54, 0x42, 0x36, 0x6b, 0x72, 0x47, 0x34, 0x42, 0x38, 0x72, 0x41, 0x4c, 0x65, 0x42, 0x56, 0x79, + 0x55, 0x5c, 0x0a, + 0x09, 0x4f, 0x6f, 0x67, 0x6b, 0x56, 0x64, 0x42, 0x46, 0x77, 0x44, 0x75, 0x4a, 0x63, 0x36, 0x6c, 0x79, 0x59, + 0x67, 0x4f, 0x51, 0x6e, 0x7a, 0x37, 0x67, 0x52, 0x4f, 0x43, 0x4d, 0x67, 0x5a, 0x39, 0x4c, 0x6b, 0x6b, 0x62, + 0x58, 0x52, 0x2b, 0x79, 0x30, 0x65, 0x69, 0x4b, 0x65, 0x4e, 0x33, 0x50, 0x6e, 0x52, 0x59, 0x44, 0x46, 0x6d, + 0x41, 0x39, 0x63, 0x44, 0x6b, 0x78, 0x4e, 0x48, 0x55, 0x53, 0x53, 0x53, 0x6d, 0x6f, 0x6c, 0x63, 0x41, 0x7a, + 0x77, 0x5c, 0x0a, + 0x09, 0x77, 0x39, 0x52, 0x42, 0x6d, 0x73, 0x49, 0x47, 0x6f, 0x44, 0x68, 0x37, 0x45, 0x76, 0x2f, 0x48, 0x33, + 0x69, 0x5a, 0x31, 0x45, 0x45, 0x6b, 0x71, 0x6d, 0x55, 0x65, 0x4a, 0x44, 0x30, 0x72, 0x33, 0x70, 0x41, 0x37, + 0x53, 0x4a, 0x43, 0x34, 0x42, 0x46, 0x4f, 0x63, 0x65, 0x59, 0x46, 0x2f, 0x67, 0x39, 0x74, 0x52, 0x42, 0x4a, + 0x4b, 0x6c, 0x45, 0x62, 0x67, 0x66, 0x32, 0x77, 0x2b, 0x4a, 0x66, 0x4f, 0x42, 0x75, 0x41, 0x59, 0x6a, 0x31, + 0x42, 0x5c, 0x0a, + 0x09, 0x37, 0x42, 0x70, 0x34, 0x63, 0x65, 0x49, 0x63, 0x6b, 0x6c, 0x51, 0x47, 0x33, 0x79, 0x54, 0x4f, 0x69, + 0x59, 0x76, 0x53, 0x78, 0x6d, 0x67, 0x6d, 0x47, 0x34, 0x44, 0x69, 0x2f, 0x52, 0x55, 0x34, 0x67, 0x58, 0x69, + 0x53, 0x31, 0x51, 0x75, 0x4a, 0x73, 0x30, 0x68, 0x53, 0x43, 0x69, 0x38, 0x51, 0x35, 0x38, 0x44, 0x6a, 0x69, + 0x58, 0x4f, 0x69, 0x45, 0x76, 0x41, 0x61, 0x67, 0x4c, 0x54, 0x65, 0x44, 0x48, 0x77, 0x58, 0x6d, 0x4a, 0x30, + 0x34, 0x5c, 0x0a, + 0x09, 0x68, 0x79, 0x51, 0x56, 0x5a, 0x51, 0x6e, 0x78, 0x51, 0x4a, 0x2b, 0x62, 0x55, 0x67, 0x64, 0x70, 0x4f, + 0x68, 0x75, 0x41, 0x39, 0x4c, 0x59, 0x48, 0x72, 0x69, 0x53, 0x65, 0x4a, 0x53, 0x42, 0x4a, 0x64, 0x58, 0x59, + 0x6e, 0x63, 0x42, 0x54, 0x77, 0x53, 0x4f, 0x6f, 0x67, 0x63, 0x67, 0x6d, 0x67, 0x44, 0x42, 0x34, 0x42, 0x33, + 0x67, 0x42, 0x38, 0x4c, 0x58, 0x55, 0x51, 0x53, 0x63, 0x72, 0x52, 0x31, 0x34, 0x6c, 0x7a, 0x6e, 0x63, 0x57, + 0x2f, 0x5c, 0x0a, + 0x09, 0x4a, 0x4a, 0x77, 0x41, 0x6c, 0x4d, 0x75, 0x78, 0x52, 0x43, 0x50, 0x67, 0x66, 0x67, 0x47, 0x53, 0x36, + 0x6d, 0x49, 0x6c, 0x63, 0x42, 0x4a, 0x77, 0x57, 0x65, 0x6f, 0x67, 0x32, 0x70, 0x41, 0x4e, 0x51, 0x50, 0x6e, + 0x73, 0x53, 0x69, 0x77, 0x4a, 0x37, 0x4a, 0x77, 0x36, 0x69, 0x43, 0x52, 0x31, 0x36, 0x55, 0x48, 0x67, 0x61, + 0x4f, 0x43, 0x2b, 0x31, 0x45, 0x47, 0x30, 0x4b, 0x5a, 0x63, 0x41, 0x79, 0x6d, 0x63, 0x42, 0x73, 0x56, 0x2f, + 0x41, 0x5c, 0x0a, + 0x09, 0x4a, 0x61, 0x6d, 0x44, 0x53, 0x46, 0x49, 0x58, 0x4c, 0x69, 0x48, 0x4f, 0x5a, 0x52, 0x62, 0x2f, 0x6b, + 0x72, 0x49, 0x42, 0x4b, 0x4b, 0x65, 0x56, 0x77, 0x41, 0x65, 0x41, 0x39, 0x77, 0x48, 0x4c, 0x45, 0x32, 0x65, + 0x52, 0x70, 0x48, 0x61, 0x73, 0x41, 0x4e, 0x35, 0x50, 0x6e, 0x4d, 0x4e, 0x57, 0x4a, 0x73, 0x36, 0x69, 0x55, + 0x62, 0x67, 0x45, 0x55, 0x48, 0x36, 0x76, 0x4a, 0x4a, 0x34, 0x6a, 0x34, 0x46, 0x30, 0x43, 0x6b, 0x73, 0x72, + 0x75, 0x5c, 0x0a, + 0x09, 0x54, 0x6d, 0x49, 0x2f, 0x2f, 0x7a, 0x2b, 0x6d, 0x44, 0x71, 0x4b, 0x78, 0x4f, 0x51, 0x45, 0x6f, 0x76, + 0x7a, 0x38, 0x43, 0x42, 0x77, 0x4c, 0x6e, 0x41, 0x58, 0x5a, 0x72, 0x6b, 0x73, 0x71, 0x6f, 0x6e, 0x7a, 0x68, + 0x48, 0x48, 0x59, 0x6a, 0x46, 0x76, 0x7a, 0x4b, 0x63, 0x41, 0x46, 0x54, 0x4c, 0x77, 0x63, 0x54, 0x57, 0x6d, + 0x64, 0x73, 0x6d, 0x7a, 0x69, 0x46, 0x4a, 0x67, 0x2f, 0x35, 0x43, 0x37, 0x4f, 0x6a, 0x33, 0x73, 0x39, 0x52, + 0x42, 0x5c, 0x0a, + 0x09, 0x31, 0x42, 0x34, 0x6e, 0x41, 0x4e, 0x56, 0x79, 0x49, 0x37, 0x41, 0x37, 0x63, 0x47, 0x6e, 0x71, 0x49, + 0x4a, 0x4a, 0x45, 0x33, 0x4e, 0x71, 0x33, 0x42, 0x78, 0x62, 0x2f, 0x53, 0x6e, 0x49, 0x43, 0x55, 0x46, 0x31, + 0x48, 0x41, 0x78, 0x63, 0x43, 0x4c, 0x30, 0x73, 0x64, 0x52, 0x46, 0x4c, 0x6a, 0x50, 0x45, 0x50, 0x63, 0x32, + 0x33, 0x39, 0x46, 0x36, 0x69, 0x44, 0x71, 0x6e, 0x41, 0x31, 0x41, 0x74, 0x63, 0x30, 0x68, 0x64, 0x74, 0x65, + 0x61, 0x5c, 0x0a, + 0x09, 0x6e, 0x7a, 0x71, 0x49, 0x70, 0x4d, 0x62, 0x34, 0x49, 0x66, 0x41, 0x68, 0x66, 0x49, 0x4a, 0x66, 0x35, + 0x62, 0x6b, 0x45, 0x55, 0x47, 0x32, 0x4c, 0x67, 0x4d, 0x4f, 0x4a, 0x48, 0x51, 0x53, 0x66, 0x54, 0x70, 0x78, + 0x46, 0x55, 0x72, 0x30, 0x39, 0x54, 0x5a, 0x78, 0x72, 0x44, 0x73, 0x66, 0x69, 0x58, 0x77, 0x74, 0x4f, 0x41, + 0x4f, 0x70, 0x6a, 0x43, 0x2b, 0x44, 0x4c, 0x78, 0x4e, 0x4b, 0x41, 0x4a, 0x47, 0x58, 0x70, 0x53, 0x75, 0x41, + 0x55, 0x5c, 0x0a, + 0x09, 0x34, 0x4d, 0x6e, 0x55, 0x51, 0x5a, 0x51, 0x64, 0x4a, 0x77, 0x44, 0x31, 0x73, 0x52, 0x68, 0x34, 0x4e, + 0x2f, 0x47, 0x6b, 0x72, 0x53, 0x63, 0x53, 0x5a, 0x35, 0x46, 0x55, 0x44, 0x30, 0x38, 0x51, 0x35, 0x35, 0x53, + 0x6a, 0x73, 0x66, 0x6a, 0x58, 0x6a, 0x67, 0x31, 0x41, 0x2f, 0x56, 0x77, 0x46, 0x7a, 0x43, 0x4d, 0x65, 0x4b, + 0x72, 0x51, 0x75, 0x63, 0x52, 0x5a, 0x4a, 0x31, 0x62, 0x53, 0x4f, 0x75, 0x4c, 0x35, 0x6f, 0x48, 0x6e, 0x46, + 0x4f, 0x5c, 0x0a, + 0x09, 0x55, 0x51, 0x32, 0x35, 0x42, 0x46, 0x42, 0x76, 0x72, 0x79, 0x66, 0x2b, 0x45, 0x65, 0x2b, 0x65, 0x4f, + 0x6f, 0x69, 0x6b, 0x79, 0x72, 0x67, 0x58, 0x4f, 0x42, 0x6d, 0x34, 0x4c, 0x58, 0x55, 0x51, 0x35, 0x63, 0x73, + 0x4a, 0x51, 0x4c, 0x33, 0x39, 0x4a, 0x37, 0x41, 0x33, 0x38, 0x45, 0x2f, 0x41, 0x36, 0x73, 0x52, 0x5a, 0x4a, + 0x4a, 0x58, 0x62, 0x63, 0x38, 0x53, 0x35, 0x34, 0x72, 0x56, 0x59, 0x2f, 0x42, 0x76, 0x42, 0x43, 0x55, 0x42, + 0x7a, 0x5c, 0x0a, + 0x09, 0x62, 0x41, 0x65, 0x63, 0x44, 0x78, 0x79, 0x52, 0x4f, 0x6f, 0x69, 0x6b, 0x30, 0x76, 0x6b, 0x65, 0x38, + 0x46, 0x46, 0x67, 0x59, 0x65, 0x6f, 0x67, 0x4b, 0x6f, 0x34, 0x4e, 0x51, 0x50, 0x50, 0x38, 0x4c, 0x66, 0x42, + 0x46, 0x59, 0x4a, 0x66, 0x55, 0x51, 0x53, 0x51, 0x6c, 0x64, 0x7a, 0x39, 0x52, 0x2b, 0x4b, 0x39, 0x50, 0x48, + 0x55, 0x54, 0x46, 0x63, 0x77, 0x6d, 0x67, 0x65, 0x57, 0x34, 0x41, 0x58, 0x67, 0x4f, 0x63, 0x41, 0x53, 0x78, + 0x4c, 0x5c, 0x0a, + 0x09, 0x6e, 0x45, 0x56, 0x53, 0x47, 0x73, 0x75, 0x4a, 0x63, 0x38, 0x42, 0x65, 0x57, 0x50, 0x77, 0x62, 0x79, + 0x77, 0x6c, 0x41, 0x73, 0x38, 0x30, 0x42, 0x7a, 0x69, 0x59, 0x65, 0x35, 0x44, 0x45, 0x68, 0x63, 0x52, 0x5a, + 0x4a, 0x2b, 0x58, 0x73, 0x42, 0x75, 0x41, 0x54, 0x34, 0x46, 0x39, 0x7a, 0x4d, 0x70, 0x2f, 0x46, 0x73, 0x41, + 0x41, 0x53, 0x78, 0x48, 0x48, 0x41, 0x65, 0x63, 0x46, 0x6a, 0x71, 0x49, 0x4a, 0x4a, 0x79, 0x63, 0x79, 0x33, + 0x77, 0x5c, 0x0a, + 0x09, 0x63, 0x57, 0x4c, 0x73, 0x4c, 0x37, 0x6b, 0x45, 0x49, 0x43, 0x42, 0x4f, 0x43, 0x47, 0x38, 0x62, 0x65, + 0x4e, 0x32, 0x58, 0x4f, 0x49, 0x75, 0x6b, 0x62, 0x41, 0x33, 0x39, 0x39, 0x32, 0x33, 0x78, 0x31, 0x34, 0x74, + 0x73, 0x41, 0x44, 0x54, 0x55, 0x74, 0x63, 0x54, 0x31, 0x41, 0x63, 0x66, 0x6a, 0x31, 0x63, 0x42, 0x53, 0x31, + 0x53, 0x30, 0x6b, 0x2f, 0x69, 0x32, 0x2f, 0x68, 0x76, 0x69, 0x33, 0x4c, 0x57, 0x33, 0x41, 0x4a, 0x51, 0x43, + 0x4e, 0x5c, 0x0a, + 0x09, 0x70, 0x4a, 0x64, 0x34, 0x33, 0x4f, 0x63, 0x6e, 0x69, 0x4f, 0x63, 0x4d, 0x53, 0x4b, 0x71, 0x47, 0x4a, + 0x63, 0x43, 0x6e, 0x69, 0x63, 0x65, 0x46, 0x50, 0x35, 0x38, 0x34, 0x69, 0x30, 0x72, 0x4d, 0x42, 0x6b, 0x42, + 0x6a, 0x6d, 0x51, 0x71, 0x63, 0x54, 0x71, 0x77, 0x64, 0x54, 0x6b, 0x2b, 0x63, 0x52, 0x64, 0x4c, 0x49, 0x6c, + 0x68, 0x48, 0x58, 0x38, 0x70, 0x77, 0x50, 0x72, 0x45, 0x79, 0x63, 0x52, 0x52, 0x56, 0x67, 0x41, 0x36, 0x42, + 0x57, 0x5c, 0x0a, + 0x09, 0x62, 0x55, 0x37, 0x63, 0x4c, 0x33, 0x77, 0x61, 0x4d, 0x43, 0x31, 0x78, 0x46, 0x6b, 0x6e, 0x72, 0x72, + 0x51, 0x41, 0x75, 0x41, 0x44, 0x34, 0x50, 0x50, 0x4a, 0x4d, 0x34, 0x69, 0x79, 0x72, 0x45, 0x42, 0x6b, 0x44, + 0x74, 0x6d, 0x73, 0x6e, 0x36, 0x52, 0x73, 0x43, 0x4a, 0x67, 0x4a, 0x54, 0x4f, 0x63, 0x75, 0x49, 0x52, 0x34, + 0x4a, 0x38, 0x48, 0x6e, 0x6b, 0x36, 0x63, 0x52, 0x52, 0x56, 0x6b, 0x41, 0x36, 0x42, 0x4f, 0x7a, 0x53, 0x43, + 0x61, 0x5c, 0x0a, + 0x09, 0x67, 0x4e, 0x4f, 0x49, 0x70, 0x6b, 0x42, 0x53, 0x4d, 0x5a, 0x34, 0x46, 0x76, 0x6b, 0x54, 0x73, 0x36, + 0x4f, 0x6b, 0x6e, 0x66, 0x6e, 0x58, 0x4d, 0x42, 0x6b, 0x44, 0x64, 0x32, 0x67, 0x77, 0x34, 0x6b, 0x62, 0x68, + 0x4f, 0x59, 0x4f, 0x76, 0x45, 0x57, 0x61, 0x51, 0x36, 0x65, 0x34, 0x78, 0x59, 0x33, 0x2f, 0x38, 0x47, 0x4d, + 0x66, 0x61, 0x58, 0x75, 0x6d, 0x49, 0x44, 0x6f, 0x4b, 0x7a, 0x30, 0x41, 0x73, 0x63, 0x42, 0x5a, 0x77, 0x49, + 0x37, 0x5c, 0x0a, + 0x09, 0x4a, 0x38, 0x34, 0x69, 0x31, 0x63, 0x6d, 0x44, 0x77, 0x4c, 0x6e, 0x41, 0x70, 0x58, 0x68, 0x56, 0x76, + 0x7a, 0x4a, 0x6b, 0x41, 0x36, 0x43, 0x73, 0x39, 0x51, 0x44, 0x76, 0x4a, 0x4b, 0x34, 0x54, 0x65, 0x46, 0x50, + 0x69, 0x4c, 0x46, 0x4b, 0x56, 0x33, 0x51, 0x70, 0x38, 0x41, 0x66, 0x67, 0x42, 0x73, 0x43, 0x35, 0x78, 0x46, + 0x74, 0x57, 0x51, 0x44, 0x59, 0x44, 0x79, 0x74, 0x44, 0x64, 0x78, 0x6a, 0x63, 0x42, 0x37, 0x69, 0x41, 0x6d, + 0x42, 0x5c, 0x0a, + 0x09, 0x70, 0x4e, 0x45, 0x39, 0x44, 0x33, 0x79, 0x48, 0x4b, 0x50, 0x78, 0x33, 0x4a, 0x63, 0x36, 0x69, 0x6d, + 0x72, 0x4d, 0x42, 0x55, 0x42, 0x47, 0x32, 0x41, 0x6a, 0x35, 0x4d, 0x58, 0x43, 0x75, 0x77, 0x5a, 0x65, 0x49, + 0x73, 0x55, 0x68, 0x6b, 0x39, 0x53, 0x61, 0x7a, 0x74, 0x66, 0x78, 0x56, 0x34, 0x49, 0x6e, 0x45, 0x57, 0x4e, + 0x59, 0x51, 0x4e, 0x67, 0x49, 0x6f, 0x30, 0x43, 0x54, 0x69, 0x43, 0x32, 0x47, 0x48, 0x51, 0x35, 0x51, 0x45, + 0x4a, 0x5c, 0x0a, + 0x09, 0x66, 0x6b, 0x37, 0x73, 0x32, 0x48, 0x63, 0x31, 0x73, 0x43, 0x5a, 0x78, 0x46, 0x6a, 0x57, 0x4d, 0x44, + 0x59, 0x42, 0x53, 0x32, 0x5a, 0x56, 0x6f, 0x42, 0x4e, 0x36, 0x48, 0x2b, 0x77, 0x6d, 0x6f, 0x57, 0x5a, 0x59, + 0x42, 0x33, 0x77, 0x4b, 0x2b, 0x42, 0x69, 0x78, 0x49, 0x6e, 0x45, 0x55, 0x4e, 0x5a, 0x67, 0x4f, 0x67, 0x31, + 0x4b, 0x59, 0x41, 0x52, 0x78, 0x4d, 0x50, 0x4c, 0x58, 0x6b, 0x6a, 0x4d, 0x43, 0x35, 0x74, 0x48, 0x43, 0x6b, + 0x58, 0x5c, 0x0a, + 0x09, 0x2f, 0x63, 0x53, 0x6e, 0x2f, 0x59, 0x75, 0x42, 0x4b, 0x33, 0x47, 0x72, 0x58, 0x70, 0x57, 0x41, 0x44, + 0x59, 0x44, 0x4b, 0x35, 0x46, 0x58, 0x41, 0x43, 0x63, 0x52, 0x55, 0x34, 0x4f, 0x57, 0x4a, 0x73, 0x30, 0x68, + 0x5a, 0x65, 0x4a, 0x7a, 0x34, 0x74, 0x50, 0x39, 0x4e, 0x34, 0x6e, 0x59, 0x2b, 0x71, 0x54, 0x52, 0x73, 0x41, + 0x46, 0x52, 0x47, 0x34, 0x34, 0x47, 0x33, 0x45, 0x76, 0x73, 0x4b, 0x76, 0x42, 0x4f, 0x59, 0x6e, 0x44, 0x61, + 0x4f, 0x5c, 0x0a, + 0x09, 0x31, 0x4a, 0x62, 0x56, 0x78, 0x4b, 0x31, 0x37, 0x6c, 0x77, 0x49, 0x2f, 0x42, 0x66, 0x72, 0x53, 0x78, + 0x70, 0x47, 0x47, 0x5a, 0x77, 0x4f, 0x67, 0x73, 0x70, 0x74, 0x4b, 0x4e, 0x41, 0x48, 0x76, 0x42, 0x51, 0x34, + 0x46, 0x4a, 0x71, 0x61, 0x4e, 0x49, 0x77, 0x31, 0x72, 0x4c, 0x58, 0x41, 0x39, 0x63, 0x44, 0x6c, 0x52, 0x2f, + 0x42, 0x33, 0x78, 0x71, 0x2f, 0x52, 0x73, 0x41, 0x46, 0x51, 0x6c, 0x73, 0x34, 0x42, 0x33, 0x44, 0x37, 0x7a, + 0x65, 0x5c, 0x0a, + 0x09, 0x51, 0x45, 0x77, 0x4b, 0x70, 0x46, 0x54, 0x36, 0x67, 0x46, 0x38, 0x41, 0x33, 0x78, 0x31, 0x34, 0x50, + 0x5a, 0x55, 0x32, 0x6a, 0x74, 0x51, 0x65, 0x47, 0x77, 0x42, 0x56, 0x31, 0x52, 0x62, 0x41, 0x75, 0x34, 0x41, + 0x6a, 0x67, 0x62, 0x66, 0x67, 0x5a, 0x45, 0x44, 0x46, 0x57, 0x41, 0x76, 0x63, 0x42, 0x46, 0x77, 0x46, 0x66, + 0x42, 0x39, 0x59, 0x6e, 0x44, 0x61, 0x4f, 0x31, 0x44, 0x6b, 0x62, 0x41, 0x4e, 0x58, 0x42, 0x54, 0x4f, 0x44, + 0x77, 0x5c, 0x0a, + 0x09, 0x67, 0x64, 0x65, 0x68, 0x78, 0x4c, 0x4b, 0x42, 0x6c, 0x4a, 0x57, 0x56, 0x77, 0x48, 0x58, 0x41, 0x4e, + 0x51, 0x4f, 0x76, 0x5a, 0x39, 0x50, 0x47, 0x6b, 0x62, 0x4a, 0x68, 0x41, 0x36, 0x43, 0x36, 0x36, 0x51, 0x58, + 0x65, 0x44, 0x4c, 0x77, 0x44, 0x65, 0x44, 0x75, 0x77, 0x59, 0x39, 0x49, 0x30, 0x71, 0x71, 0x6f, 0x2f, 0x41, + 0x54, 0x38, 0x61, 0x65, 0x4e, 0x32, 0x43, 0x6d, 0x2f, 0x53, 0x6f, 0x68, 0x6d, 0x77, 0x41, 0x56, 0x48, 0x65, + 0x37, 0x5c, 0x0a, + 0x09, 0x41, 0x49, 0x63, 0x42, 0x68, 0x78, 0x43, 0x37, 0x44, 0x33, 0x70, 0x48, 0x67, 0x59, 0x61, 0x7a, 0x6d, + 0x72, 0x68, 0x50, 0x2f, 0x7a, 0x72, 0x67, 0x57, 0x75, 0x44, 0x2b, 0x74, 0x48, 0x47, 0x6b, 0x2f, 0x4e, 0x6b, + 0x41, 0x71, 0x45, 0x6c, 0x65, 0x41, 0x68, 0x78, 0x41, 0x4e, 0x41, 0x4f, 0x48, 0x41, 0x6e, 0x73, 0x53, 0x54, + 0x79, 0x39, 0x55, 0x38, 0x36, 0x77, 0x44, 0x37, 0x69, 0x45, 0x4b, 0x2f, 0x76, 0x58, 0x41, 0x4c, 0x34, 0x47, + 0x2f, 0x5c, 0x0a, + 0x09, 0x4a, 0x6b, 0x30, 0x6b, 0x46, 0x63, 0x77, 0x47, 0x51, 0x45, 0x30, 0x32, 0x6b, 0x37, 0x69, 0x62, 0x34, + 0x43, 0x42, 0x69, 0x4f, 0x72, 0x41, 0x58, 0x4d, 0x43, 0x46, 0x70, 0x49, 0x75, 0x58, 0x6c, 0x42, 0x65, 0x42, + 0x75, 0x34, 0x6c, 0x50, 0x2b, 0x7a, 0x63, 0x54, 0x56, 0x2b, 0x36, 0x37, 0x6c, 0x71, 0x39, 0x46, 0x73, 0x41, + 0x4b, 0x54, 0x31, 0x4e, 0x69, 0x4d, 0x6d, 0x42, 0x47, 0x38, 0x45, 0x39, 0x67, 0x66, 0x32, 0x78, 0x65, 0x63, + 0x55, 0x5c, 0x0a, + 0x09, 0x56, 0x4e, 0x56, 0x79, 0x34, 0x41, 0x37, 0x67, 0x64, 0x71, 0x4c, 0x59, 0x33, 0x77, 0x61, 0x73, 0x53, + 0x4a, 0x70, 0x49, 0x4b, 0x68, 0x6b, 0x62, 0x41, 0x47, 0x6c, 0x6b, 0x50, 0x63, 0x41, 0x38, 0x6f, 0x68, 0x6c, + 0x34, 0x48, 0x62, 0x41, 0x66, 0x63, 0x55, 0x32, 0x42, 0x74, 0x78, 0x79, 0x57, 0x79, 0x77, 0x76, 0x45, 0x51, + 0x33, 0x58, 0x75, 0x41, 0x48, 0x34, 0x31, 0x38, 0x4f, 0x50, 0x39, 0x78, 0x4a, 0x68, 0x66, 0x30, 0x67, 0x68, + 0x73, 0x5c, 0x0a, + 0x09, 0x41, 0x4b, 0x54, 0x32, 0x76, 0x41, 0x54, 0x59, 0x6a, 0x56, 0x67, 0x75, 0x32, 0x42, 0x50, 0x59, 0x47, + 0x39, 0x67, 0x44, 0x4c, 0x79, 0x34, 0x73, 0x79, 0x6d, 0x72, 0x67, 0x58, 0x75, 0x41, 0x33, 0x78, 0x42, 0x72, + 0x2b, 0x33, 0x63, 0x42, 0x39, 0x75, 0x48, 0x34, 0x76, 0x74, 0x63, 0x30, 0x47, 0x51, 0x4f, 0x72, 0x65, 0x65, + 0x47, 0x41, 0x48, 0x59, 0x6a, 0x71, 0x77, 0x43, 0x2f, 0x47, 0x6f, 0x34, 0x33, 0x6b, 0x44, 0x4c, 0x78, 0x75, + 0x44, 0x5c, 0x0a, + 0x09, 0x7a, 0x71, 0x77, 0x47, 0x48, 0x68, 0x68, 0x34, 0x4c, 0x53, 0x41, 0x2b, 0x30, 0x64, 0x39, 0x50, 0x33, + 0x4a, 0x37, 0x6e, 0x33, 0x76, 0x70, 0x53, 0x42, 0x6d, 0x77, 0x41, 0x70, 0x50, 0x7a, 0x30, 0x41, 0x4e, 0x73, + 0x43, 0x63, 0x77, 0x64, 0x65, 0x4f, 0x77, 0x37, 0x35, 0x2b, 0x55, 0x37, 0x45, 0x6f, 0x35, 0x43, 0x62, 0x62, + 0x44, 0x58, 0x77, 0x30, 0x4d, 0x44, 0x72, 0x34, 0x59, 0x48, 0x58, 0x34, 0x4b, 0x2f, 0x2f, 0x67, 0x69, 0x4e, + 0x38, 0x5c, 0x0a, + 0x09, 0x4b, 0x56, 0x63, 0x32, 0x41, 0x46, 0x49, 0x36, 0x73, 0x34, 0x42, 0x74, 0x69, 0x43, 0x5a, 0x68, 0x75, + 0x34, 0x47, 0x66, 0x62, 0x77, 0x4e, 0x73, 0x54, 0x57, 0x78, 0x31, 0x50, 0x48, 0x76, 0x67, 0x4e, 0x53, 0x35, + 0x56, 0x77, 0x41, 0x37, 0x31, 0x41, 0x30, 0x73, 0x47, 0x58, 0x6f, 0x75, 0x42, 0x78, 0x34, 0x42, 0x48, 0x42, + 0x31, 0x34, 0x4c, 0x69, 0x65, 0x4c, 0x2b, 0x4b, 0x4f, 0x36, 0x64, 0x4c, 0x79, 0x56, 0x6c, 0x41, 0x79, 0x43, + 0x56, 0x5c, 0x0a, + 0x09, 0x32, 0x33, 0x67, 0x32, 0x62, 0x41, 0x59, 0x32, 0x42, 0x32, 0x59, 0x4d, 0x38, 0x35, 0x6f, 0x79, 0x38, + 0x4a, 0x6f, 0x4d, 0x54, 0x41, 0x4b, 0x6d, 0x45, 0x52, 0x63, 0x72, 0x62, 0x6e, 0x77, 0x58, 0x77, 0x7a, 0x51, + 0x32, 0x66, 0x59, 0x68, 0x53, 0x48, 0x33, 0x48, 0x56, 0x2f, 0x46, 0x44, 0x4c, 0x69, 0x48, 0x33, 0x76, 0x6c, + 0x78, 0x4f, 0x37, 0x34, 0x4b, 0x30, 0x47, 0x56, 0x67, 0x32, 0x38, 0x6c, 0x67, 0x37, 0x7a, 0x65, 0x6f, 0x62, + 0x31, 0x5c, 0x0a, + 0x09, 0x52, 0x58, 0x38, 0x4a, 0x63, 0x57, 0x47, 0x65, 0x70, 0x42, 0x4c, 0x37, 0x2f, 0x2b, 0x36, 0x4a, 0x76, + 0x53, 0x43, 0x72, 0x32, 0x66, 0x6e, 0x73, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x6c, 0x46, 0x54, 0x6b, 0x53, + 0x75, 0x51, 0x6d, 0x43, 0x43, 0x5c, 0x0a, + 0x09, 0x22, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x6e, 0x67, 0x20, + 0x3d, 0x0a, + 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x4e, + 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x43, 0x41, + 0x59, 0x41, 0x41, 0x41, 0x44, 0x6b, 0x74, 0x62, 0x63, 0x4b, 0x41, 0x41, 0x41, 0x48, 0x48, 0x30, 0x6c, 0x45, + 0x51, 0x56, 0x52, 0x34, 0x6e, 0x4f, 0x33, 0x64, 0x79, 0x38, 0x39, 0x63, 0x63, 0x78, 0x7a, 0x48, 0x38, 0x66, + 0x66, 0x7a, 0x5c, 0x0a, + 0x09, 0x39, 0x46, 0x36, 0x58, 0x58, 0x72, 0x52, 0x39, 0x74, 0x4b, 0x36, 0x6c, 0x4c, 0x58, 0x56, 0x70, 0x56, + 0x43, 0x51, 0x6b, 0x4c, 0x68, 0x47, 0x68, 0x49, 0x57, 0x69, 0x49, 0x52, 0x46, 0x30, 0x53, 0x47, 0x34, 0x53, + 0x39, 0x68, 0x4a, 0x55, 0x56, 0x47, 0x78, 0x61, 0x57, 0x4e, 0x68, 0x62, 0x2b, 0x41, 0x49, 0x74, 0x4b, 0x42, + 0x47, 0x46, 0x68, 0x30, 0x34, 0x55, 0x67, 0x49, 0x69, 0x68, 0x42, 0x56, 0x4a, 0x75, 0x57, 0x74, 0x6d, 0x69, + 0x72, 0x5c, 0x0a, + 0x09, 0x56, 0x38, 0x56, 0x44, 0x78, 0x2b, 0x4a, 0x33, 0x4a, 0x73, 0x39, 0x30, 0x4f, 0x76, 0x4e, 0x30, 0x66, + 0x6d, 0x66, 0x6d, 0x39, 0x46, 0x78, 0x2b, 0x37, 0x31, 0x63, 0x79, 0x65, 0x57, 0x61, 0x65, 0x7a, 0x75, 0x58, + 0x62, 0x4e, 0x74, 0x2f, 0x50, 0x37, 0x33, 0x64, 0x2b, 0x35, 0x38, 0x77, 0x35, 0x59, 0x36, 0x31, 0x57, 0x43, + 0x30, 0x6c, 0x70, 0x47, 0x69, 0x2b, 0x37, 0x41, 0x45, 0x6e, 0x6c, 0x4d, 0x51, 0x43, 0x6b, 0x68, 0x4d, 0x30, + 0x73, 0x5c, 0x0a, + 0x09, 0x75, 0x77, 0x44, 0x56, 0x79, 0x36, 0x70, 0x4c, 0x56, 0x30, 0x59, 0x39, 0x2f, 0x38, 0x63, 0x64, 0x32, + 0x77, 0x75, 0x71, 0x52, 0x4b, 0x4e, 0x67, 0x41, 0x43, 0x51, 0x71, 0x74, 0x70, 0x47, 0x37, 0x6a, 0x41, 0x45, + 0x4c, 0x67, 0x47, 0x58, 0x41, 0x63, 0x6d, 0x41, 0x43, 0x57, 0x4a, 0x49, 0x39, 0x6e, 0x67, 0x43, 0x4f, 0x41, + 0x53, 0x38, 0x42, 0x68, 0x34, 0x61, 0x72, 0x55, 0x6b, 0x55, 0x62, 0x63, 0x78, 0x47, 0x77, 0x33, 0x6f, 0x5a, + 0x73, 0x5c, 0x0a, + 0x09, 0x35, 0x48, 0x48, 0x67, 0x4c, 0x47, 0x41, 0x68, 0x6f, 0x58, 0x47, 0x58, 0x41, 0x59, 0x75, 0x7a, 0x32, + 0x33, 0x6b, 0x64, 0x39, 0x78, 0x66, 0x31, 0x75, 0x48, 0x2b, 0x36, 0x7a, 0x63, 0x65, 0x33, 0x67, 0x51, 0x66, + 0x42, 0x57, 0x55, 0x43, 0x56, 0x4f, 0x51, 0x4f, 0x6f, 0x67, 0x43, 0x47, 0x62, 0x47, 0x47, 0x41, 0x57, 0x6f, + 0x5a, 0x48, 0x50, 0x4a, 0x54, 0x54, 0x75, 0x2b, 0x63, 0x42, 0x46, 0x68, 0x47, 0x5a, 0x74, 0x4e, 0x2b, 0x79, + 0x69, 0x5c, 0x0a, + 0x09, 0x72, 0x73, 0x66, 0x6e, 0x41, 0x65, 0x63, 0x4d, 0x2b, 0x38, 0x48, 0x54, 0x65, 0x41, 0x42, 0x59, 0x44, + 0x33, 0x78, 0x52, 0x34, 0x47, 0x64, 0x6f, 0x53, 0x41, 0x62, 0x41, 0x43, 0x49, 0x31, 0x67, 0x4e, 0x4a, 0x34, + 0x4e, 0x7a, 0x41, 0x50, 0x4f, 0x4a, 0x6a, 0x54, 0x70, 0x42, 0x48, 0x41, 0x68, 0x73, 0x4a, 0x4c, 0x51, 0x73, + 0x4e, 0x31, 0x4e, 0x33, 0x4c, 0x35, 0x66, 0x31, 0x63, 0x58, 0x63, 0x52, 0x7a, 0x41, 0x41, 0x4b, 0x73, 0x31, + 0x4e, 0x5c, 0x0a, + 0x09, 0x67, 0x42, 0x36, 0x47, 0x62, 0x4f, 0x51, 0x5a, 0x68, 0x42, 0x46, 0x35, 0x4c, 0x6d, 0x46, 0x55, 0x58, + 0x67, 0x41, 0x73, 0x42, 0x56, 0x59, 0x41, 0x6c, 0x77, 0x4b, 0x72, 0x43, 0x56, 0x50, 0x74, 0x37, 0x69, 0x61, + 0x65, 0x50, 0x63, 0x79, 0x48, 0x56, 0x74, 0x54, 0x6e, 0x77, 0x41, 0x33, 0x67, 0x5a, 0x6b, 0x42, 0x56, 0x4e, + 0x58, 0x6f, 0x47, 0x4d, 0x49, 0x49, 0x52, 0x65, 0x53, 0x61, 0x68, 0x4d, 0x65, 0x63, 0x54, 0x70, 0x74, 0x65, + 0x4c, 0x5c, 0x0a, + 0x09, 0x43, 0x4b, 0x50, 0x79, 0x4a, 0x63, 0x44, 0x6c, 0x77, 0x46, 0x58, 0x41, 0x42, 0x55, 0x77, 0x31, 0x38, + 0x66, 0x78, 0x68, 0x50, 0x72, 0x43, 0x42, 0x31, 0x68, 0x50, 0x2b, 0x48, 0x55, 0x2b, 0x55, 0x58, 0x59, 0x68, + 0x36, 0x71, 0x30, 0x30, 0x41, 0x44, 0x4e, 0x48, 0x4d, 0x59, 0x34, 0x52, 0x52, 0x65, 0x53, 0x59, 0x77, 0x68, + 0x39, 0x43, 0x6b, 0x43, 0x77, 0x6c, 0x54, 0x36, 0x75, 0x57, 0x45, 0x5a, 0x72, 0x34, 0x43, 0x75, 0x49, 0x59, + 0x77, 0x5c, 0x0a, + 0x09, 0x31, 0x56, 0x35, 0x4d, 0x47, 0x4d, 0x45, 0x31, 0x76, 0x48, 0x48, 0x43, 0x76, 0x2f, 0x66, 0x52, 0x73, + 0x67, 0x74, 0x52, 0x62, 0x36, 0x55, 0x45, 0x77, 0x49, 0x69, 0x61, 0x75, 0x54, 0x33, 0x46, 0x58, 0x6b, 0x69, + 0x59, 0x59, 0x69, 0x38, 0x6e, 0x6a, 0x4d, 0x70, 0x58, 0x45, 0x6b, 0x61, 0x65, 0x4b, 0x37, 0x4c, 0x6e, 0x71, + 0x6c, 0x79, 0x4c, 0x4d, 0x41, 0x41, 0x71, 0x61, 0x32, 0x51, 0x42, 0x6b, 0x4b, 0x4f, 0x70, 0x78, 0x77, 0x67, + 0x6a, 0x5c, 0x0a, + 0x09, 0x78, 0x43, 0x7a, 0x43, 0x79, 0x4e, 0x79, 0x39, 0x76, 0x62, 0x77, 0x53, 0x57, 0x41, 0x4e, 0x63, 0x42, + 0x36, 0x79, 0x6a, 0x75, 0x67, 0x74, 0x64, 0x6d, 0x74, 0x37, 0x35, 0x77, 0x4b, 0x36, 0x79, 0x69, 0x31, 0x42, + 0x76, 0x41, 0x77, 0x66, 0x41, 0x67, 0x41, 0x33, 0x65, 0x58, 0x67, 0x43, 0x62, 0x54, 0x39, 0x6a, 0x46, 0x74, + 0x4a, 0x69, 0x70, 0x5a, 0x6c, 0x35, 0x4e, 0x6d, 0x47, 0x62, 0x66, 0x68, 0x4e, 0x76, 0x4b, 0x4b, 0x62, 0x6b, + 0x49, 0x5c, 0x0a, + 0x09, 0x2b, 0x4b, 0x7a, 0x73, 0x49, 0x74, 0x54, 0x62, 0x51, 0x41, 0x48, 0x51, 0x30, 0x66, 0x79, 0x7a, 0x43, + 0x43, 0x76, 0x5a, 0x61, 0x34, 0x43, 0x31, 0x68, 0x42, 0x58, 0x65, 0x56, 0x63, 0x44, 0x46, 0x68, 0x4a, 0x46, + 0x62, 0x36, 0x6e, 0x5a, 0x35, 0x32, 0x51, 0x57, 0x6f, 0x76, 0x35, 0x68, 0x4e, 0x67, 0x48, 0x48, 0x67, 0x65, + 0x38, 0x4a, 0x6f, 0x4c, 0x67, 0x33, 0x71, 0x36, 0x72, 0x49, 0x4c, 0x55, 0x48, 0x38, 0x78, 0x32, 0x39, 0x57, + 0x72, 0x5c, 0x0a, + 0x09, 0x73, 0x50, 0x6b, 0x56, 0x62, 0x31, 0x33, 0x5a, 0x42, 0x61, 0x69, 0x2f, 0x6d, 0x41, 0x42, 0x59, 0x58, + 0x56, 0x67, 0x56, 0x61, 0x6a, 0x49, 0x44, 0x6f, 0x4d, 0x4a, 0x69, 0x41, 0x6d, 0x43, 0x69, 0x73, 0x43, 0x72, + 0x55, 0x5a, 0x44, 0x4e, 0x67, 0x4a, 0x4e, 0x39, 0x33, 0x55, 0x41, 0x46, 0x69, 0x41, 0x73, 0x42, 0x46, 0x50, + 0x75, 0x55, 0x31, 0x56, 0x6e, 0x59, 0x42, 0x36, 0x69, 0x30, 0x6d, 0x41, 0x4a, 0x59, 0x55, 0x56, 0x6f, 0x57, + 0x61, 0x5c, 0x0a, + 0x09, 0x7a, 0x67, 0x43, 0x6f, 0x4b, 0x41, 0x4e, 0x41, 0x5a, 0x34, 0x4a, 0x48, 0x5a, 0x46, 0x5a, 0x55, 0x54, + 0x41, 0x43, 0x59, 0x34, 0x73, 0x72, 0x4c, 0x41, 0x4b, 0x67, 0x6f, 0x44, 0x36, 0x2f, 0x56, 0x6d, 0x57, 0x41, + 0x41, 0x56, 0x46, 0x52, 0x4d, 0x41, 0x4d, 0x77, 0x70, 0x72, 0x41, 0x6f, 0x31, 0x58, 0x57, 0x32, 0x2b, 0x64, + 0x5a, 0x71, 0x61, 0x6d, 0x41, 0x43, 0x59, 0x56, 0x31, 0x67, 0x56, 0x61, 0x6a, 0x71, 0x2f, 0x58, 0x6c, 0x31, + 0x52, 0x5c, 0x0a, + 0x09, 0x62, 0x67, 0x4c, 0x6f, 0x54, 0x44, 0x41, 0x41, 0x4b, 0x69, 0x6f, 0x6d, 0x41, 0x50, 0x59, 0x58, 0x56, + 0x6f, 0x57, 0x61, 0x7a, 0x67, 0x43, 0x6f, 0x71, 0x4a, 0x67, 0x41, 0x32, 0x46, 0x6c, 0x59, 0x46, 0x57, 0x71, + 0x36, 0x4a, 0x70, 0x37, 0x76, 0x73, 0x42, 0x46, 0x69, 0x41, 0x6d, 0x42, 0x33, 0x59, 0x56, 0x57, 0x6f, 0x36, + 0x53, 0x62, 0x4c, 0x4c, 0x6b, 0x43, 0x39, 0x78, 0x51, 0x54, 0x41, 0x6e, 0x73, 0x4b, 0x71, 0x55, 0x4e, 0x50, + 0x39, 0x5c, 0x0a, + 0x09, 0x58, 0x58, 0x59, 0x42, 0x36, 0x69, 0x30, 0x6d, 0x41, 0x4c, 0x7a, 0x4d, 0x6b, 0x2f, 0x49, 0x36, 0x58, + 0x6e, 0x59, 0x42, 0x36, 0x69, 0x30, 0x6d, 0x41, 0x50, 0x34, 0x6f, 0x72, 0x41, 0x6f, 0x31, 0x6e, 0x59, 0x4e, + 0x48, 0x52, 0x52, 0x6b, 0x41, 0x4b, 0x74, 0x70, 0x78, 0x38, 0x4d, 0x49, 0x67, 0x56, 0x52, 0x55, 0x54, 0x41, + 0x4d, 0x63, 0x4b, 0x71, 0x30, 0x4a, 0x4e, 0x35, 0x69, 0x6e, 0x42, 0x4b, 0x79, 0x77, 0x6d, 0x41, 0x46, 0x7a, + 0x49, 0x5c, 0x0a, + 0x09, 0x55, 0x52, 0x35, 0x37, 0x79, 0x79, 0x35, 0x41, 0x2f, 0x63, 0x55, 0x45, 0x67, 0x4c, 0x74, 0x79, 0x6c, + 0x49, 0x65, 0x37, 0x6a, 0x79, 0x73, 0x73, 0x4a, 0x67, 0x44, 0x2b, 0x4b, 0x36, 0x77, 0x4b, 0x4e, 0x64, 0x6e, + 0x50, 0x5a, 0x52, 0x65, 0x67, 0x2f, 0x6d, 0x49, 0x43, 0x77, 0x4d, 0x73, 0x49, 0x4b, 0x77, 0x2b, 0x50, 0x48, + 0x36, 0x6d, 0x77, 0x67, 0x51, 0x4b, 0x67, 0x59, 0x77, 0x58, 0x58, 0x68, 0x55, 0x44, 0x46, 0x32, 0x6c, 0x5a, + 0x32, 0x5c, 0x0a, + 0x09, 0x41, 0x65, 0x6f, 0x76, 0x39, 0x74, 0x75, 0x41, 0x58, 0x78, 0x52, 0x53, 0x68, 0x5a, 0x72, 0x4d, 0x79, + 0x34, 0x4a, 0x56, 0x57, 0x47, 0x77, 0x41, 0x62, 0x43, 0x6d, 0x6b, 0x43, 0x6a, 0x58, 0x52, 0x62, 0x38, 0x44, + 0x72, 0x77, 0x44, 0x64, 0x6c, 0x46, 0x36, 0x4c, 0x2b, 0x59, 0x73, 0x2f, 0x55, 0x38, 0x6d, 0x55, 0x68, 0x56, + 0x61, 0x69, 0x4f, 0x57, 0x6f, 0x51, 0x6d, 0x33, 0x77, 0x6e, 0x73, 0x36, 0x50, 0x6a, 0x35, 0x48, 0x62, 0x43, + 0x56, 0x5c, 0x0a, + 0x09, 0x6a, 0x74, 0x31, 0x2f, 0x48, 0x67, 0x52, 0x55, 0x58, 0x62, 0x45, 0x42, 0x38, 0x45, 0x4d, 0x68, 0x56, + 0x61, 0x67, 0x71, 0x2f, 0x67, 0x4c, 0x32, 0x41, 0x62, 0x38, 0x53, 0x7a, 0x76, 0x2b, 0x77, 0x6a, 0x39, 0x44, + 0x6b, 0x76, 0x32, 0x66, 0x33, 0x64, 0x78, 0x4d, 0x61, 0x2b, 0x35, 0x66, 0x73, 0x64, 0x2f, 0x39, 0x4f, 0x39, + 0x32, 0x59, 0x32, 0x66, 0x76, 0x58, 0x46, 0x42, 0x73, 0x43, 0x4f, 0x49, 0x6f, 0x72, 0x51, 0x79, 0x4c, 0x55, + 0x49, 0x5c, 0x0a, + 0x09, 0x68, 0x32, 0x34, 0x66, 0x36, 0x50, 0x72, 0x5a, 0x65, 0x66, 0x38, 0x33, 0x51, 0x6c, 0x50, 0x76, 0x5a, + 0x36, 0x72, 0x4a, 0x6f, 0x78, 0x64, 0x35, 0x62, 0x66, 0x4a, 0x36, 0x69, 0x77, 0x32, 0x41, 0x67, 0x39, 0x6c, + 0x74, 0x59, 0x51, 0x47, 0x31, 0x36, 0x47, 0x53, 0x48, 0x42, 0x72, 0x6a, 0x39, 0x77, 0x61, 0x6d, 0x4e, 0x66, + 0x59, 0x44, 0x77, 0x66, 0x35, 0x53, 0x4c, 0x44, 0x5a, 0x32, 0x57, 0x32, 0x41, 0x42, 0x6f, 0x41, 0x65, 0x38, + 0x42, 0x5c, 0x0a, + 0x09, 0x6a, 0x78, 0x56, 0x51, 0x53, 0x35, 0x4d, 0x63, 0x34, 0x64, 0x52, 0x6d, 0x50, 0x64, 0x6a, 0x6a, 0x64, + 0x2f, 0x31, 0x75, 0x75, 0x52, 0x75, 0x34, 0x7a, 0x55, 0x62, 0x57, 0x49, 0x4d, 0x5a, 0x61, 0x72, 0x63, 0x47, + 0x50, 0x37, 0x38, 0x6b, 0x75, 0x38, 0x48, 0x67, 0x66, 0x38, 0x45, 0x35, 0x52, 0x42, 0x56, 0x58, 0x4d, 0x46, + 0x6d, 0x41, 0x58, 0x6f, 0x61, 0x48, 0x62, 0x74, 0x38, 0x4f, 0x45, 0x42, 0x6a, 0x33, 0x53, 0x34, 0x39, 0x5a, + 0x75, 0x5c, 0x0a, + 0x09, 0x34, 0x4b, 0x45, 0x50, 0x6d, 0x72, 0x4b, 0x42, 0x64, 0x53, 0x62, 0x6b, 0x4f, 0x56, 0x2f, 0x37, 0x75, + 0x38, 0x41, 0x6e, 0x77, 0x49, 0x30, 0x6a, 0x72, 0x69, 0x57, 0x76, 0x76, 0x77, 0x6b, 0x4e, 0x4f, 0x51, 0x6c, + 0x63, 0x4f, 0x4d, 0x4c, 0x33, 0x66, 0x52, 0x6c, 0x34, 0x4d, 0x65, 0x2b, 0x4c, 0x62, 0x57, 0x44, 0x56, 0x51, + 0x5a, 0x34, 0x41, 0x61, 0x41, 0x46, 0x33, 0x41, 0x30, 0x38, 0x41, 0x4e, 0x77, 0x43, 0x58, 0x41, 0x57, 0x63, + 0x54, 0x5c, 0x0a, + 0x09, 0x31, 0x67, 0x58, 0x6d, 0x45, 0x71, 0x34, 0x66, 0x63, 0x47, 0x37, 0x48, 0x38, 0x34, 0x38, 0x41, 0x4a, + 0x7a, 0x6f, 0x65, 0x54, 0x78, 0x49, 0x57, 0x6d, 0x37, 0x70, 0x2f, 0x48, 0x73, 0x2b, 0x65, 0x65, 0x35, 0x51, + 0x77, 0x79, 0x68, 0x37, 0x4f, 0x37, 0x68, 0x2f, 0x6c, 0x35, 0x42, 0x47, 0x32, 0x2f, 0x62, 0x75, 0x44, 0x68, + 0x47, 0x33, 0x65, 0x76, 0x37, 0x4c, 0x33, 0x66, 0x52, 0x35, 0x34, 0x4a, 0x63, 0x66, 0x66, 0x70, 0x35, 0x66, + 0x6e, 0x5c, 0x0a, + 0x09, 0x67, 0x4e, 0x66, 0x41, 0x52, 0x6c, 0x61, 0x7a, 0x52, 0x57, 0x30, 0x43, 0x51, 0x4b, 0x57, 0x76, 0x38, + 0x2f, 0x34, 0x35, 0x63, 0x50, 0x32, 0x51, 0x37, 0x33, 0x45, 0x43, 0x65, 0x41, 0x70, 0x34, 0x45, 0x32, 0x78, + 0x2b, 0x4e, 0x56, 0x39, 0x30, 0x41, 0x46, 0x52, 0x4e, 0x46, 0x6b, 0x68, 0x72, 0x67, 0x4f, 0x2b, 0x48, 0x66, + 0x4b, 0x74, 0x4a, 0x59, 0x42, 0x4f, 0x77, 0x47, 0x57, 0x78, 0x2b, 0x70, 0x61, 0x45, 0x70, 0x31, 0x32, 0x7a, + 0x62, 0x5c, 0x0a, + 0x09, 0x4e, 0x4f, 0x54, 0x72, 0x6a, 0x77, 0x45, 0x62, 0x67, 0x59, 0x2f, 0x41, 0x35, 0x6c, 0x63, 0x36, 0x61, + 0x6a, 0x30, 0x44, 0x36, 0x4e, 0x67, 0x63, 0x2b, 0x52, 0x5a, 0x59, 0x6d, 0x2f, 0x4e, 0x74, 0x39, 0x67, 0x50, + 0x33, 0x45, 0x68, 0x59, 0x32, 0x62, 0x58, 0x34, 0x6c, 0x70, 0x51, 0x6b, 0x7a, 0x67, 0x47, 0x76, 0x4a, 0x33, + 0x2f, 0x79, 0x2f, 0x45, 0x42, 0x59, 0x30, 0x74, 0x34, 0x4c, 0x4e, 0x72, 0x2f, 0x51, 0x30, 0x49, 0x51, 0x41, + 0x65, 0x5c, 0x0a, + 0x09, 0x7a, 0x66, 0x6d, 0x36, 0x62, 0x63, 0x41, 0x47, 0x34, 0x43, 0x65, 0x77, 0x2b, 0x5a, 0x57, 0x6d, 0x32, + 0x6d, 0x34, 0x43, 0x64, 0x45, 0x7a, 0x2f, 0x74, 0x78, 0x46, 0x32, 0x52, 0x63, 0x62, 0x59, 0x43, 0x74, 0x78, + 0x46, 0x39, 0x6f, 0x30, 0x31, 0x6d, 0x31, 0x2b, 0x70, 0x71, 0x76, 0x76, 0x6c, 0x77, 0x57, 0x38, 0x6b, 0x76, + 0x76, 0x6b, 0x2f, 0x42, 0x6d, 0x37, 0x42, 0x35, 0x70, 0x66, 0x71, 0x47, 0x51, 0x41, 0x64, 0x6f, 0x2f, 0x2f, + 0x44, 0x5c, 0x0a, + 0x09, 0x6b, 0x53, 0x2f, 0x39, 0x45, 0x4c, 0x69, 0x54, 0x37, 0x45, 0x6f, 0x31, 0x4e, 0x72, 0x39, 0x53, 0x56, + 0x38, 0x73, 0x41, 0x79, 0x49, 0x77, 0x44, 0x6a, 0x30, 0x51, 0x38, 0x2f, 0x79, 0x33, 0x67, 0x66, 0x75, 0x42, + 0x50, 0x73, 0x50, 0x6b, 0x6c, 0x71, 0x48, 0x63, 0x41, 0x33, 0x41, 0x79, 0x73, 0x47, 0x50, 0x43, 0x35, 0x62, + 0x78, 0x41, 0x57, 0x43, 0x2f, 0x38, 0x42, 0x6d, 0x31, 0x39, 0x71, 0x71, 0x31, 0x30, 0x41, 0x64, 0x45, 0x7a, + 0x2f, 0x5c, 0x0a, + 0x09, 0x42, 0x2f, 0x31, 0x4b, 0x38, 0x71, 0x76, 0x41, 0x4d, 0x32, 0x54, 0x58, 0x4e, 0x62, 0x44, 0x35, 0x70, + 0x53, 0x6c, 0x31, 0x33, 0x51, 0x30, 0x34, 0x41, 0x33, 0x68, 0x6f, 0x67, 0x4f, 0x65, 0x39, 0x51, 0x41, 0x67, + 0x41, 0x77, 0x4f, 0x61, 0x58, 0x75, 0x74, 0x55, 0x31, 0x41, 0x4f, 0x34, 0x45, 0x6c, 0x6b, 0x37, 0x7a, 0x35, + 0x79, 0x65, 0x41, 0x5a, 0x77, 0x6c, 0x54, 0x66, 0x78, 0x74, 0x66, 0x36, 0x71, 0x4e, 0x57, 0x41, 0x54, 0x44, + 0x67, 0x5c, 0x0a, + 0x09, 0x36, 0x76, 0x38, 0x6b, 0x38, 0x44, 0x68, 0x68, 0x30, 0x63, 0x2f, 0x6d, 0x6c, 0x36, 0x5a, 0x52, 0x71, + 0x77, 0x44, 0x49, 0x7a, 0x4b, 0x48, 0x2f, 0x39, 0x50, 0x38, 0x34, 0x38, 0x43, 0x44, 0x77, 0x41, 0x64, 0x6a, + 0x38, 0x30, 0x75, 0x6e, 0x55, 0x4d, 0x51, 0x41, 0x32, 0x41, 0x41, 0x74, 0x36, 0x2f, 0x50, 0x34, 0x51, 0x63, + 0x41, 0x2f, 0x68, 0x51, 0x42, 0x2b, 0x62, 0x58, 0x78, 0x70, 0x41, 0x62, 0x51, 0x4c, 0x67, 0x4e, 0x4b, 0x76, + 0x2f, 0x5c, 0x0a, + 0x09, 0x65, 0x77, 0x6e, 0x42, 0x38, 0x44, 0x58, 0x59, 0x2f, 0x4e, 0x4b, 0x67, 0x36, 0x72, 0x59, 0x62, 0x63, + 0x42, 0x37, 0x68, 0x59, 0x4a, 0x35, 0x4f, 0x32, 0x34, 0x46, 0x62, 0x73, 0x66, 0x6d, 0x6c, 0x61, 0x48, 0x55, + 0x4c, 0x67, 0x49, 0x33, 0x41, 0x57, 0x52, 0x32, 0x50, 0x74, 0x77, 0x4b, 0x33, 0x41, 0x54, 0x2b, 0x43, 0x7a, + 0x53, 0x2f, 0x46, 0x71, 0x6b, 0x55, 0x41, 0x39, 0x46, 0x6e, 0x39, 0x2f, 0x78, 0x53, 0x34, 0x48, 0x66, 0x67, + 0x5a, 0x5c, 0x0a, + 0x09, 0x62, 0x48, 0x34, 0x70, 0x6a, 0x31, 0x6f, 0x45, 0x51, 0x47, 0x59, 0x42, 0x34, 0x63, 0x77, 0x39, 0x45, + 0x45, 0x37, 0x64, 0x64, 0x51, 0x66, 0x68, 0x62, 0x44, 0x34, 0x32, 0x76, 0x35, 0x52, 0x54, 0x6e, 0x51, 0x4a, + 0x67, 0x49, 0x32, 0x45, 0x58, 0x34, 0x47, 0x62, 0x43, 0x61, 0x76, 0x38, 0x78, 0x73, 0x50, 0x6d, 0x6c, 0x59, + 0x56, 0x54, 0x2b, 0x68, 0x43, 0x41, 0x64, 0x30, 0x2f, 0x2f, 0x33, 0x67, 0x54, 0x33, 0x41, 0x30, 0x33, 0x68, + 0x63, 0x5c, 0x0a, + 0x09, 0x76, 0x7a, 0x51, 0x53, 0x64, 0x5a, 0x6b, 0x42, 0x4c, 0x41, 0x61, 0x2b, 0x41, 0x70, 0x37, 0x45, 0x35, + 0x70, 0x64, 0x47, 0x70, 0x69, 0x34, 0x7a, 0x67, 0x44, 0x45, 0x36, 0x72, 0x72, 0x64, 0x6e, 0x38, 0x30, 0x75, + 0x6a, 0x55, 0x5a, 0x63, 0x44, 0x67, 0x56, 0x70, 0x67, 0x34, 0x30, 0x75, 0x6a, 0x56, 0x76, 0x6b, 0x5a, 0x67, + 0x4b, 0x54, 0x69, 0x31, 0x47, 0x55, 0x4e, 0x51, 0x46, 0x49, 0x42, 0x44, 0x41, 0x41, 0x70, 0x59, 0x51, 0x61, + 0x41, 0x5c, 0x0a, + 0x09, 0x6c, 0x44, 0x41, 0x44, 0x51, 0x45, 0x71, 0x59, 0x41, 0x53, 0x41, 0x6c, 0x7a, 0x41, 0x43, 0x51, 0x45, + 0x6d, 0x59, 0x41, 0x53, 0x41, 0x6b, 0x7a, 0x41, 0x4b, 0x53, 0x45, 0x47, 0x51, 0x42, 0x53, 0x77, 0x67, 0x77, + 0x41, 0x4b, 0x57, 0x45, 0x47, 0x67, 0x4a, 0x51, 0x77, 0x41, 0x30, 0x42, 0x4b, 0x6d, 0x41, 0x45, 0x67, 0x4a, + 0x63, 0x77, 0x41, 0x6b, 0x42, 0x4a, 0x6d, 0x41, 0x45, 0x67, 0x4a, 0x4d, 0x77, 0x43, 0x6b, 0x68, 0x42, 0x6b, + 0x41, 0x5c, 0x0a, + 0x09, 0x55, 0x73, 0x49, 0x4d, 0x41, 0x43, 0x6c, 0x68, 0x42, 0x6f, 0x43, 0x55, 0x4d, 0x41, 0x4e, 0x41, 0x53, + 0x70, 0x67, 0x42, 0x49, 0x43, 0x58, 0x4d, 0x41, 0x4a, 0x41, 0x53, 0x5a, 0x67, 0x42, 0x49, 0x43, 0x54, 0x4d, + 0x41, 0x70, 0x49, 0x51, 0x5a, 0x41, 0x46, 0x4c, 0x43, 0x44, 0x41, 0x41, 0x70, 0x59, 0x51, 0x61, 0x41, 0x6c, + 0x44, 0x41, 0x44, 0x51, 0x45, 0x71, 0x59, 0x41, 0x53, 0x41, 0x6c, 0x7a, 0x41, 0x43, 0x51, 0x45, 0x6d, 0x59, + 0x41, 0x5c, 0x0a, + 0x09, 0x53, 0x41, 0x6b, 0x7a, 0x41, 0x4b, 0x53, 0x45, 0x47, 0x51, 0x42, 0x53, 0x77, 0x67, 0x77, 0x41, 0x4b, + 0x57, 0x45, 0x47, 0x67, 0x4a, 0x51, 0x77, 0x41, 0x30, 0x42, 0x4b, 0x6d, 0x41, 0x45, 0x67, 0x4a, 0x63, 0x77, + 0x41, 0x6b, 0x42, 0x4a, 0x6d, 0x41, 0x45, 0x67, 0x4a, 0x4d, 0x77, 0x43, 0x6b, 0x68, 0x42, 0x6b, 0x41, 0x55, + 0x73, 0x49, 0x4d, 0x41, 0x43, 0x6c, 0x68, 0x42, 0x6f, 0x43, 0x55, 0x4d, 0x41, 0x4e, 0x41, 0x53, 0x70, 0x67, + 0x42, 0x5c, 0x0a, + 0x09, 0x49, 0x43, 0x58, 0x4d, 0x41, 0x4a, 0x41, 0x53, 0x5a, 0x67, 0x42, 0x49, 0x43, 0x54, 0x4d, 0x41, 0x70, + 0x49, 0x51, 0x5a, 0x41, 0x46, 0x4c, 0x43, 0x44, 0x41, 0x41, 0x70, 0x59, 0x66, 0x38, 0x44, 0x63, 0x44, 0x39, + 0x39, 0x47, 0x6c, 0x32, 0x37, 0x6b, 0x55, 0x6b, 0x41, 0x41, 0x41, 0x41, 0x41, 0x53, 0x55, 0x56, 0x4f, 0x52, + 0x4b, 0x35, 0x43, 0x59, 0x49, 0x49, 0x3d, 0x5c, 0x0a, + 0x09, 0x22, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x70, + 0x6e, 0x67, 0x20, 0x3d, 0x0a, + 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x4e, + 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x43, 0x41, + 0x59, 0x41, 0x41, 0x41, 0x42, 0x63, 0x63, 0x71, 0x68, 0x6d, 0x41, 0x41, 0x41, 0x67, 0x41, 0x45, 0x6c, 0x45, + 0x51, 0x56, 0x52, 0x34, 0x6e, 0x4f, 0x79, 0x39, 0x65, 0x62, 0x77, 0x6c, 0x56, 0x31, 0x55, 0x76, 0x2f, 0x6c, + 0x31, 0x56, 0x5c, 0x0a, + 0x09, 0x5a, 0x37, 0x68, 0x44, 0x39, 0x37, 0x33, 0x64, 0x6e, 0x52, 0x34, 0x79, 0x64, 0x79, 0x66, 0x64, 0x68, + 0x42, 0x41, 0x79, 0x51, 0x42, 0x42, 0x4d, 0x43, 0x43, 0x42, 0x44, 0x6e, 0x67, 0x4a, 0x52, 0x47, 0x63, 0x57, + 0x66, 0x54, 0x31, 0x51, 0x45, 0x55, 0x51, 0x48, 0x31, 0x5a, 0x2b, 0x43, 0x4a, 0x67, 0x6b, 0x39, 0x42, 0x48, + 0x6a, 0x6a, 0x41, 0x38, 0x34, 0x47, 0x41, 0x54, 0x49, 0x72, 0x54, 0x44, 0x35, 0x2b, 0x6f, 0x50, 0x50, 0x7a, + 0x4a, 0x5c, 0x0a, + 0x09, 0x45, 0x30, 0x55, 0x68, 0x41, 0x57, 0x51, 0x4d, 0x49, 0x43, 0x52, 0x6b, 0x41, 0x45, 0x4a, 0x43, 0x35, + 0x6e, 0x6e, 0x6f, 0x76, 0x74, 0x31, 0x33, 0x50, 0x50, 0x64, 0x55, 0x37, 0x66, 0x66, 0x48, 0x72, 0x72, 0x31, + 0x72, 0x72, 0x62, 0x56, 0x58, 0x6e, 0x64, 0x76, 0x45, 0x4f, 0x2f, 0x54, 0x7a, 0x31, 0x75, 0x72, 0x50, 0x37, + 0x56, 0x4f, 0x6e, 0x61, 0x67, 0x39, 0x72, 0x72, 0x2b, 0x47, 0x37, 0x31, 0x74, 0x36, 0x31, 0x71, 0x77, 0x34, + 0x35, 0x5c, 0x0a, + 0x09, 0x35, 0x39, 0x42, 0x53, 0x53, 0x79, 0x31, 0x74, 0x54, 0x73, 0x6f, 0x32, 0x6d, 0x6f, 0x47, 0x57, 0x57, + 0x6d, 0x70, 0x70, 0x34, 0x36, 0x67, 0x46, 0x67, 0x4a, 0x5a, 0x61, 0x32, 0x73, 0x54, 0x55, 0x41, 0x6b, 0x42, + 0x4c, 0x4c, 0x57, 0x31, 0x69, 0x61, 0x67, 0x47, 0x67, 0x70, 0x5a, 0x59, 0x32, 0x4d, 0x62, 0x55, 0x41, 0x30, + 0x46, 0x4a, 0x4c, 0x6d, 0x35, 0x68, 0x61, 0x41, 0x47, 0x69, 0x70, 0x70, 0x55, 0x31, 0x4d, 0x4c, 0x51, 0x43, + 0x30, 0x5c, 0x0a, + 0x09, 0x31, 0x4e, 0x49, 0x6d, 0x70, 0x68, 0x59, 0x41, 0x57, 0x6d, 0x70, 0x70, 0x45, 0x31, 0x4d, 0x4c, 0x41, + 0x43, 0x32, 0x31, 0x74, 0x49, 0x6d, 0x70, 0x42, 0x59, 0x43, 0x57, 0x57, 0x74, 0x72, 0x45, 0x31, 0x41, 0x4a, + 0x41, 0x53, 0x79, 0x31, 0x74, 0x59, 0x6d, 0x6f, 0x42, 0x6f, 0x4b, 0x57, 0x57, 0x4e, 0x6a, 0x47, 0x31, 0x41, + 0x4e, 0x42, 0x53, 0x53, 0x35, 0x75, 0x59, 0x57, 0x67, 0x42, 0x6f, 0x71, 0x61, 0x56, 0x4e, 0x54, 0x43, 0x30, + 0x41, 0x5c, 0x0a, + 0x09, 0x74, 0x4e, 0x54, 0x53, 0x4a, 0x71, 0x59, 0x57, 0x41, 0x46, 0x70, 0x71, 0x61, 0x52, 0x4e, 0x54, 0x43, + 0x77, 0x41, 0x74, 0x74, 0x62, 0x53, 0x4a, 0x71, 0x51, 0x57, 0x41, 0x6c, 0x6c, 0x72, 0x61, 0x78, 0x4e, 0x51, + 0x43, 0x51, 0x45, 0x73, 0x74, 0x62, 0x57, 0x4a, 0x71, 0x41, 0x61, 0x43, 0x6c, 0x6c, 0x6a, 0x59, 0x78, 0x74, + 0x51, 0x44, 0x51, 0x55, 0x6b, 0x75, 0x62, 0x6d, 0x46, 0x6f, 0x41, 0x61, 0x4b, 0x6d, 0x6c, 0x54, 0x55, 0x77, + 0x74, 0x5c, 0x0a, + 0x09, 0x41, 0x4c, 0x54, 0x55, 0x30, 0x69, 0x61, 0x6d, 0x46, 0x67, 0x42, 0x61, 0x61, 0x6d, 0x6b, 0x54, 0x55, + 0x77, 0x73, 0x41, 0x4c, 0x62, 0x57, 0x30, 0x69, 0x61, 0x6b, 0x46, 0x67, 0x4a, 0x5a, 0x61, 0x32, 0x73, 0x54, + 0x55, 0x41, 0x6b, 0x42, 0x4c, 0x4c, 0x57, 0x31, 0x69, 0x61, 0x67, 0x47, 0x67, 0x70, 0x5a, 0x59, 0x32, 0x4d, + 0x62, 0x55, 0x41, 0x30, 0x46, 0x4a, 0x4c, 0x6d, 0x35, 0x68, 0x61, 0x41, 0x47, 0x69, 0x70, 0x70, 0x55, 0x31, + 0x4d, 0x5c, 0x0a, + 0x09, 0x4c, 0x51, 0x43, 0x30, 0x31, 0x4e, 0x49, 0x6d, 0x70, 0x68, 0x59, 0x41, 0x57, 0x6d, 0x70, 0x70, 0x45, + 0x31, 0x4d, 0x4c, 0x41, 0x43, 0x32, 0x31, 0x74, 0x49, 0x6d, 0x70, 0x42, 0x59, 0x43, 0x57, 0x57, 0x74, 0x72, + 0x45, 0x31, 0x41, 0x4a, 0x41, 0x53, 0x79, 0x31, 0x74, 0x59, 0x6d, 0x6f, 0x42, 0x6f, 0x4b, 0x57, 0x57, 0x4e, + 0x6a, 0x47, 0x31, 0x41, 0x4e, 0x42, 0x53, 0x53, 0x35, 0x75, 0x59, 0x57, 0x67, 0x42, 0x6f, 0x71, 0x61, 0x56, + 0x4e, 0x5c, 0x0a, + 0x09, 0x54, 0x43, 0x30, 0x41, 0x74, 0x4e, 0x54, 0x53, 0x4a, 0x71, 0x59, 0x57, 0x41, 0x46, 0x70, 0x71, 0x61, + 0x52, 0x4e, 0x54, 0x43, 0x77, 0x41, 0x74, 0x74, 0x62, 0x53, 0x4a, 0x71, 0x51, 0x57, 0x41, 0x6c, 0x6c, 0x72, + 0x61, 0x78, 0x4e, 0x51, 0x43, 0x51, 0x45, 0x73, 0x74, 0x62, 0x57, 0x4a, 0x71, 0x41, 0x61, 0x43, 0x6c, 0x6c, + 0x6a, 0x59, 0x78, 0x74, 0x51, 0x44, 0x51, 0x55, 0x6b, 0x75, 0x62, 0x6d, 0x46, 0x6f, 0x41, 0x61, 0x4b, 0x6d, + 0x6c, 0x5c, 0x0a, + 0x09, 0x54, 0x55, 0x77, 0x74, 0x41, 0x4c, 0x54, 0x55, 0x30, 0x69, 0x61, 0x6d, 0x46, 0x67, 0x42, 0x61, 0x61, + 0x6d, 0x6b, 0x54, 0x55, 0x32, 0x65, 0x6a, 0x47, 0x57, 0x69, 0x70, 0x70, 0x66, 0x38, 0x6f, 0x74, 0x48, 0x2f, + 0x66, 0x76, 0x6e, 0x68, 0x4d, 0x49, 0x41, 0x44, 0x41, 0x44, 0x54, 0x66, 0x66, 0x74, 0x45, 0x48, 0x63, 0x48, + 0x42, 0x32, 0x31, 0x47, 0x55, 0x42, 0x4c, 0x4c, 0x61, 0x30, 0x75, 0x50, 0x59, 0x74, 0x41, 0x31, 0x77, 0x4f, + 0x59, 0x5c, 0x0a, + 0x09, 0x33, 0x6d, 0x68, 0x47, 0x6a, 0x6f, 0x5a, 0x61, 0x41, 0x47, 0x69, 0x70, 0x70, 0x56, 0x55, 0x67, 0x46, + 0x76, 0x31, 0x2f, 0x79, 0x6a, 0x6e, 0x33, 0x4d, 0x41, 0x43, 0x58, 0x4f, 0x6a, 0x67, 0x63, 0x32, 0x48, 0x66, + 0x61, 0x78, 0x6a, 0x46, 0x31, 0x46, 0x4e, 0x51, 0x43, 0x51, 0x45, 0x73, 0x74, 0x72, 0x52, 0x35, 0x31, 0x41, + 0x56, 0x77, 0x4d, 0x41, 0x68, 0x7a, 0x63, 0x79, 0x77, 0x6a, 0x55, 0x63, 0x33, 0x41, 0x62, 0x7a, 0x64, 0x4e, + 0x49, 0x5c, 0x0a, + 0x09, 0x61, 0x67, 0x47, 0x67, 0x70, 0x5a, 0x5a, 0x57, 0x67, 0x78, 0x78, 0x41, 0x6f, 0x4d, 0x66, 0x44, 0x59, + 0x57, 0x73, 0x31, 0x2f, 0x39, 0x2f, 0x74, 0x34, 0x48, 0x35, 0x67, 0x6f, 0x39, 0x6c, 0x61, 0x69, 0x56, 0x6f, + 0x41, 0x61, 0x4b, 0x6d, 0x6c, 0x56, 0x53, 0x4c, 0x6e, 0x33, 0x4e, 0x4f, 0x4a, 0x71, 0x50, 0x6f, 0x43, 0x45, + 0x4f, 0x67, 0x46, 0x63, 0x4d, 0x44, 0x2b, 0x76, 0x66, 0x73, 0x32, 0x6c, 0x4b, 0x39, 0x52, 0x31, 0x41, 0x4a, + 0x41, 0x5c, 0x0a, + 0x09, 0x53, 0x79, 0x33, 0x39, 0x4f, 0x79, 0x6e, 0x4d, 0x2f, 0x34, 0x6e, 0x6f, 0x6d, 0x63, 0x35, 0x56, 0x4b, + 0x62, 0x2f, 0x48, 0x67, 0x52, 0x2b, 0x47, 0x6e, 0x78, 0x59, 0x63, 0x73, 0x39, 0x51, 0x43, 0x51, 0x45, 0x73, + 0x74, 0x72, 0x51, 0x59, 0x52, 0x39, 0x6a, 0x75, 0x34, 0x63, 0x79, 0x76, 0x48, 0x42, 0x77, 0x41, 0x34, 0x75, + 0x43, 0x6b, 0x69, 0x75, 0x6d, 0x6a, 0x6a, 0x6d, 0x46, 0x71, 0x5a, 0x57, 0x67, 0x42, 0x6f, 0x71, 0x61, 0x56, + 0x56, 0x5c, 0x0a, + 0x09, 0x49, 0x41, 0x4c, 0x39, 0x69, 0x44, 0x6a, 0x68, 0x34, 0x6c, 0x36, 0x41, 0x5a, 0x38, 0x52, 0x70, 0x77, + 0x54, 0x46, 0x49, 0x4c, 0x51, 0x43, 0x30, 0x31, 0x4e, 0x4b, 0x2f, 0x67, 0x30, 0x4c, 0x36, 0x37, 0x2b, 0x42, + 0x2b, 0x42, 0x50, 0x42, 0x4f, 0x37, 0x2b, 0x42, 0x41, 0x52, 0x4b, 0x69, 0x6d, 0x41, 0x7a, 0x2f, 0x67, 0x34, + 0x4d, 0x51, 0x6d, 0x6f, 0x57, 0x4f, 0x4a, 0x57, 0x67, 0x42, 0x6f, 0x71, 0x61, 0x56, 0x2f, 0x50, 0x35, 0x30, + 0x44, 0x5c, 0x0a, + 0x09, 0x34, 0x48, 0x77, 0x34, 0x49, 0x4b, 0x34, 0x42, 0x41, 0x4b, 0x67, 0x69, 0x2f, 0x37, 0x6b, 0x41, 0x64, + 0x6d, 0x77, 0x51, 0x58, 0x79, 0x74, 0x53, 0x43, 0x77, 0x41, 0x74, 0x74, 0x66, 0x51, 0x51, 0x4b, 0x57, 0x7a, + 0x79, 0x49, 0x64, 0x41, 0x76, 0x45, 0x4d, 0x67, 0x37, 0x50, 0x41, 0x48, 0x68, 0x31, 0x72, 0x39, 0x7a, 0x44, + 0x67, 0x36, 0x4f, 0x41, 0x44, 0x78, 0x70, 0x77, 0x35, 0x68, 0x63, 0x67, 0x56, 0x6f, 0x41, 0x61, 0x4b, 0x6d, + 0x6c, 0x5c, 0x0a, + 0x09, 0x68, 0x30, 0x67, 0x4f, 0x44, 0x67, 0x54, 0x61, 0x42, 0x2b, 0x43, 0x6e, 0x6e, 0x58, 0x4d, 0x69, 0x2b, + 0x67, 0x4d, 0x41, 0x79, 0x45, 0x38, 0x4a, 0x43, 0x50, 0x52, 0x39, 0x36, 0x38, 0x2f, 0x64, 0x30, 0x56, 0x45, + 0x4c, 0x41, 0x43, 0x32, 0x31, 0x39, 0x42, 0x41, 0x6f, 0x52, 0x48, 0x38, 0x48, 0x39, 0x33, 0x62, 0x6e, 0x6e, + 0x4c, 0x2f, 0x56, 0x46, 0x39, 0x62, 0x36, 0x2f, 0x45, 0x37, 0x41, 0x63, 0x42, 0x30, 0x41, 0x6e, 0x67, 0x6a, + 0x67, 0x5c, 0x0a, + 0x09, 0x6d, 0x46, 0x77, 0x48, 0x61, 0x4a, 0x38, 0x47, 0x62, 0x4b, 0x6d, 0x6c, 0x37, 0x34, 0x4c, 0x55, 0x45, + 0x33, 0x2b, 0x76, 0x63, 0x6e, 0x41, 0x2f, 0x46, 0x4e, 0x4c, 0x2b, 0x73, 0x41, 0x42, 0x59, 0x58, 0x51, 0x50, + 0x67, 0x41, 0x63, 0x44, 0x42, 0x50, 0x52, 0x72, 0x2b, 0x34, 0x61, 0x43, 0x5a, 0x64, 0x57, 0x64, 0x34, 0x42, + 0x54, 0x6f, 0x6d, 0x41, 0x4f, 0x44, 0x41, 0x76, 0x74, 0x4f, 0x51, 0x37, 0x4a, 0x6d, 0x32, 0x74, 0x6c, 0x42, + 0x54, 0x5c, 0x0a, + 0x09, 0x77, 0x7a, 0x57, 0x71, 0x42, 0x51, 0x34, 0x63, 0x2b, 0x34, 0x39, 0x67, 0x74, 0x76, 0x52, 0x2f, 0x4a, + 0x37, 0x45, 0x48, 0x65, 0x77, 0x6a, 0x41, 0x71, 0x78, 0x7a, 0x63, 0x57, 0x2b, 0x41, 0x51, 0x37, 0x62, 0x4b, + 0x61, 0x45, 0x73, 0x54, 0x79, 0x44, 0x41, 0x77, 0x79, 0x41, 0x45, 0x39, 0x30, 0x63, 0x50, 0x2b, 0x77, 0x6a, + 0x75, 0x77, 0x65, 0x46, 0x52, 0x30, 0x54, 0x41, 0x46, 0x41, 0x4a, 0x37, 0x71, 0x63, 0x64, 0x33, 0x48, 0x6b, + 0x45, 0x5c, 0x0a, + 0x09, 0x6d, 0x6e, 0x56, 0x77, 0x51, 0x79, 0x49, 0x36, 0x37, 0x4a, 0x77, 0x72, 0x51, 0x54, 0x67, 0x45, 0x68, + 0x77, 0x4b, 0x45, 0x49, 0x77, 0x52, 0x61, 0x42, 0x6a, 0x44, 0x6e, 0x79, 0x43, 0x33, 0x43, 0x59, 0x52, 0x48, + 0x41, 0x50, 0x41, 0x67, 0x44, 0x41, 0x73, 0x30, 0x43, 0x47, 0x41, 0x4b, 0x59, 0x63, 0x58, 0x42, 0x4f, 0x70, + 0x31, 0x6f, 0x52, 0x6a, 0x66, 0x6b, 0x63, 0x6a, 0x64, 0x2b, 0x61, 0x64, 0x62, 0x44, 0x50, 0x4b, 0x2b, 0x49, + 0x49, 0x5c, 0x0a, + 0x09, 0x62, 0x37, 0x55, 0x50, 0x74, 0x4f, 0x44, 0x7a, 0x48, 0x34, 0x30, 0x4d, 0x57, 0x33, 0x6f, 0x34, 0x67, + 0x4c, 0x63, 0x36, 0x35, 0x35, 0x35, 0x42, 0x52, 0x48, 0x44, 0x6b, 0x2b, 0x44, 0x56, 0x76, 0x48, 0x79, 0x36, + 0x65, 0x34, 0x50, 0x51, 0x45, 0x41, 0x4d, 0x63, 0x63, 0x41, 0x46, 0x43, 0x79, 0x63, 0x4c, 0x48, 0x4f, 0x78, + 0x4b, 0x4c, 0x2f, 0x31, 0x51, 0x51, 0x36, 0x4f, 0x36, 0x42, 0x6f, 0x2f, 0x48, 0x54, 0x56, 0x50, 0x56, 0x55, + 0x6d, 0x5c, 0x0a, + 0x09, 0x57, 0x4c, 0x36, 0x78, 0x49, 0x6a, 0x71, 0x6b, 0x51, 0x31, 0x30, 0x4f, 0x6d, 0x43, 0x48, 0x51, 0x30, + 0x4d, 0x48, 0x4e, 0x45, 0x6d, 0x67, 0x41, 0x59, 0x42, 0x37, 0x41, 0x45, 0x6f, 0x41, 0x46, 0x35, 0x39, 0x77, + 0x53, 0x43, 0x41, 0x76, 0x68, 0x4f, 0x34, 0x41, 0x6c, 0x41, 0x69, 0x30, 0x34, 0x35, 0x35, 0x61, 0x49, 0x61, + 0x41, 0x48, 0x41, 0x77, 0x4d, 0x48, 0x4e, 0x45, 0x79, 0x6a, 0x35, 0x72, 0x4e, 0x70, 0x70, 0x4f, 0x6c, 0x38, + 0x34, 0x5c, 0x0a, + 0x09, 0x75, 0x43, 0x4d, 0x6a, 0x42, 0x39, 0x73, 0x45, 0x4e, 0x4e, 0x2b, 0x4e, 0x43, 0x69, 0x79, 0x41, 0x4f, + 0x6f, 0x70, 0x32, 0x62, 0x37, 0x7a, 0x6c, 0x35, 0x75, 0x2b, 0x69, 0x6b, 0x38, 0x31, 0x4a, 0x30, 0x64, 0x6c, + 0x54, 0x65, 0x55, 0x34, 0x41, 0x65, 0x41, 0x61, 0x41, 0x6e, 0x77, 0x54, 0x77, 0x51, 0x2f, 0x34, 0x32, 0x76, + 0x33, 0x4a, 0x32, 0x49, 0x4e, 0x37, 0x37, 0x5a, 0x33, 0x62, 0x49, 0x70, 0x77, 0x4b, 0x66, 0x68, 0x73, 0x4f, + 0x54, 0x5c, 0x0a, + 0x09, 0x69, 0x65, 0x69, 0x59, 0x43, 0x68, 0x49, 0x62, 0x6e, 0x67, 0x46, 0x55, 0x6a, 0x6a, 0x34, 0x4f, 0x34, + 0x42, 0x48, 0x63, 0x2b, 0x51, 0x50, 0x46, 0x44, 0x52, 0x57, 0x45, 0x78, 0x75, 0x67, 0x73, 0x36, 0x6e, 0x67, + 0x67, 0x6d, 0x4b, 0x36, 0x4f, 0x6a, 0x77, 0x73, 0x4c, 0x4d, 0x6e, 0x79, 0x44, 0x52, 0x75, 0x79, 0x37, 0x61, + 0x6a, 0x64, 0x75, 0x33, 0x4b, 0x67, 0x55, 0x79, 0x76, 0x76, 0x6b, 0x51, 0x42, 0x54, 0x36, 0x31, 0x38, 0x44, + 0x45, 0x5c, 0x0a, + 0x09, 0x41, 0x61, 0x73, 0x61, 0x30, 0x32, 0x45, 0x41, 0x6a, 0x6b, 0x42, 0x7a, 0x41, 0x4a, 0x59, 0x64, 0x33, + 0x43, 0x4b, 0x41, 0x52, 0x53, 0x49, 0x61, 0x4f, 0x75, 0x64, 0x6d, 0x71, 0x32, 0x4b, 0x48, 0x4b, 0x6a, 0x5a, + 0x6d, 0x51, 0x52, 0x6a, 0x43, 0x59, 0x52, 0x47, 0x45, 0x52, 0x51, 0x42, 0x44, 0x4f, 0x4d, 0x77, 0x53, 0x6b, + 0x58, 0x50, 0x4f, 0x7a, 0x56, 0x54, 0x54, 0x6d, 0x79, 0x50, 0x4f, 0x75, 0x51, 0x4b, 0x45, 0x42, 0x51, 0x49, + 0x74, 0x5c, 0x0a, + 0x09, 0x4f, 0x62, 0x69, 0x43, 0x51, 0x45, 0x65, 0x71, 0x4d, 0x66, 0x74, 0x36, 0x50, 0x68, 0x55, 0x39, 0x41, + 0x71, 0x44, 0x77, 0x55, 0x73, 0x42, 0x4d, 0x4e, 0x54, 0x63, 0x64, 0x41, 0x4a, 0x6a, 0x66, 0x76, 0x32, 0x2b, + 0x66, 0x6e, 0x51, 0x6d, 0x4e, 0x6f, 0x71, 0x5a, 0x73, 0x36, 0x47, 0x67, 0x79, 0x4a, 0x71, 0x75, 0x4d, 0x63, + 0x53, 0x37, 0x4a, 0x71, 0x6f, 0x34, 0x79, 0x47, 0x30, 0x76, 0x4b, 0x41, 0x6e, 0x7a, 0x7a, 0x54, 0x58, 0x4f, + 0x2f, 0x5c, 0x0a, + 0x09, 0x6d, 0x67, 0x69, 0x36, 0x7a, 0x35, 0x79, 0x49, 0x48, 0x75, 0x36, 0x63, 0x4f, 0x77, 0x2b, 0x45, 0x52, + 0x77, 0x48, 0x34, 0x58, 0x67, 0x49, 0x39, 0x33, 0x73, 0x46, 0x31, 0x49, 0x36, 0x39, 0x55, 0x32, 0x30, 0x36, + 0x77, 0x70, 0x32, 0x71, 0x75, 0x37, 0x34, 0x2f, 0x44, 0x4e, 0x57, 0x6d, 0x58, 0x6a, 0x79, 0x57, 0x69, 0x33, + 0x4d, 0x45, 0x56, 0x4b, 0x34, 0x78, 0x71, 0x58, 0x57, 0x6e, 0x44, 0x41, 0x51, 0x41, 0x41, 0x48, 0x4e, 0x79, + 0x35, 0x5c, 0x0a, + 0x09, 0x41, 0x48, 0x4c, 0x74, 0x57, 0x41, 0x49, 0x49, 0x6d, 0x50, 0x45, 0x47, 0x4a, 0x56, 0x53, 0x33, 0x57, + 0x45, 0x52, 0x62, 0x59, 0x74, 0x73, 0x6c, 0x63, 0x2b, 0x44, 0x51, 0x52, 0x6a, 0x41, 0x51, 0x49, 0x68, 0x4c, + 0x4b, 0x45, 0x2f, 0x77, 0x77, 0x42, 0x59, 0x62, 0x76, 0x75, 0x71, 0x77, 0x46, 0x45, 0x75, 0x7a, 0x36, 0x56, + 0x46, 0x56, 0x76, 0x6d, 0x6f, 0x69, 0x69, 0x49, 0x58, 0x43, 0x2b, 0x51, 0x31, 0x6b, 0x4f, 0x4c, 0x76, 0x45, + 0x38, 0x5c, 0x0a, + 0x09, 0x31, 0x58, 0x30, 0x59, 0x73, 0x75, 0x4a, 0x66, 0x61, 0x72, 0x35, 0x49, 0x7a, 0x54, 0x38, 0x44, 0x7a, + 0x35, 0x4b, 0x2f, 0x65, 0x51, 0x44, 0x4c, 0x46, 0x65, 0x38, 0x7a, 0x46, 0x63, 0x67, 0x4d, 0x41, 0x63, 0x78, + 0x57, 0x35, 0x30, 0x4a, 0x6d, 0x42, 0x43, 0x49, 0x36, 0x41, 0x70, 0x2f, 0x56, 0x6c, 0x41, 0x41, 0x4f, 0x52, + 0x2f, 0x6d, 0x68, 0x79, 0x71, 0x44, 0x71, 0x75, 0x65, 0x38, 0x79, 0x67, 0x44, 0x6b, 0x32, 0x4a, 0x6c, 0x2b, + 0x65, 0x5c, 0x0a, + 0x09, 0x61, 0x76, 0x34, 0x63, 0x33, 0x41, 0x77, 0x41, 0x78, 0x32, 0x51, 0x32, 0x43, 0x32, 0x44, 0x49, 0x39, + 0x4c, 0x4c, 0x67, 0x34, 0x4a, 0x59, 0x49, 0x46, 0x4a, 0x32, 0x4c, 0x52, 0x31, 0x48, 0x65, 0x68, 0x34, 0x69, + 0x73, 0x77, 0x52, 0x47, 0x42, 0x6a, 0x49, 0x69, 0x6d, 0x74, 0x46, 0x34, 0x71, 0x36, 0x68, 0x4c, 0x52, 0x70, + 0x48, 0x4f, 0x75, 0x43, 0x38, 0x49, 0x6b, 0x48, 0x4d, 0x4a, 0x6e, 0x68, 0x34, 0x69, 0x32, 0x4f, 0x4c, 0x68, + 0x70, 0x5c, 0x0a, + 0x09, 0x45, 0x4c, 0x62, 0x42, 0x34, 0x58, 0x67, 0x69, 0x4f, 0x74, 0x6b, 0x35, 0x64, 0x38, 0x43, 0x52, 0x47, + 0x2b, 0x4d, 0x79, 0x35, 0x72, 0x4c, 0x6c, 0x49, 0x4d, 0x41, 0x70, 0x79, 0x6a, 0x36, 0x73, 0x42, 0x7a, 0x68, + 0x6d, 0x76, 0x7a, 0x35, 0x34, 0x54, 0x54, 0x69, 0x34, 0x73, 0x77, 0x46, 0x63, 0x6c, 0x53, 0x68, 0x31, 0x41, + 0x2b, 0x6d, 0x59, 0x41, 0x41, 0x41, 0x43, 0x50, 0x64, 0x72, 0x42, 0x53, 0x63, 0x56, 0x56, 0x42, 0x6b, 0x62, + 0x77, 0x5c, 0x0a, + 0x09, 0x38, 0x79, 0x79, 0x52, 0x42, 0x66, 0x41, 0x56, 0x31, 0x31, 0x44, 0x4f, 0x53, 0x4d, 0x6d, 0x34, 0x4d, + 0x71, 0x4a, 0x2b, 0x79, 0x48, 0x41, 0x53, 0x64, 0x73, 0x79, 0x56, 0x7a, 0x63, 0x46, 0x43, 0x74, 0x36, 0x4f, + 0x7a, 0x42, 0x75, 0x37, 0x63, 0x30, 0x65, 0x47, 0x59, 0x38, 0x79, 0x6d, 0x41, 0x6b, 0x47, 0x4e, 0x4d, 0x6a, + 0x54, 0x61, 0x4a, 0x49, 0x69, 0x4c, 0x62, 0x4d, 0x4b, 0x4a, 0x50, 0x35, 0x49, 0x6b, 0x5a, 0x49, 0x73, 0x2b, + 0x4b, 0x5c, 0x0a, + 0x09, 0x71, 0x74, 0x4d, 0x54, 0x4c, 0x4d, 0x75, 0x5a, 0x44, 0x6d, 0x4d, 0x4c, 0x73, 0x75, 0x64, 0x39, 0x36, + 0x50, 0x48, 0x47, 0x66, 0x68, 0x6a, 0x50, 0x6a, 0x52, 0x51, 0x63, 0x6e, 0x35, 0x79, 0x6f, 0x45, 0x39, 0x74, + 0x7a, 0x6b, 0x6e, 0x64, 0x72, 0x34, 0x55, 0x7a, 0x49, 0x78, 0x77, 0x42, 0x4a, 0x72, 0x67, 0x50, 0x65, 0x6a, + 0x75, 0x57, 0x63, 0x51, 0x52, 0x34, 0x43, 0x51, 0x48, 0x69, 0x36, 0x37, 0x74, 0x49, 0x36, 0x2f, 0x4c, 0x72, + 0x6d, 0x5c, 0x0a, + 0x09, 0x30, 0x35, 0x79, 0x61, 0x57, 0x76, 0x55, 0x5a, 0x57, 0x46, 0x58, 0x6c, 0x4c, 0x33, 0x44, 0x4f, 0x48, + 0x56, 0x4d, 0x41, 0x63, 0x4b, 0x7a, 0x73, 0x41, 0x33, 0x68, 0x4d, 0x6f, 0x32, 0x4b, 0x64, 0x45, 0x77, 0x61, + 0x54, 0x4f, 0x42, 0x59, 0x7a, 0x78, 0x48, 0x41, 0x74, 0x52, 0x50, 0x66, 0x34, 0x6a, 0x36, 0x6a, 0x65, 0x6e, + 0x56, 0x55, 0x5a, 0x4f, 0x30, 0x2f, 0x6c, 0x51, 0x68, 0x6d, 0x65, 0x50, 0x6e, 0x4c, 0x41, 0x34, 0x55, 0x59, + 0x54, 0x5c, 0x0a, + 0x09, 0x32, 0x71, 0x6a, 0x42, 0x6e, 0x55, 0x51, 0x36, 0x79, 0x38, 0x63, 0x51, 0x32, 0x6b, 0x73, 0x79, 0x44, + 0x4f, 0x35, 0x77, 0x69, 0x70, 0x66, 0x41, 0x44, 0x32, 0x2f, 0x50, 0x6e, 0x42, 0x61, 0x70, 0x4e, 0x68, 0x4d, + 0x6e, 0x63, 0x69, 0x78, 0x44, 0x49, 0x6c, 0x6e, 0x4f, 0x64, 0x46, 0x35, 0x31, 0x53, 0x6d, 0x64, 0x5a, 0x6b, + 0x5a, 0x63, 0x52, 0x6a, 0x68, 0x39, 0x30, 0x6c, 0x66, 0x42, 0x41, 0x4a, 0x44, 0x36, 0x35, 0x54, 0x43, 0x4c, + 0x66, 0x5c, 0x0a, + 0x09, 0x59, 0x54, 0x6a, 0x4f, 0x48, 0x6c, 0x2b, 0x55, 0x47, 0x35, 0x4d, 0x72, 0x50, 0x36, 0x65, 0x4c, 0x4a, + 0x2b, 0x31, 0x43, 0x32, 0x6c, 0x55, 0x59, 0x53, 0x7a, 0x6a, 0x48, 0x77, 0x59, 0x50, 0x4c, 0x6d, 0x37, 0x66, + 0x50, 0x62, 0x55, 0x65, 0x33, 0x41, 0x34, 0x63, 0x34, 0x58, 0x6a, 0x36, 0x2b, 0x61, 0x43, 0x64, 0x65, 0x31, + 0x34, 0x39, 0x72, 0x46, 0x4e, 0x34, 0x47, 0x30, 0x59, 0x59, 0x43, 0x77, 0x50, 0x36, 0x39, 0x2b, 0x34, 0x4a, + 0x67, 0x5c, 0x0a, + 0x09, 0x48, 0x38, 0x55, 0x4e, 0x51, 0x69, 0x4f, 0x31, 0x6e, 0x6d, 0x73, 0x44, 0x38, 0x50, 0x57, 0x43, 0x4d, + 0x69, 0x43, 0x6e, 0x44, 0x4f, 0x45, 0x38, 0x4e, 0x78, 0x61, 0x74, 0x4d, 0x4f, 0x34, 0x63, 0x49, 0x6c, 0x56, + 0x7a, 0x64, 0x54, 0x62, 0x41, 0x2f, 0x31, 0x6e, 0x54, 0x6b, 0x64, 0x43, 0x58, 0x53, 0x53, 0x77, 0x71, 0x36, + 0x4e, 0x52, 0x56, 0x39, 0x4b, 0x76, 0x41, 0x49, 0x2f, 0x4a, 0x4a, 0x63, 0x6c, 0x36, 0x5a, 0x47, 0x44, 0x49, + 0x33, 0x5c, 0x0a, + 0x09, 0x4e, 0x49, 0x4f, 0x46, 0x43, 0x43, 0x34, 0x75, 0x58, 0x56, 0x63, 0x52, 0x36, 0x61, 0x6e, 0x46, 0x64, + 0x2f, 0x68, 0x30, 0x55, 0x70, 0x5a, 0x4a, 0x4f, 0x2b, 0x78, 0x66, 0x34, 0x4a, 0x6c, 0x2f, 0x61, 0x72, 0x43, + 0x49, 0x5a, 0x61, 0x6e, 0x75, 0x4a, 0x39, 0x45, 0x50, 0x72, 0x78, 0x4c, 0x30, 0x77, 0x65, 0x71, 0x49, 0x31, + 0x4e, 0x2f, 0x56, 0x66, 0x43, 0x62, 0x7a, 0x66, 0x30, 0x69, 0x77, 0x45, 0x39, 0x4d, 0x35, 0x35, 0x61, 0x51, + 0x36, 0x5c, 0x0a, + 0x09, 0x36, 0x2b, 0x44, 0x50, 0x39, 0x50, 0x4f, 0x4d, 0x69, 0x6f, 0x4d, 0x59, 0x6c, 0x32, 0x47, 0x30, 0x46, + 0x2f, 0x6b, 0x79, 0x6b, 0x47, 0x54, 0x73, 0x41, 0x43, 0x34, 0x45, 0x6a, 0x71, 0x30, 0x4e, 0x51, 0x63, 0x64, + 0x43, 0x42, 0x74, 0x41, 0x6c, 0x30, 0x4c, 0x6e, 0x68, 0x69, 0x31, 0x43, 0x69, 0x51, 0x32, 0x4a, 0x77, 0x38, + 0x53, 0x75, 0x66, 0x4b, 0x72, 0x42, 0x50, 0x45, 0x57, 0x6c, 0x34, 0x55, 0x38, 0x48, 0x51, 0x41, 0x6c, 0x67, + 0x77, 0x5c, 0x0a, + 0x09, 0x38, 0x49, 0x6a, 0x39, 0x4d, 0x4b, 0x66, 0x56, 0x6b, 0x55, 0x59, 0x72, 0x6c, 0x42, 0x75, 0x63, 0x42, + 0x68, 0x49, 0x64, 0x77, 0x51, 0x57, 0x66, 0x53, 0x4e, 0x4e, 0x4a, 0x31, 0x6f, 0x6d, 0x34, 0x72, 0x71, 0x2f, + 0x70, 0x71, 0x4b, 0x5a, 0x65, 0x50, 0x70, 0x48, 0x30, 0x41, 0x5a, 0x62, 0x42, 0x61, 0x50, 0x37, 0x46, 0x47, + 0x48, 0x6e, 0x55, 0x5a, 0x75, 0x50, 0x6a, 0x52, 0x68, 0x33, 0x54, 0x63, 0x45, 0x73, 0x57, 0x71, 0x41, 0x46, + 0x61, 0x5c, 0x0a, + 0x09, 0x33, 0x36, 0x45, 0x78, 0x6e, 0x59, 0x7a, 0x78, 0x7a, 0x4f, 0x55, 0x6f, 0x2b, 0x47, 0x54, 0x4f, 0x4c, + 0x6b, 0x43, 0x54, 0x5a, 0x57, 0x7a, 0x67, 0x30, 0x79, 0x41, 0x47, 0x32, 0x68, 0x5a, 0x70, 0x2f, 0x69, 0x49, + 0x51, 0x36, 0x4c, 0x46, 0x58, 0x4d, 0x74, 0x50, 0x79, 0x31, 0x30, 0x47, 0x47, 0x5a, 0x35, 0x58, 0x57, 0x74, + 0x46, 0x4a, 0x6e, 0x6c, 0x68, 0x58, 0x2f, 0x5a, 0x34, 0x4c, 0x38, 0x2b, 0x74, 0x43, 0x78, 0x51, 0x68, 0x73, + 0x4f, 0x5c, 0x0a, + 0x09, 0x41, 0x45, 0x52, 0x30, 0x46, 0x6f, 0x41, 0x65, 0x52, 0x31, 0x71, 0x4e, 0x77, 0x50, 0x47, 0x37, 0x55, + 0x39, 0x45, 0x62, 0x64, 0x70, 0x53, 0x70, 0x47, 0x34, 0x65, 0x4d, 0x53, 0x67, 0x6f, 0x6b, 0x51, 0x76, 0x6d, + 0x6f, 0x7a, 0x42, 0x42, 0x6c, 0x2b, 0x48, 0x66, 0x57, 0x70, 0x67, 0x61, 0x6a, 0x6d, 0x4a, 0x30, 0x77, 0x2f, + 0x72, 0x67, 0x68, 0x69, 0x58, 0x6f, 0x38, 0x30, 0x33, 0x44, 0x79, 0x47, 0x68, 0x38, 0x6a, 0x6a, 0x31, 0x44, + 0x57, 0x5c, 0x0a, + 0x09, 0x6d, 0x45, 0x52, 0x62, 0x41, 0x52, 0x51, 0x30, 0x4b, 0x41, 0x5a, 0x5a, 0x61, 0x52, 0x41, 0x4a, 0x78, + 0x55, 0x6a, 0x4b, 0x7a, 0x38, 0x71, 0x49, 0x72, 0x49, 0x7a, 0x48, 0x57, 0x76, 0x45, 0x32, 0x2b, 0x57, 0x50, + 0x31, 0x72, 0x4f, 0x79, 0x4a, 0x38, 0x38, 0x58, 0x6e, 0x32, 0x61, 0x4a, 0x74, 0x79, 0x34, 0x2b, 0x35, 0x54, + 0x74, 0x4b, 0x6e, 0x37, 0x6b, 0x62, 0x79, 0x4a, 0x57, 0x54, 0x4f, 0x2b, 0x2b, 0x54, 0x4f, 0x7a, 0x75, 0x78, + 0x44, 0x5c, 0x0a, + 0x09, 0x5a, 0x35, 0x41, 0x61, 0x33, 0x45, 0x57, 0x2f, 0x54, 0x75, 0x6f, 0x35, 0x64, 0x73, 0x6d, 0x79, 0x6d, + 0x77, 0x70, 0x6f, 0x69, 0x55, 0x44, 0x66, 0x59, 0x34, 0x78, 0x73, 0x77, 0x32, 0x6a, 0x44, 0x41, 0x51, 0x44, + 0x41, 0x59, 0x2f, 0x53, 0x4a, 0x42, 0x4d, 0x6c, 0x46, 0x49, 0x47, 0x55, 0x70, 0x71, 0x62, 0x45, 0x34, 0x78, + 0x38, 0x76, 0x46, 0x4b, 0x4f, 0x4a, 0x50, 0x4a, 0x4d, 0x71, 0x4a, 0x42, 0x73, 0x6f, 0x4d, 0x51, 0x73, 0x77, + 0x2f, 0x5c, 0x0a, + 0x09, 0x6b, 0x36, 0x43, 0x56, 0x70, 0x74, 0x30, 0x52, 0x43, 0x49, 0x4b, 0x54, 0x67, 0x4a, 0x49, 0x73, 0x68, + 0x6e, 0x38, 0x4b, 0x77, 0x47, 0x46, 0x74, 0x52, 0x6d, 0x66, 0x47, 0x43, 0x69, 0x6d, 0x36, 0x49, 0x6a, 0x30, + 0x66, 0x6a, 0x56, 0x47, 0x55, 0x4f, 0x62, 0x49, 0x77, 0x61, 0x4f, 0x59, 0x45, 0x63, 0x53, 0x79, 0x73, 0x54, + 0x77, 0x74, 0x38, 0x42, 0x4a, 0x41, 0x5a, 0x36, 0x61, 0x30, 0x41, 0x6d, 0x70, 0x43, 0x57, 0x73, 0x7a, 0x37, + 0x45, 0x5c, 0x0a, + 0x09, 0x4f, 0x42, 0x76, 0x47, 0x6c, 0x2f, 0x54, 0x4e, 0x6e, 0x5a, 0x47, 0x74, 0x6b, 0x38, 0x54, 0x7a, 0x56, + 0x47, 0x64, 0x75, 0x2b, 0x70, 0x6f, 0x59, 0x46, 0x77, 0x50, 0x6b, 0x79, 0x41, 0x75, 0x37, 0x79, 0x36, 0x51, + 0x6a, 0x65, 0x7a, 0x49, 0x6d, 0x6c, 0x58, 0x6e, 0x70, 0x31, 0x44, 0x2f, 0x79, 0x45, 0x73, 0x62, 0x49, 0x77, + 0x56, 0x6a, 0x5a, 0x5a, 0x4e, 0x56, 0x76, 0x59, 0x75, 0x38, 0x62, 0x53, 0x52, 0x73, 0x4b, 0x41, 0x42, 0x55, + 0x79, 0x5c, 0x0a, + 0x09, 0x50, 0x74, 0x6f, 0x79, 0x68, 0x71, 0x52, 0x73, 0x70, 0x51, 0x78, 0x52, 0x4c, 0x6a, 0x79, 0x42, 0x52, + 0x61, 0x78, 0x4d, 0x51, 0x78, 0x54, 0x57, 0x61, 0x56, 0x72, 0x6f, 0x68, 0x36, 0x4e, 0x32, 0x45, 0x69, 0x30, + 0x4e, 0x55, 0x4c, 0x47, 0x69, 0x61, 0x6f, 0x77, 0x55, 0x49, 0x55, 0x58, 0x56, 0x43, 0x35, 0x42, 0x49, 0x4d, + 0x78, 0x66, 0x74, 0x38, 0x4c, 0x46, 0x39, 0x66, 0x6e, 0x74, 0x53, 0x70, 0x64, 0x7a, 0x38, 0x75, 0x33, 0x41, + 0x6f, 0x5c, 0x0a, + 0x09, 0x32, 0x4f, 0x65, 0x44, 0x73, 0x2b, 0x71, 0x73, 0x67, 0x6d, 0x63, 0x50, 0x6e, 0x42, 0x2f, 0x64, 0x68, + 0x2b, 0x55, 0x55, 0x79, 0x54, 0x46, 0x7a, 0x51, 0x6e, 0x46, 0x33, 0x77, 0x74, 0x57, 0x4f, 0x31, 0x73, 0x53, + 0x72, 0x50, 0x68, 0x66, 0x4c, 0x57, 0x6d, 0x6b, 0x35, 0x61, 0x68, 0x76, 0x67, 0x66, 0x59, 0x6c, 0x78, 0x36, + 0x7a, 0x45, 0x5a, 0x55, 0x35, 0x74, 0x51, 0x56, 0x32, 0x53, 0x52, 0x6f, 0x55, 0x2b, 0x64, 0x63, 0x57, 0x71, + 0x65, 0x5c, 0x0a, + 0x09, 0x2b, 0x54, 0x77, 0x66, 0x74, 0x55, 0x36, 0x74, 0x76, 0x51, 0x63, 0x38, 0x75, 0x41, 0x53, 0x39, 0x56, + 0x75, 0x30, 0x38, 0x35, 0x69, 0x69, 0x78, 0x66, 0x56, 0x31, 0x6f, 0x77, 0x77, 0x44, 0x67, 0x77, 0x4c, 0x37, + 0x54, 0x51, 0x45, 0x54, 0x49, 0x38, 0x6c, 0x7a, 0x63, 0x41, 0x51, 0x43, 0x51, 0x70, 0x47, 0x49, 0x51, 0x38, + 0x70, 0x56, 0x7a, 0x4c, 0x37, 0x37, 0x77, 0x49, 0x71, 0x59, 0x4b, 0x37, 0x42, 0x39, 0x58, 0x4f, 0x6c, 0x2b, + 0x77, 0x5c, 0x0a, + 0x09, 0x45, 0x61, 0x6b, 0x6f, 0x36, 0x79, 0x51, 0x34, 0x72, 0x70, 0x55, 0x2b, 0x78, 0x37, 0x49, 0x61, 0x4e, + 0x4b, 0x69, 0x75, 0x78, 0x39, 0x4e, 0x35, 0x55, 0x51, 0x59, 0x71, 0x4b, 0x68, 0x73, 0x4c, 0x6c, 0x4b, 0x45, + 0x4d, 0x42, 0x7a, 0x77, 0x75, 0x41, 0x79, 0x76, 0x36, 0x78, 0x73, 0x6a, 0x45, 0x6f, 0x68, 0x4e, 0x33, 0x6c, + 0x67, 0x68, 0x4d, 0x54, 0x48, 0x61, 0x78, 0x72, 0x77, 0x43, 0x69, 0x72, 0x75, 0x5a, 0x66, 0x38, 0x38, 0x36, + 0x6a, 0x5c, 0x0a, + 0x09, 0x4a, 0x49, 0x2b, 0x65, 0x59, 0x64, 0x77, 0x57, 0x58, 0x36, 0x46, 0x76, 0x6b, 0x65, 0x6f, 0x62, 0x38, + 0x6f, 0x78, 0x67, 0x77, 0x52, 0x32, 0x53, 0x6c, 0x50, 0x78, 0x5a, 0x56, 0x73, 0x48, 0x48, 0x70, 0x67, 0x47, + 0x66, 0x67, 0x35, 0x61, 0x70, 0x4f, 0x35, 0x34, 0x39, 0x4d, 0x46, 0x6e, 0x7a, 0x64, 0x72, 0x6d, 0x38, 0x6d, + 0x6a, 0x49, 0x59, 0x62, 0x6a, 0x4d, 0x63, 0x2b, 0x42, 0x4f, 0x67, 0x67, 0x62, 0x50, 0x47, 0x38, 0x52, 0x67, + 0x41, 0x5c, 0x0a, + 0x09, 0x78, 0x38, 0x77, 0x50, 0x68, 0x6d, 0x77, 0x59, 0x41, 0x50, 0x54, 0x48, 0x78, 0x75, 0x43, 0x63, 0x79, + 0x7a, 0x71, 0x64, 0x2f, 0x44, 0x48, 0x36, 0x31, 0x6b, 0x70, 0x79, 0x37, 0x31, 0x55, 0x5a, 0x6b, 0x33, 0x55, + 0x37, 0x43, 0x63, 0x54, 0x2b, 0x55, 0x43, 0x74, 0x48, 0x4b, 0x30, 0x58, 0x55, 0x71, 0x53, 0x2b, 0x6f, 0x72, + 0x37, 0x62, 0x79, 0x6d, 0x79, 0x4b, 0x2f, 0x64, 0x70, 0x4c, 0x49, 0x4f, 0x37, 0x76, 0x48, 0x62, 0x68, 0x4c, + 0x5a, 0x5c, 0x0a, + 0x09, 0x42, 0x73, 0x6a, 0x37, 0x30, 0x30, 0x35, 0x68, 0x70, 0x61, 0x74, 0x52, 0x5a, 0x68, 0x5a, 0x65, 0x4d, + 0x61, 0x50, 0x6e, 0x42, 0x69, 0x6d, 0x63, 0x52, 0x64, 0x58, 0x6c, 0x44, 0x69, 0x62, 0x36, 0x61, 0x70, 0x67, + 0x53, 0x52, 0x53, 0x63, 0x30, 0x36, 0x70, 0x68, 0x70, 0x73, 0x73, 0x6f, 0x32, 0x65, 0x4e, 0x39, 0x4a, 0x4e, + 0x71, 0x68, 0x42, 0x6b, 0x6a, 0x6d, 0x38, 0x75, 0x45, 0x2b, 0x76, 0x6f, 0x7a, 0x62, 0x62, 0x4e, 0x32, 0x44, + 0x61, 0x5c, 0x0a, + 0x09, 0x6a, 0x62, 0x72, 0x6c, 0x71, 0x6d, 0x32, 0x4d, 0x6a, 0x35, 0x6e, 0x72, 0x6c, 0x73, 0x74, 0x66, 0x67, + 0x49, 0x4c, 0x4f, 0x38, 0x4a, 0x69, 0x38, 0x52, 0x4d, 0x5a, 0x43, 0x4f, 0x45, 0x42, 0x68, 0x70, 0x2b, 0x6f, + 0x78, 0x51, 0x42, 0x73, 0x47, 0x41, 0x4c, 0x74, 0x33, 0x37, 0x63, 0x54, 0x30, 0x74, 0x6d, 0x31, 0x6e, 0x44, + 0x67, 0x61, 0x44, 0x6e, 0x6a, 0x59, 0x49, 0x37, 0x55, 0x6a, 0x56, 0x67, 0x56, 0x51, 0x42, 0x51, 0x32, 0x68, + 0x53, 0x5c, 0x0a, + 0x09, 0x2f, 0x31, 0x44, 0x4e, 0x42, 0x2f, 0x6e, 0x39, 0x32, 0x61, 0x67, 0x58, 0x53, 0x68, 0x58, 0x4b, 0x69, + 0x65, 0x38, 0x37, 0x30, 0x44, 0x77, 0x30, 0x52, 0x52, 0x65, 0x65, 0x65, 0x51, 0x41, 0x53, 0x77, 0x45, 0x51, + 0x35, 0x48, 0x68, 0x46, 0x56, 0x57, 0x34, 0x6e, 0x6a, 0x4b, 0x47, 0x42, 0x67, 0x46, 0x78, 0x41, 0x7a, 0x47, + 0x61, 0x54, 0x70, 0x4b, 0x75, 0x65, 0x4a, 0x5a, 0x7a, 0x4c, 0x57, 0x37, 0x63, 0x41, 0x49, 0x72, 0x6b, 0x5a, + 0x62, 0x5c, 0x0a, + 0x09, 0x47, 0x6f, 0x77, 0x30, 0x38, 0x65, 0x75, 0x57, 0x63, 0x77, 0x59, 0x2b, 0x39, 0x51, 0x4a, 0x64, 0x79, + 0x47, 0x62, 0x30, 0x75, 0x6f, 0x31, 0x31, 0x53, 0x7a, 0x63, 0x36, 0x75, 0x41, 0x59, 0x4d, 0x7a, 0x6a, 0x73, + 0x48, 0x4d, 0x53, 0x34, 0x72, 0x67, 0x72, 0x41, 0x5a, 0x49, 0x52, 0x73, 0x6c, 0x5a, 0x33, 0x45, 0x6e, 0x78, + 0x4c, 0x67, 0x74, 0x47, 0x63, 0x64, 0x70, 0x36, 0x45, 0x72, 0x76, 0x4d, 0x62, 0x48, 0x34, 0x34, 0x33, 0x71, + 0x6f, 0x5c, 0x0a, + 0x09, 0x32, 0x6e, 0x6a, 0x4d, 0x2b, 0x4d, 0x53, 0x45, 0x4b, 0x64, 0x66, 0x31, 0x70, 0x67, 0x30, 0x44, 0x67, + 0x4f, 0x50, 0x33, 0x37, 0x4d, 0x48, 0x6a, 0x4c, 0x33, 0x6a, 0x73, 0x43, 0x34, 0x4b, 0x44, 0x38, 0x73, 0x69, + 0x67, 0x68, 0x5a, 0x32, 0x67, 0x71, 0x6a, 0x50, 0x53, 0x78, 0x48, 0x68, 0x5a, 0x70, 0x5a, 0x30, 0x6b, 0x32, + 0x30, 0x6d, 0x69, 0x6d, 0x72, 0x38, 0x6f, 0x32, 0x32, 0x6c, 0x77, 0x43, 0x6c, 0x48, 0x4e, 0x4d, 0x48, 0x41, + 0x4f, 0x5c, 0x0a, + 0x09, 0x4c, 0x71, 0x48, 0x50, 0x30, 0x46, 0x36, 0x6f, 0x45, 0x78, 0x79, 0x41, 0x70, 0x36, 0x38, 0x36, 0x6b, + 0x77, 0x68, 0x31, 0x4e, 0x53, 0x44, 0x71, 0x4c, 0x43, 0x6e, 0x32, 0x79, 0x65, 0x65, 0x6c, 0x6b, 0x49, 0x62, + 0x4c, 0x78, 0x79, 0x53, 0x75, 0x51, 0x78, 0x70, 0x6e, 0x7a, 0x46, 0x67, 0x61, 0x35, 0x72, 0x38, 0x42, 0x52, + 0x4d, 0x58, 0x30, 0x78, 0x69, 0x6d, 0x6a, 0x48, 0x78, 0x58, 0x6c, 0x77, 0x58, 0x52, 0x4a, 0x64, 0x63, 0x51, + 0x55, 0x5c, 0x0a, + 0x09, 0x49, 0x4b, 0x4c, 0x6c, 0x59, 0x30, 0x52, 0x6c, 0x44, 0x57, 0x68, 0x61, 0x6a, 0x70, 0x46, 0x6e, 0x4a, + 0x2b, 0x58, 0x43, 0x65, 0x59, 0x33, 0x39, 0x45, 0x64, 0x4d, 0x70, 0x43, 0x78, 0x43, 0x68, 0x72, 0x4a, 0x55, + 0x74, 0x68, 0x54, 0x46, 0x70, 0x6e, 0x71, 0x4c, 0x4f, 0x4e, 0x4f, 0x41, 0x59, 0x2b, 0x48, 0x7a, 0x79, 0x33, + 0x6c, 0x4f, 0x66, 0x74, 0x48, 0x33, 0x48, 0x39, 0x76, 0x54, 0x43, 0x42, 0x74, 0x43, 0x47, 0x41, 0x63, 0x44, + 0x6b, 0x5c, 0x0a, + 0x09, 0x35, 0x41, 0x54, 0x4b, 0x30, 0x6a, 0x32, 0x4e, 0x70, 0x37, 0x61, 0x42, 0x74, 0x44, 0x4b, 0x6a, 0x34, + 0x54, 0x50, 0x48, 0x35, 0x32, 0x6d, 0x67, 0x46, 0x72, 0x70, 0x49, 0x44, 0x53, 0x73, 0x6e, 0x53, 0x56, 0x4a, + 0x78, 0x35, 0x63, 0x79, 0x36, 0x48, 0x2b, 0x46, 0x41, 0x54, 0x72, 0x59, 0x44, 0x79, 0x4f, 0x76, 0x43, 0x55, + 0x4e, 0x53, 0x55, 0x77, 0x42, 0x64, 0x4e, 0x39, 0x37, 0x43, 0x48, 0x65, 0x68, 0x62, 0x70, 0x31, 0x44, 0x67, + 0x59, 0x5c, 0x0a, + 0x09, 0x65, 0x58, 0x4c, 0x64, 0x53, 0x4d, 0x6d, 0x74, 0x7a, 0x49, 0x48, 0x4c, 0x69, 0x6e, 0x39, 0x76, 0x79, + 0x6d, 0x51, 0x53, 0x67, 0x41, 0x79, 0x38, 0x73, 0x6b, 0x7a, 0x4b, 0x57, 0x71, 0x77, 0x4d, 0x50, 0x46, 0x6c, + 0x5a, 0x56, 0x58, 0x51, 0x4f, 0x35, 0x78, 0x4a, 0x48, 0x45, 0x64, 0x47, 0x2b, 0x47, 0x72, 0x65, 0x51, 0x6e, + 0x5a, 0x37, 0x4b, 0x75, 0x56, 0x51, 0x58, 0x69, 0x61, 0x4f, 0x53, 0x4d, 0x55, 0x36, 0x6e, 0x78, 0x68, 0x68, + 0x41, 0x5c, 0x0a, + 0x09, 0x67, 0x6b, 0x38, 0x56, 0x48, 0x45, 0x52, 0x67, 0x34, 0x58, 0x62, 0x44, 0x36, 0x79, 0x53, 0x41, 0x77, + 0x36, 0x35, 0x72, 0x47, 0x65, 0x70, 0x73, 0x63, 0x38, 0x2f, 0x75, 0x33, 0x5a, 0x64, 0x73, 0x32, 0x62, 0x6f, + 0x31, 0x6b, 0x66, 0x46, 0x47, 0x30, 0x49, 0x59, 0x42, 0x77, 0x41, 0x4d, 0x50, 0x48, 0x73, 0x53, 0x39, 0x39, + 0x39, 0x33, 0x2f, 0x4d, 0x43, 0x73, 0x56, 0x42, 0x6c, 0x43, 0x6e, 0x37, 0x67, 0x68, 0x66, 0x70, 0x62, 0x46, + 0x77, 0x5c, 0x0a, + 0x09, 0x6c, 0x41, 0x37, 0x31, 0x64, 0x45, 0x53, 0x4c, 0x37, 0x55, 0x42, 0x47, 0x61, 0x2b, 0x36, 0x45, 0x58, + 0x4f, 0x47, 0x52, 0x42, 0x37, 0x34, 0x77, 0x78, 0x51, 0x77, 0x6b, 0x39, 0x73, 0x4d, 0x57, 0x7a, 0x54, 0x52, + 0x2f, 0x4e, 0x66, 0x74, 0x70, 0x52, 0x4e, 0x66, 0x54, 0x43, 0x6d, 0x73, 0x4f, 0x79, 0x69, 0x6e, 0x4a, 0x51, + 0x46, 0x43, 0x50, 0x57, 0x59, 0x39, 0x50, 0x72, 0x4e, 0x34, 0x7a, 0x2b, 0x56, 0x67, 0x72, 0x31, 0x4c, 0x78, + 0x2f, 0x5c, 0x0a, + 0x09, 0x6b, 0x58, 0x32, 0x6f, 0x73, 0x66, 0x4c, 0x32, 0x6d, 0x79, 0x6a, 0x4b, 0x4d, 0x67, 0x79, 0x66, 0x70, + 0x38, 0x54, 0x73, 0x72, 0x67, 0x44, 0x62, 0x44, 0x4a, 0x4f, 0x41, 0x31, 0x4b, 0x6a, 0x73, 0x4c, 0x2b, 0x48, + 0x62, 0x41, 0x6a, 0x2f, 0x6d, 0x32, 0x4b, 0x49, 0x65, 0x47, 0x32, 0x76, 0x67, 0x49, 0x2f, 0x52, 0x76, 0x38, + 0x52, 0x4c, 0x36, 0x53, 0x71, 0x61, 0x58, 0x50, 0x4e, 0x4e, 0x73, 0x34, 0x44, 0x4f, 0x5a, 0x45, 0x6f, 0x7a, + 0x49, 0x5c, 0x0a, + 0x09, 0x61, 0x67, 0x38, 0x66, 0x50, 0x6e, 0x4c, 0x6d, 0x31, 0x4d, 0x51, 0x34, 0x33, 0x76, 0x66, 0x37, 0x76, + 0x7a, 0x4e, 0x43, 0x73, 0x75, 0x74, 0x44, 0x47, 0x77, 0x49, 0x41, 0x2b, 0x2f, 0x66, 0x74, 0x77, 0x39, 0x61, + 0x78, 0x4c, 0x72, 0x35, 0x7a, 0x30, 0x38, 0x33, 0x48, 0x63, 0x61, 0x51, 0x56, 0x45, 0x64, 0x52, 0x4b, 0x38, + 0x56, 0x6d, 0x61, 0x5a, 0x74, 0x32, 0x43, 0x53, 0x64, 0x4a, 0x37, 0x6c, 0x52, 0x35, 0x7a, 0x35, 0x2b, 0x4e, + 0x52, 0x5c, 0x0a, + 0x09, 0x4e, 0x54, 0x71, 0x44, 0x45, 0x51, 0x47, 0x74, 0x61, 0x41, 0x68, 0x41, 0x5a, 0x42, 0x68, 0x4a, 0x4a, + 0x48, 0x42, 0x79, 0x47, 0x69, 0x4c, 0x4b, 0x4f, 0x64, 0x6b, 0x47, 0x54, 0x33, 0x48, 0x6a, 0x2b, 0x46, 0x56, + 0x47, 0x4a, 0x4d, 0x62, 0x4f, 0x32, 0x68, 0x64, 0x33, 0x51, 0x58, 0x6a, 0x4b, 0x54, 0x61, 0x69, 0x64, 0x55, + 0x6f, 0x68, 0x50, 0x4f, 0x70, 0x61, 0x49, 0x75, 0x4e, 0x62, 0x65, 0x41, 0x35, 0x31, 0x47, 0x68, 0x37, 0x6f, + 0x71, 0x5c, 0x0a, + 0x09, 0x79, 0x6e, 0x46, 0x77, 0x35, 0x65, 0x30, 0x4b, 0x48, 0x61, 0x6b, 0x70, 0x53, 0x42, 0x4b, 0x78, 0x6e, + 0x65, 0x4a, 0x42, 0x70, 0x66, 0x58, 0x43, 0x41, 0x63, 0x4d, 0x66, 0x5a, 0x42, 0x43, 0x6f, 0x32, 0x62, 0x5a, + 0x33, 0x57, 0x6f, 0x72, 0x70, 0x68, 0x61, 0x4c, 0x59, 0x4e, 0x38, 0x73, 0x4b, 0x64, 0x4a, 0x74, 0x4e, 0x78, + 0x39, 0x77, 0x47, 0x64, 0x53, 0x44, 0x67, 0x55, 0x35, 0x52, 0x41, 0x33, 0x37, 0x6e, 0x78, 0x78, 0x69, 0x31, + 0x50, 0x5c, 0x0a, + 0x09, 0x66, 0x66, 0x78, 0x6a, 0x74, 0x77, 0x2b, 0x47, 0x77, 0x34, 0x53, 0x50, 0x39, 0x61, 0x59, 0x4e, 0x65, + 0x78, 0x72, 0x77, 0x63, 0x31, 0x2f, 0x2b, 0x61, 0x76, 0x36, 0x33, 0x66, 0x2f, 0x69, 0x37, 0x4e, 0x2f, 0x55, + 0x36, 0x2b, 0x63, 0x50, 0x6d, 0x6c, 0x67, 0x5a, 0x77, 0x5a, 0x58, 0x41, 0x65, 0x59, 0x48, 0x5a, 0x78, 0x4b, + 0x5a, 0x59, 0x62, 0x44, 0x6b, 0x76, 0x4d, 0x4c, 0x79, 0x32, 0x68, 0x72, 0x4b, 0x34, 0x76, 0x46, 0x30, 0x4d, + 0x4d, 0x5c, 0x0a, + 0x09, 0x68, 0x6b, 0x56, 0x30, 0x75, 0x63, 0x48, 0x53, 0x4d, 0x67, 0x5a, 0x46, 0x43, 0x61, 0x72, 0x4f, 0x7a, + 0x43, 0x38, 0x73, 0x6f, 0x71, 0x79, 0x55, 0x57, 0x4a, 0x59, 0x6c, 0x35, 0x6c, 0x6c, 0x62, 0x79, 0x38, 0x74, + 0x44, 0x4c, 0x43, 0x37, 0x56, 0x33, 0x35, 0x65, 0x57, 0x68, 0x78, 0x67, 0x4d, 0x42, 0x74, 0x47, 0x41, 0x35, + 0x75, 0x62, 0x6e, 0x55, 0x52, 0x59, 0x46, 0x6e, 0x41, 0x4f, 0x49, 0x67, 0x45, 0x4d, 0x7a, 0x73, 0x77, 0x67, + 0x67, 0x5c, 0x0a, + 0x09, 0x50, 0x69, 0x79, 0x47, 0x4f, 0x48, 0x7a, 0x34, 0x63, 0x4b, 0x79, 0x37, 0x75, 0x4c, 0x43, 0x41, 0x75, + 0x62, 0x6b, 0x35, 0x4d, 0x61, 0x61, 0x59, 0x68, 0x61, 0x69, 0x35, 0x64, 0x48, 0x52, 0x38, 0x35, 0x70, 0x67, + 0x6d, 0x4d, 0x4c, 0x6d, 0x36, 0x72, 0x72, 0x55, 0x49, 0x47, 0x52, 0x32, 0x47, 0x4f, 0x7a, 0x75, 0x59, 0x6f, + 0x36, 0x6e, 0x73, 0x77, 0x4a, 0x70, 0x61, 0x4a, 0x53, 0x44, 0x41, 0x48, 0x4a, 0x53, 0x44, 0x56, 0x68, 0x49, + 0x74, 0x5c, 0x0a, + 0x09, 0x51, 0x33, 0x76, 0x4b, 0x6d, 0x5a, 0x74, 0x41, 0x51, 0x77, 0x41, 0x67, 0x79, 0x51, 0x7a, 0x4e, 0x6b, + 0x70, 0x6b, 0x41, 0x4f, 0x44, 0x59, 0x4f, 0x77, 0x5a, 0x2b, 0x65, 0x63, 0x71, 0x68, 0x73, 0x52, 0x54, 0x68, + 0x77, 0x77, 0x39, 0x68, 0x45, 0x39, 0x79, 0x34, 0x64, 0x6b, 0x78, 0x36, 0x7a, 0x6d, 0x4a, 0x71, 0x77, 0x65, + 0x6a, 0x47, 0x72, 0x41, 0x4e, 0x57, 0x50, 0x62, 0x37, 0x4f, 0x78, 0x43, 0x4f, 0x42, 0x6a, 0x33, 0x34, 0x6b, + 0x49, 0x5c, 0x0a, + 0x09, 0x77, 0x2b, 0x56, 0x6c, 0x7a, 0x43, 0x30, 0x75, 0x50, 0x64, 0x63, 0x35, 0x39, 0x33, 0x35, 0x73, 0x4d, + 0x47, 0x30, 0x59, 0x41, 0x4c, 0x7a, 0x6e, 0x39, 0x5a, 0x63, 0x57, 0x6a, 0x7a, 0x70, 0x74, 0x54, 0x38, 0x38, + 0x37, 0x42, 0x67, 0x39, 0x58, 0x4b, 0x6d, 0x77, 0x46, 0x62, 0x2f, 0x52, 0x66, 0x36, 0x6d, 0x76, 0x52, 0x43, + 0x49, 0x69, 0x56, 0x55, 0x64, 0x66, 0x6a, 0x74, 0x58, 0x42, 0x4a, 0x61, 0x54, 0x2f, 0x59, 0x62, 0x71, 0x4a, + 0x67, 0x5c, 0x0a, + 0x09, 0x48, 0x58, 0x31, 0x4a, 0x39, 0x73, 0x66, 0x72, 0x56, 0x39, 0x64, 0x6d, 0x6c, 0x35, 0x59, 0x78, 0x4c, + 0x46, 0x7a, 0x73, 0x64, 0x33, 0x5a, 0x68, 0x43, 0x61, 0x56, 0x7a, 0x49, 0x41, 0x4a, 0x4b, 0x42, 0x38, 0x77, + 0x74, 0x44, 0x6d, 0x4a, 0x7a, 0x79, 0x38, 0x4d, 0x53, 0x53, 0x38, 0x76, 0x4c, 0x6b, 0x64, 0x76, 0x42, 0x73, + 0x4d, 0x44, 0x53, 0x63, 0x68, 0x30, 0x4e, 0x35, 0x68, 0x61, 0x57, 0x55, 0x4a, 0x52, 0x6c, 0x2f, 0x44, 0x36, + 0x37, 0x5c, 0x0a, + 0x09, 0x34, 0x4e, 0x2f, 0x33, 0x34, 0x65, 0x44, 0x67, 0x53, 0x6f, 0x66, 0x35, 0x78, 0x53, 0x55, 0x51, 0x43, + 0x43, 0x57, 0x41, 0x34, 0x58, 0x43, 0x49, 0x70, 0x63, 0x46, 0x79, 0x4c, 0x4c, 0x75, 0x30, 0x50, 0x4d, 0x42, + 0x77, 0x57, 0x45, 0x59, 0x6e, 0x6d, 0x56, 0x39, 0x59, 0x51, 0x75, 0x6d, 0x4b, 0x79, 0x4f, 0x37, 0x63, 0x2f, + 0x45, 0x4a, 0x31, 0x6a, 0x56, 0x41, 0x55, 0x51, 0x79, 0x77, 0x73, 0x4c, 0x43, 0x49, 0x49, 0x59, 0x6d, 0x6d, + 0x77, 0x5c, 0x0a, + 0x09, 0x6a, 0x49, 0x58, 0x46, 0x4a, 0x53, 0x38, 0x75, 0x42, 0x38, 0x7a, 0x4e, 0x7a, 0x57, 0x4b, 0x77, 0x58, + 0x50, 0x4e, 0x39, 0x38, 0x4d, 0x47, 0x44, 0x63, 0x45, 0x56, 0x52, 0x4f, 0x77, 0x63, 0x48, 0x70, 0x67, 0x42, + 0x61, 0x37, 0x42, 0x56, 0x5a, 0x77, 0x68, 0x6b, 0x55, 0x79, 0x49, 0x56, 0x6a, 0x72, 0x6e, 0x4a, 0x72, 0x44, + 0x55, 0x4e, 0x48, 0x65, 0x50, 0x35, 0x64, 0x5a, 0x41, 0x6a, 0x47, 0x71, 0x6a, 0x32, 0x72, 0x56, 0x4b, 0x66, + 0x37, 0x5c, 0x0a, + 0x09, 0x55, 0x65, 0x65, 0x79, 0x54, 0x75, 0x67, 0x76, 0x38, 0x42, 0x55, 0x65, 0x43, 0x37, 0x65, 0x6d, 0x6d, + 0x4c, 0x77, 0x74, 0x76, 0x65, 0x61, 0x51, 0x54, 0x41, 0x63, 0x55, 0x6e, 0x32, 0x48, 0x4d, 0x52, 0x2b, 0x59, + 0x57, 0x6e, 0x6c, 0x61, 0x57, 0x35, 0x65, 0x59, 0x45, 0x67, 0x42, 0x74, 0x76, 0x76, 0x68, 0x6e, 0x6c, 0x74, + 0x5a, 0x39, 0x45, 0x72, 0x66, 0x32, 0x51, 0x39, 0x73, 0x6e, 0x30, 0x71, 0x58, 0x5a, 0x45, 0x46, 0x6a, 0x36, + 0x31, 0x5c, 0x0a, + 0x09, 0x49, 0x33, 0x4b, 0x41, 0x55, 0x4e, 0x67, 0x68, 0x79, 0x73, 0x58, 0x7a, 0x7a, 0x48, 0x45, 0x70, 0x57, + 0x41, 0x59, 0x48, 0x45, 0x46, 0x55, 0x50, 0x71, 0x6a, 0x2f, 0x42, 0x4a, 0x38, 0x58, 0x50, 0x4c, 0x58, 0x33, + 0x32, 0x49, 0x37, 0x42, 0x45, 0x32, 0x44, 0x62, 0x5a, 0x5a, 0x30, 0x79, 0x77, 0x44, 0x49, 0x43, 0x42, 0x52, + 0x74, 0x49, 0x75, 0x35, 0x30, 0x32, 0x54, 0x41, 0x44, 0x53, 0x53, 0x34, 0x30, 0x37, 0x6b, 0x45, 0x43, 0x4a, + 0x61, 0x5c, 0x0a, + 0x09, 0x51, 0x33, 0x6b, 0x68, 0x5a, 0x36, 0x4f, 0x74, 0x4f, 0x47, 0x37, 0x64, 0x66, 0x71, 0x79, 0x45, 0x34, + 0x62, 0x44, 0x41, 0x37, 0x47, 0x49, 0x4e, 0x50, 0x4d, 0x50, 0x53, 0x59, 0x58, 0x35, 0x70, 0x55, 0x48, 0x58, + 0x6c, 0x4d, 0x42, 0x67, 0x36, 0x78, 0x42, 0x54, 0x58, 0x4f, 0x63, 0x77, 0x50, 0x43, 0x78, 0x54, 0x44, 0x49, + 0x72, 0x5a, 0x34, 0x5a, 0x4b, 0x48, 0x4f, 0x78, 0x41, 0x72, 0x6e, 0x63, 0x47, 0x52, 0x75, 0x41, 0x56, 0x6e, + 0x46, 0x5c, 0x0a, + 0x09, 0x77, 0x32, 0x42, 0x59, 0x59, 0x48, 0x46, 0x70, 0x43, 0x5a, 0x52, 0x6c, 0x63, 0x48, 0x42, 0x59, 0x57, + 0x68, 0x78, 0x67, 0x75, 0x58, 0x53, 0x67, 0x79, 0x73, 0x46, 0x6d, 0x46, 0x78, 0x61, 0x72, 0x5a, 0x6e, 0x33, + 0x36, 0x50, 0x56, 0x64, 0x39, 0x4a, 0x79, 0x49, 0x4d, 0x79, 0x78, 0x49, 0x4c, 0x38, 0x77, 0x74, 0x52, 0x74, + 0x6f, 0x50, 0x42, 0x41, 0x45, 0x75, 0x44, 0x49, 0x59, 0x49, 0x65, 0x46, 0x78, 0x65, 0x57, 0x4d, 0x43, 0x79, + 0x57, 0x5c, 0x0a, + 0x09, 0x34, 0x35, 0x41, 0x50, 0x48, 0x35, 0x36, 0x4e, 0x57, 0x69, 0x2f, 0x4c, 0x45, 0x6f, 0x64, 0x6d, 0x44, + 0x6b, 0x57, 0x2b, 0x6c, 0x68, 0x61, 0x58, 0x4d, 0x44, 0x63, 0x37, 0x6d, 0x32, 0x52, 0x67, 0x31, 0x6e, 0x71, + 0x41, 0x58, 0x67, 0x67, 0x4d, 0x41, 0x43, 0x4c, 0x71, 0x6b, 0x6f, 0x74, 0x54, 0x6b, 0x41, 0x64, 0x6d, 0x5a, + 0x73, 0x37, 0x64, 0x64, 0x38, 0x49, 0x65, 0x62, 0x44, 0x52, 0x74, 0x37, 0x41, 0x74, 0x42, 0x6f, 0x6f, 0x4d, + 0x72, 0x5c, 0x0a, + 0x09, 0x4a, 0x77, 0x33, 0x61, 0x30, 0x63, 0x36, 0x42, 0x63, 0x4b, 0x34, 0x43, 0x44, 0x65, 0x35, 0x4d, 0x78, + 0x4f, 0x71, 0x48, 0x6c, 0x4c, 0x4c, 0x4a, 0x53, 0x65, 0x4b, 0x70, 0x32, 0x6f, 0x46, 0x54, 0x50, 0x6d, 0x53, + 0x30, 0x53, 0x48, 0x68, 0x75, 0x41, 0x67, 0x54, 0x6e, 0x6d, 0x72, 0x4d, 0x54, 0x6e, 0x6c, 0x68, 0x77, 0x45, + 0x42, 0x44, 0x6a, 0x55, 0x33, 0x30, 0x78, 0x6b, 0x4c, 0x45, 0x64, 0x31, 0x53, 0x41, 0x75, 0x45, 0x33, 0x34, + 0x75, 0x5c, 0x0a, + 0x09, 0x36, 0x64, 0x73, 0x59, 0x72, 0x35, 0x41, 0x46, 0x42, 0x38, 0x6a, 0x36, 0x4b, 0x77, 0x42, 0x30, 0x38, + 0x67, 0x7a, 0x62, 0x74, 0x6f, 0x7a, 0x4a, 0x38, 0x57, 0x38, 0x64, 0x47, 0x79, 0x32, 0x58, 0x55, 0x61, 0x43, + 0x55, 0x6b, 0x4f, 0x6f, 0x62, 0x51, 0x4d, 0x4b, 0x4c, 0x47, 0x49, 0x73, 0x78, 0x7a, 0x67, 0x51, 0x55, 0x6d, + 0x77, 0x45, 0x74, 0x37, 0x56, 0x36, 0x42, 0x4a, 0x49, 0x44, 0x35, 0x78, 0x57, 0x55, 0x4d, 0x68, 0x76, 0x55, + 0x62, 0x5c, 0x0a, + 0x09, 0x76, 0x57, 0x61, 0x58, 0x42, 0x69, 0x68, 0x4c, 0x46, 0x35, 0x73, 0x39, 0x73, 0x6a, 0x43, 0x49, 0x2f, + 0x52, 0x52, 0x6c, 0x69, 0x59, 0x55, 0x6c, 0x6c, 0x75, 0x55, 0x56, 0x70, 0x63, 0x6a, 0x55, 0x43, 0x44, 0x51, + 0x33, 0x58, 0x4b, 0x35, 0x42, 0x63, 0x4b, 0x4e, 0x6f, 0x59, 0x77, 0x46, 0x41, 0x4f, 0x33, 0x77, 0x38, 0x62, + 0x36, 0x54, 0x6b, 0x4f, 0x72, 0x6f, 0x35, 0x64, 0x69, 0x30, 0x30, 0x35, 0x69, 0x70, 0x67, 0x69, 0x44, 0x62, + 0x63, 0x5c, 0x0a, + 0x09, 0x45, 0x47, 0x6d, 0x62, 0x70, 0x68, 0x56, 0x31, 0x41, 0x58, 0x2b, 0x4f, 0x70, 0x62, 0x4f, 0x4e, 0x66, + 0x41, 0x53, 0x6e, 0x64, 0x66, 0x77, 0x36, 0x64, 0x36, 0x36, 0x6d, 0x63, 0x52, 0x6e, 0x47, 0x6d, 0x66, 0x43, + 0x6c, 0x2b, 0x75, 0x56, 0x6c, 0x74, 0x49, 0x79, 0x73, 0x38, 0x51, 0x6e, 0x6e, 0x45, 0x53, 0x6d, 0x49, 0x71, + 0x6b, 0x38, 0x31, 0x50, 0x31, 0x61, 0x6d, 0x45, 0x61, 0x73, 0x62, 0x63, 0x75, 0x4b, 0x4f, 0x71, 0x49, 0x6b, + 0x44, 0x5c, 0x0a, + 0x09, 0x59, 0x67, 0x52, 0x42, 0x42, 0x73, 0x36, 0x69, 0x4b, 0x65, 0x33, 0x6f, 0x58, 0x41, 0x61, 0x42, 0x48, + 0x79, 0x55, 0x66, 0x44, 0x58, 0x44, 0x4f, 0x70, 0x58, 0x71, 0x78, 0x35, 0x41, 0x4e, 0x57, 0x52, 0x76, 0x52, + 0x50, 0x71, 0x61, 0x78, 0x5a, 0x6d, 0x59, 0x6d, 0x78, 0x44, 0x69, 0x5a, 0x51, 0x5a, 0x33, 0x6f, 0x52, 0x41, + 0x48, 0x6e, 0x39, 0x5a, 0x45, 0x79, 0x47, 0x58, 0x50, 0x7a, 0x59, 0x70, 0x2b, 0x2b, 0x64, 0x6d, 0x55, 0x75, + 0x76, 0x5c, 0x0a, + 0x09, 0x72, 0x54, 0x4e, 0x74, 0x2f, 0x4e, 0x4f, 0x41, 0x7a, 0x6a, 0x72, 0x68, 0x36, 0x67, 0x73, 0x6d, 0x4f, + 0x4b, 0x6a, 0x76, 0x50, 0x45, 0x72, 0x47, 0x36, 0x38, 0x79, 0x6f, 0x2b, 0x58, 0x58, 0x74, 0x65, 0x4e, 0x6f, + 0x49, 0x49, 0x6b, 0x2f, 0x42, 0x75, 0x42, 0x73, 0x69, 0x42, 0x4f, 0x64, 0x44, 0x4f, 0x49, 0x65, 0x4b, 0x39, + 0x4e, 0x48, 0x6f, 0x64, 0x63, 0x51, 0x33, 0x49, 0x6a, 0x4c, 0x6e, 0x53, 0x7a, 0x75, 0x63, 0x35, 0x54, 0x44, + 0x4a, 0x5c, 0x0a, + 0x09, 0x64, 0x33, 0x56, 0x4f, 0x31, 0x46, 0x65, 0x66, 0x73, 0x52, 0x2b, 0x64, 0x68, 0x57, 0x6c, 0x67, 0x67, + 0x58, 0x49, 0x49, 0x73, 0x50, 0x47, 0x6f, 0x66, 0x70, 0x7a, 0x53, 0x47, 0x79, 0x44, 0x6c, 0x7a, 0x38, 0x48, + 0x53, 0x36, 0x6b, 0x75, 0x6d, 0x63, 0x59, 0x62, 0x75, 0x36, 0x4f, 0x68, 0x34, 0x31, 0x74, 0x6b, 0x4c, 0x58, + 0x43, 0x72, 0x37, 0x41, 0x4e, 0x68, 0x78, 0x50, 0x4b, 0x78, 0x50, 0x70, 0x38, 0x76, 0x7a, 0x65, 0x73, 0x36, + 0x57, 0x5c, 0x0a, + 0x09, 0x4e, 0x52, 0x38, 0x7a, 0x31, 0x37, 0x6c, 0x46, 0x50, 0x67, 0x76, 0x64, 0x76, 0x6e, 0x74, 0x36, 0x30, + 0x72, 0x36, 0x2b, 0x6a, 0x72, 0x51, 0x68, 0x41, 0x46, 0x42, 0x65, 0x39, 0x79, 0x6c, 0x2f, 0x34, 0x4c, 0x41, + 0x72, 0x47, 0x6c, 0x69, 0x6b, 0x59, 0x46, 0x68, 0x4d, 0x75, 0x55, 0x6d, 0x71, 0x48, 0x42, 0x77, 0x62, 0x78, + 0x6a, 0x57, 0x4c, 0x48, 0x46, 0x50, 0x63, 0x69, 0x45, 0x78, 0x44, 0x6e, 0x47, 0x38, 0x77, 0x65, 0x74, 0x45, + 0x73, 0x5c, 0x0a, + 0x09, 0x7a, 0x79, 0x37, 0x59, 0x39, 0x63, 0x43, 0x58, 0x63, 0x4f, 0x51, 0x52, 0x42, 0x74, 0x48, 0x49, 0x41, + 0x2b, 0x38, 0x44, 0x6f, 0x39, 0x76, 0x51, 0x77, 0x46, 0x68, 0x66, 0x73, 0x48, 0x6b, 0x4d, 0x55, 0x56, 0x44, + 0x49, 0x6b, 0x48, 0x32, 0x4f, 0x54, 0x4d, 0x31, 0x5a, 0x30, 0x30, 0x6b, 0x78, 0x72, 0x53, 0x39, 0x49, 0x47, + 0x65, 0x72, 0x49, 0x48, 0x4d, 0x34, 0x6e, 0x71, 0x62, 0x7a, 0x69, 0x79, 0x30, 0x72, 0x7a, 0x4c, 0x64, 0x33, + 0x48, 0x5c, 0x0a, + 0x09, 0x61, 0x36, 0x78, 0x73, 0x62, 0x4d, 0x59, 0x70, 0x6e, 0x59, 0x6d, 0x43, 0x61, 0x54, 0x75, 0x36, 0x6a, + 0x41, 0x42, 0x70, 0x33, 0x54, 0x2f, 0x59, 0x47, 0x42, 0x72, 0x73, 0x68, 0x48, 0x39, 0x33, 0x4f, 0x43, 0x62, + 0x32, 0x41, 0x6d, 0x39, 0x63, 0x42, 0x6b, 0x41, 0x30, 0x44, 0x61, 0x49, 0x4a, 0x30, 0x32, 0x69, 0x31, 0x59, + 0x2f, 0x50, 0x30, 0x6b, 0x59, 0x4f, 0x44, 0x6b, 0x48, 0x58, 0x34, 0x6f, 0x6f, 0x77, 0x4e, 0x67, 0x4f, 0x30, + 0x59, 0x5c, 0x0a, + 0x09, 0x52, 0x6b, 0x6a, 0x55, 0x45, 0x56, 0x64, 0x48, 0x68, 0x74, 0x69, 0x75, 0x63, 0x53, 0x36, 0x65, 0x5a, + 0x75, 0x41, 0x52, 0x77, 0x43, 0x33, 0x77, 0x49, 0x69, 0x49, 0x4c, 0x34, 0x35, 0x4d, 0x37, 0x67, 0x4a, 0x34, + 0x47, 0x69, 0x44, 0x6e, 0x35, 0x55, 0x59, 0x41, 0x58, 0x35, 0x7a, 0x6c, 0x78, 0x49, 0x41, 0x57, 0x30, 0x6e, + 0x46, 0x63, 0x6f, 0x65, 0x65, 0x6b, 0x6f, 0x79, 0x79, 0x6b, 0x42, 0x62, 0x41, 0x4e, 0x34, 0x7a, 0x54, 0x48, + 0x55, 0x5c, 0x0a, + 0x09, 0x70, 0x2b, 0x6f, 0x2b, 0x57, 0x56, 0x6e, 0x64, 0x4c, 0x6e, 0x63, 0x32, 0x72, 0x51, 0x64, 0x72, 0x47, + 0x68, 0x54, 0x62, 0x56, 0x33, 0x32, 0x47, 0x73, 0x6b, 0x45, 0x6e, 0x6b, 0x74, 0x48, 0x6d, 0x66, 0x76, 0x6b, + 0x35, 0x33, 0x62, 0x62, 0x51, 0x72, 0x52, 0x35, 0x44, 0x51, 0x79, 0x43, 0x53, 0x41, 0x4c, 0x63, 0x46, 0x59, + 0x4d, 0x46, 0x77, 0x67, 0x32, 0x69, 0x44, 0x41, 0x4d, 0x41, 0x42, 0x77, 0x44, 0x34, 0x5a, 0x47, 0x56, 0x53, + 0x55, 0x5c, 0x0a, + 0x09, 0x74, 0x70, 0x51, 0x67, 0x55, 0x6c, 0x47, 0x65, 0x68, 0x6d, 0x6f, 0x48, 0x68, 0x42, 0x31, 0x52, 0x64, + 0x48, 0x74, 0x4e, 0x55, 0x34, 0x42, 0x51, 0x33, 0x34, 0x71, 0x71, 0x31, 0x68, 0x77, 0x39, 0x47, 0x70, 0x5a, + 0x79, 0x61, 0x6a, 0x46, 0x6b, 0x70, 0x77, 0x78, 0x51, 0x47, 0x58, 0x49, 0x79, 0x39, 0x32, 0x52, 0x64, 0x4a, + 0x46, 0x6b, 0x51, 0x30, 0x75, 0x2f, 0x6d, 0x32, 0x42, 0x53, 0x66, 0x76, 0x47, 0x37, 0x53, 0x48, 0x6d, 0x74, + 0x54, 0x5c, 0x0a, + 0x09, 0x67, 0x34, 0x67, 0x77, 0x63, 0x70, 0x4a, 0x31, 0x4c, 0x48, 0x36, 0x53, 0x39, 0x51, 0x57, 0x6a, 0x6e, + 0x42, 0x55, 0x70, 0x56, 0x79, 0x4b, 0x52, 0x7a, 0x75, 0x74, 0x78, 0x4b, 0x54, 0x6c, 0x71, 0x33, 0x69, 0x30, + 0x51, 0x31, 0x4b, 0x44, 0x4f, 0x78, 0x78, 0x41, 0x7a, 0x4f, 0x42, 0x58, 0x39, 0x64, 0x5a, 0x51, 0x33, 0x70, + 0x32, 0x6b, 0x4b, 0x61, 0x44, 0x52, 0x66, 0x39, 0x65, 0x65, 0x57, 0x6f, 0x78, 0x2f, 0x38, 0x32, 0x74, 0x41, + 0x47, 0x5c, 0x0a, + 0x09, 0x4c, 0x67, 0x4b, 0x36, 0x30, 0x36, 0x76, 0x50, 0x46, 0x61, 0x4b, 0x46, 0x53, 0x34, 0x57, 0x63, 0x52, + 0x47, 0x4e, 0x4b, 0x73, 0x77, 0x62, 0x64, 0x68, 0x6a, 0x79, 0x42, 0x6b, 0x5a, 0x45, 0x74, 0x53, 0x66, 0x63, + 0x5a, 0x77, 0x46, 0x44, 0x31, 0x58, 0x39, 0x4b, 0x45, 0x6b, 0x53, 0x48, 0x77, 0x4d, 0x57, 0x6c, 0x6a, 0x6a, + 0x45, 0x59, 0x52, 0x32, 0x41, 0x6c, 0x5a, 0x44, 0x6c, 0x49, 0x5a, 0x61, 0x4e, 0x34, 0x41, 0x32, 0x2f, 0x41, + 0x69, 0x5c, 0x0a, + 0x09, 0x61, 0x4c, 0x6d, 0x61, 0x54, 0x38, 0x32, 0x54, 0x6c, 0x70, 0x2b, 0x4f, 0x6c, 0x4d, 0x6e, 0x69, 0x4a, + 0x43, 0x54, 0x49, 0x6a, 0x73, 0x71, 0x45, 0x4c, 0x48, 0x36, 0x45, 0x34, 0x54, 0x4f, 0x65, 0x52, 0x70, 0x49, + 0x6c, 0x42, 0x30, 0x73, 0x2b, 0x42, 0x6f, 0x43, 0x62, 0x59, 0x31, 0x50, 0x38, 0x38, 0x4c, 0x46, 0x79, 0x2f, + 0x71, 0x33, 0x79, 0x31, 0x68, 0x68, 0x58, 0x6b, 0x68, 0x2f, 0x50, 0x31, 0x71, 0x7a, 0x2b, 0x36, 0x75, 0x75, + 0x39, 0x5c, 0x0a, + 0x09, 0x78, 0x6d, 0x78, 0x68, 0x6e, 0x57, 0x68, 0x6a, 0x4d, 0x67, 0x41, 0x48, 0x41, 0x48, 0x53, 0x36, 0x76, + 0x62, 0x41, 0x54, 0x79, 0x68, 0x69, 0x43, 0x73, 0x2b, 0x62, 0x68, 0x56, 0x6e, 0x53, 0x4d, 0x4b, 0x52, 0x6f, + 0x67, 0x6c, 0x47, 0x6d, 0x68, 0x74, 0x35, 0x6d, 0x2b, 0x68, 0x6e, 0x6f, 0x47, 0x6f, 0x6f, 0x76, 0x69, 0x54, + 0x56, 0x47, 0x65, 0x32, 0x47, 0x55, 0x56, 0x33, 0x66, 0x6e, 0x31, 0x6b, 0x4d, 0x48, 0x6f, 0x72, 0x45, 0x41, + 0x62, 0x5c, 0x0a, + 0x09, 0x72, 0x4a, 0x6d, 0x5a, 0x71, 0x4d, 0x69, 0x73, 0x78, 0x38, 0x4a, 0x5a, 0x30, 0x2f, 0x4e, 0x2b, 0x6e, + 0x6b, 0x47, 0x6c, 0x68, 0x5a, 0x56, 0x4d, 0x57, 0x43, 0x5a, 0x6b, 0x79, 0x54, 0x36, 0x4d, 0x75, 0x30, 0x6b, + 0x47, 0x41, 0x71, 0x68, 0x59, 0x57, 0x52, 0x48, 0x4e, 0x46, 0x57, 0x6d, 0x67, 0x45, 0x57, 0x6b, 0x2f, 0x36, + 0x38, 0x64, 0x63, 0x77, 0x41, 0x30, 0x79, 0x30, 0x65, 0x56, 0x34, 0x47, 0x2b, 0x46, 0x69, 0x4f, 0x4f, 0x39, + 0x73, 0x5c, 0x0a, + 0x09, 0x32, 0x54, 0x56, 0x6c, 0x42, 0x6e, 0x72, 0x38, 0x34, 0x54, 0x77, 0x76, 0x7a, 0x36, 0x64, 0x7a, 0x77, + 0x5a, 0x36, 0x43, 0x50, 0x64, 0x52, 0x5a, 0x7a, 0x4e, 0x51, 0x47, 0x2b, 0x2f, 0x38, 0x47, 0x72, 0x67, 0x47, + 0x34, 0x4b, 0x67, 0x50, 0x51, 0x63, 0x79, 0x70, 0x5a, 0x70, 0x6a, 0x70, 0x6f, 0x53, 0x4c, 0x64, 0x34, 0x78, + 0x4c, 0x49, 0x51, 0x50, 0x79, 0x34, 0x6f, 0x38, 0x6e, 0x50, 0x36, 0x32, 0x43, 0x49, 0x79, 0x6c, 0x47, 0x58, + 0x31, 0x5c, 0x0a, + 0x09, 0x7a, 0x66, 0x6f, 0x7a, 0x35, 0x35, 0x32, 0x73, 0x72, 0x4a, 0x56, 0x65, 0x78, 0x71, 0x48, 0x70, 0x79, + 0x4b, 0x54, 0x4b, 0x63, 0x79, 0x42, 0x4c, 0x30, 0x6b, 0x78, 0x74, 0x6b, 0x44, 0x78, 0x4b, 0x47, 0x76, 0x31, + 0x59, 0x36, 0x79, 0x4a, 0x6d, 0x5a, 0x46, 0x65, 0x5a, 0x69, 0x77, 0x57, 0x79, 0x76, 0x46, 0x79, 0x55, 0x43, + 0x32, 0x74, 0x44, 0x4f, 0x30, 0x51, 0x43, 0x44, 0x41, 0x5a, 0x77, 0x38, 0x62, 0x61, 0x35, 0x6a, 0x71, 0x55, + 0x77, 0x5c, 0x0a, + 0x09, 0x5a, 0x42, 0x6b, 0x7a, 0x4b, 0x32, 0x4a, 0x74, 0x72, 0x5a, 0x67, 0x5a, 0x47, 0x74, 0x48, 0x61, 0x79, + 0x73, 0x4b, 0x53, 0x39, 0x6c, 0x52, 0x67, 0x69, 0x67, 0x6b, 0x41, 0x41, 0x2f, 0x70, 0x67, 0x4f, 0x31, 0x77, + 0x6e, 0x39, 0x52, 0x72, 0x57, 0x75, 0x4e, 0x33, 0x4a, 0x2b, 0x74, 0x46, 0x47, 0x37, 0x67, 0x4d, 0x34, 0x45, + 0x59, 0x42, 0x43, 0x34, 0x34, 0x71, 0x73, 0x46, 0x46, 0x4a, 0x2f, 0x4d, 0x6d, 0x45, 0x75, 0x4c, 0x51, 0x39, + 0x78, 0x5c, 0x0a, + 0x09, 0x33, 0x2b, 0x46, 0x35, 0x50, 0x48, 0x42, 0x6b, 0x48, 0x6f, 0x64, 0x6d, 0x46, 0x33, 0x48, 0x6f, 0x79, + 0x42, 0x7a, 0x6d, 0x6c, 0x35, 0x61, 0x77, 0x74, 0x44, 0x7a, 0x45, 0x77, 0x75, 0x49, 0x41, 0x73, 0x77, 0x75, + 0x4c, 0x47, 0x41, 0x79, 0x47, 0x47, 0x41, 0x79, 0x58, 0x77, 0x66, 0x66, 0x6f, 0x4c, 0x79, 0x77, 0x75, 0x6f, + 0x53, 0x6a, 0x38, 0x78, 0x6f, 0x34, 0x38, 0x7a, 0x7a, 0x45, 0x2b, 0x78, 0x6e, 0x66, 0x76, 0x41, 0x55, 0x53, + 0x45, 0x5c, 0x0a, + 0x09, 0x79, 0x66, 0x45, 0x78, 0x67, 0x49, 0x41, 0x38, 0x79, 0x7a, 0x44, 0x65, 0x37, 0x77, 0x45, 0x41, 0x2b, + 0x74, 0x30, 0x75, 0x4f, 0x74, 0x30, 0x63, 0x6e, 0x62, 0x79, 0x44, 0x69, 0x56, 0x34, 0x58, 0x52, 0x49, 0x53, + 0x74, 0x45, 0x2f, 0x36, 0x65, 0x38, 0x48, 0x69, 0x2f, 0x69, 0x30, 0x36, 0x57, 0x6f, 0x64, 0x66, 0x74, 0x6f, + 0x4e, 0x66, 0x4a, 0x30, 0x65, 0x39, 0x32, 0x30, 0x4f, 0x74, 0x6b, 0x47, 0x4f, 0x2f, 0x31, 0x30, 0x4d, 0x6e, + 0x39, 0x5c, 0x0a, + 0x09, 0x6a, 0x73, 0x46, 0x4f, 0x7a, 0x6e, 0x48, 0x58, 0x41, 0x44, 0x32, 0x52, 0x79, 0x6a, 0x4f, 0x6a, 0x34, + 0x58, 0x4e, 0x7a, 0x71, 0x36, 0x34, 0x34, 0x48, 0x51, 0x7a, 0x4e, 0x32, 0x57, 0x56, 0x6a, 0x57, 0x7a, 0x78, + 0x6a, 0x63, 0x63, 0x70, 0x6f, 0x6c, 0x52, 0x35, 0x30, 0x50, 0x5a, 0x4d, 0x48, 0x42, 0x6e, 0x79, 0x31, 0x49, + 0x41, 0x30, 0x6d, 0x58, 0x66, 0x31, 0x42, 0x68, 0x50, 0x6d, 0x6c, 0x5a, 0x51, 0x79, 0x57, 0x43, 0x79, 0x77, + 0x4d, 0x5c, 0x0a, + 0x09, 0x68, 0x6c, 0x67, 0x75, 0x43, 0x73, 0x77, 0x76, 0x44, 0x56, 0x41, 0x36, 0x59, 0x48, 0x62, 0x52, 0x62, + 0x36, 0x36, 0x5a, 0x57, 0x31, 0x78, 0x43, 0x36, 0x59, 0x41, 0x6a, 0x38, 0x34, 0x74, 0x77, 0x7a, 0x75, 0x46, + 0x49, 0x74, 0x61, 0x56, 0x35, 0x66, 0x6e, 0x45, 0x51, 0x74, 0x30, 0x51, 0x50, 0x6c, 0x6f, 0x64, 0x77, 0x7a, + 0x6d, 0x46, 0x68, 0x30, 0x57, 0x2f, 0x44, 0x39, 0x75, 0x7a, 0x36, 0x54, 0x2f, 0x2b, 0x4d, 0x69, 0x41, 0x65, + 0x4c, 0x5c, 0x0a, + 0x09, 0x4c, 0x4d, 0x73, 0x78, 0x4d, 0x64, 0x36, 0x76, 0x57, 0x50, 0x50, 0x62, 0x6d, 0x4d, 0x66, 0x37, 0x50, + 0x66, 0x52, 0x36, 0x58, 0x59, 0x7a, 0x31, 0x2b, 0x39, 0x67, 0x79, 0x33, 0x6b, 0x65, 0x2f, 0x32, 0x38, 0x56, + 0x34, 0x76, 0x34, 0x74, 0x74, 0x57, 0x79, 0x61, 0x77, 0x66, 0x63, 0x73, 0x45, 0x64, 0x6d, 0x77, 0x64, 0x78, + 0x2b, 0x37, 0x70, 0x53, 0x66, 0x54, 0x79, 0x54, 0x4e, 0x71, 0x73, 0x6d, 0x48, 0x59, 0x41, 0x69, 0x5a, 0x50, + 0x48, 0x5c, 0x0a, + 0x09, 0x6f, 0x6b, 0x70, 0x2f, 0x76, 0x73, 0x35, 0x55, 0x49, 0x7a, 0x69, 0x74, 0x45, 0x32, 0x30, 0x6b, 0x41, + 0x42, 0x78, 0x76, 0x6e, 0x68, 0x57, 0x6f, 0x37, 0x35, 0x53, 0x64, 0x4f, 0x63, 0x7a, 0x4d, 0x4c, 0x2b, 0x45, + 0x72, 0x4e, 0x39, 0x79, 0x42, 0x61, 0x32, 0x36, 0x38, 0x46, 0x54, 0x66, 0x63, 0x65, 0x67, 0x64, 0x75, 0x76, + 0x4f, 0x6c, 0x57, 0x33, 0x48, 0x54, 0x54, 0x54, 0x52, 0x67, 0x4f, 0x6c, 0x36, 0x4e, 0x4e, 0x4a, 0x58, 0x76, + 0x4e, 0x5c, 0x0a, + 0x09, 0x41, 0x61, 0x55, 0x54, 0x75, 0x61, 0x56, 0x54, 0x50, 0x48, 0x52, 0x53, 0x39, 0x52, 0x57, 0x33, 0x63, + 0x61, 0x72, 0x67, 0x6e, 0x7a, 0x77, 0x41, 0x34, 0x79, 0x6f, 0x6a, 0x71, 0x73, 0x37, 0x78, 0x65, 0x76, 0x70, + 0x68, 0x6e, 0x48, 0x42, 0x74, 0x79, 0x35, 0x61, 0x74, 0x6d, 0x4e, 0x34, 0x32, 0x6a, 0x61, 0x6d, 0x74, 0x57, + 0x37, 0x46, 0x39, 0x32, 0x7a, 0x53, 0x6d, 0x70, 0x37, 0x5a, 0x69, 0x65, 0x75, 0x73, 0x55, 0x64, 0x6b, 0x78, + 0x76, 0x5c, 0x0a, + 0x09, 0x77, 0x61, 0x37, 0x74, 0x57, 0x37, 0x48, 0x6e, 0x75, 0x4f, 0x30, 0x34, 0x59, 0x66, 0x73, 0x57, 0x37, + 0x4e, 0x32, 0x35, 0x48, 0x56, 0x73, 0x6e, 0x75, 0x6b, 0x67, 0x4d, 0x7a, 0x5a, 0x77, 0x6a, 0x73, 0x33, 0x4d, + 0x38, 0x36, 0x6f, 0x2b, 0x63, 0x72, 0x34, 0x34, 0x67, 0x37, 0x65, 0x6a, 0x4a, 0x66, 0x4e, 0x77, 0x67, 0x55, + 0x59, 0x52, 0x77, 0x78, 0x77, 0x4e, 0x48, 0x63, 0x4f, 0x65, 0x44, 0x4d, 0x37, 0x6a, 0x72, 0x67, 0x52, 0x6e, + 0x63, 0x5c, 0x0a, + 0x09, 0x65, 0x2b, 0x67, 0x49, 0x37, 0x6a, 0x73, 0x34, 0x67, 0x35, 0x6b, 0x6a, 0x63, 0x35, 0x69, 0x5a, 0x6e, + 0x63, 0x57, 0x68, 0x51, 0x7a, 0x4f, 0x59, 0x6d, 0x54, 0x6d, 0x43, 0x67, 0x34, 0x63, 0x4f, 0x59, 0x75, 0x62, + 0x67, 0x51, 0x51, 0x79, 0x48, 0x42, 0x66, 0x51, 0x65, 0x66, 0x76, 0x36, 0x77, 0x6b, 0x33, 0x34, 0x71, 0x30, + 0x48, 0x6f, 0x49, 0x43, 0x57, 0x52, 0x38, 0x52, 0x74, 0x5a, 0x59, 0x75, 0x35, 0x44, 0x62, 0x64, 0x4a, 0x4d, + 0x45, 0x5c, 0x0a, + 0x09, 0x6f, 0x36, 0x71, 0x72, 0x37, 0x61, 0x54, 0x62, 0x36, 0x32, 0x4c, 0x66, 0x76, 0x74, 0x4e, 0x77, 0x2b, + 0x72, 0x35, 0x54, 0x63, 0x57, 0x44, 0x76, 0x53, 0x54, 0x68, 0x6e, 0x2f, 0x36, 0x6e, 0x34, 0x6e, 0x67, 0x4d, + 0x6e, 0x59, 0x57, 0x71, 0x38, 0x70, 0x79, 0x49, 0x2b, 0x55, 0x47, 0x38, 0x7a, 0x44, 0x32, 0x30, 0x36, 0x32, + 0x59, 0x48, 0x58, 0x31, 0x59, 0x34, 0x56, 0x39, 0x62, 0x44, 0x47, 0x74, 0x48, 0x45, 0x41, 0x51, 0x42, 0x59, + 0x41, 0x5c, 0x0a, + 0x09, 0x63, 0x43, 0x4f, 0x56, 0x47, 0x63, 0x46, 0x31, 0x74, 0x39, 0x2b, 0x50, 0x39, 0x2f, 0x33, 0x64, 0x5a, + 0x66, 0x6a, 0x6e, 0x54, 0x31, 0x77, 0x57, 0x6e, 0x54, 0x31, 0x35, 0x53, 0x6b, 0x73, 0x72, 0x54, 0x54, 0x6c, + 0x38, 0x31, 0x4c, 0x65, 0x31, 0x54, 0x39, 0x75, 0x6c, 0x44, 0x35, 0x30, 0x41, 0x7a, 0x50, 0x69, 0x55, 0x51, + 0x66, 0x45, 0x2b, 0x4f, 0x59, 0x43, 0x45, 0x2f, 0x64, 0x36, 0x38, 0x37, 0x33, 0x6f, 0x59, 0x33, 0x71, 0x6e, + 0x6d, 0x5c, 0x0a, + 0x09, 0x5a, 0x6d, 0x63, 0x78, 0x65, 0x2b, 0x51, 0x49, 0x37, 0x6f, 0x68, 0x42, 0x50, 0x6a, 0x58, 0x71, 0x77, + 0x4e, 0x2f, 0x70, 0x70, 0x2b, 0x2f, 0x48, 0x67, 0x66, 0x32, 0x6e, 0x34, 0x65, 0x47, 0x6e, 0x6e, 0x59, 0x4c, + 0x7a, 0x48, 0x37, 0x59, 0x58, 0x35, 0x35, 0x35, 0x32, 0x41, 0x71, 0x59, 0x6d, 0x2b, 0x6e, 0x57, 0x55, 0x6a, + 0x30, 0x42, 0x51, 0x6a, 0x37, 0x64, 0x78, 0x37, 0x55, 0x41, 0x66, 0x43, 0x37, 0x44, 0x6c, 0x57, 0x5a, 0x55, + 0x71, 0x5c, 0x0a, + 0x09, 0x4c, 0x31, 0x4a, 0x6a, 0x4e, 0x66, 0x37, 0x71, 0x32, 0x71, 0x33, 0x33, 0x48, 0x38, 0x48, 0x58, 0x62, + 0x72, 0x67, 0x56, 0x58, 0x37, 0x2f, 0x78, 0x46, 0x74, 0x78, 0x77, 0x30, 0x32, 0x32, 0x34, 0x37, 0x68, 0x76, + 0x66, 0x77, 0x71, 0x47, 0x44, 0x42, 0x31, 0x4d, 0x64, 0x4d, 0x54, 0x6c, 0x77, 0x6b, 0x4c, 0x51, 0x65, 0x44, + 0x39, 0x62, 0x36, 0x35, 0x49, 0x39, 0x55, 0x57, 0x77, 0x38, 0x49, 0x38, 0x59, 0x65, 0x50, 0x6b, 0x6f, 0x53, + 0x48, 0x5c, 0x0a, + 0x09, 0x4f, 0x54, 0x49, 0x48, 0x2b, 0x2f, 0x41, 0x41, 0x6b, 0x2b, 0x69, 0x48, 0x62, 0x48, 0x30, 0x50, 0x42, + 0x67, 0x4e, 0x63, 0x66, 0x2f, 0x32, 0x33, 0x38, 0x4f, 0x33, 0x72, 0x72, 0x38, 0x63, 0x2f, 0x56, 0x2b, 0x50, + 0x6f, 0x64, 0x4c, 0x76, 0x34, 0x34, 0x55, 0x74, 0x2b, 0x41, 0x44, 0x39, 0x39, 0x79, 0x66, 0x66, 0x68, 0x7a, + 0x4a, 0x4e, 0x33, 0x53, 0x64, 0x6e, 0x79, 0x44, 0x43, 0x34, 0x42, 0x55, 0x41, 0x63, 0x41, 0x4f, 0x7a, 0x59, + 0x36, 0x5c, 0x0a, + 0x09, 0x41, 0x36, 0x44, 0x47, 0x46, 0x31, 0x61, 0x75, 0x45, 0x66, 0x6d, 0x48, 0x67, 0x41, 0x41, 0x51, 0x4c, + 0x63, 0x4b, 0x35, 0x66, 0x69, 0x33, 0x6b, 0x5a, 0x69, 0x54, 0x38, 0x2f, 0x79, 0x37, 0x37, 0x43, 0x6e, 0x37, + 0x6e, 0x44, 0x39, 0x36, 0x54, 0x52, 0x41, 0x6e, 0x74, 0x6d, 0x4e, 0x70, 0x59, 0x77, 0x72, 0x6c, 0x59, 0x4e, + 0x70, 0x42, 0x43, 0x2f, 0x4d, 0x5a, 0x4d, 0x67, 0x46, 0x32, 0x33, 0x6a, 0x46, 0x61, 0x30, 0x70, 0x63, 0x70, + 0x70, 0x5c, 0x0a, + 0x09, 0x59, 0x2b, 0x5a, 0x41, 0x77, 0x68, 0x39, 0x42, 0x74, 0x51, 0x41, 0x69, 0x65, 0x53, 0x38, 0x41, 0x4d, + 0x2f, 0x67, 0x38, 0x7a, 0x33, 0x48, 0x52, 0x52, 0x52, 0x66, 0x69, 0x71, 0x52, 0x65, 0x63, 0x6a, 0x30, 0x73, + 0x65, 0x2b, 0x77, 0x68, 0x4d, 0x54, 0x2f, 0x53, 0x62, 0x48, 0x5a, 0x6f, 0x7a, 0x79, 0x4e, 0x4e, 0x54, 0x6e, + 0x6a, 0x33, 0x6f, 0x7a, 0x4b, 0x42, 0x70, 0x79, 0x6d, 0x58, 0x51, 0x74, 0x2b, 0x39, 0x36, 0x45, 0x42, 0x2f, + 0x35, 0x5c, 0x0a, + 0x09, 0x33, 0x4a, 0x58, 0x34, 0x78, 0x4b, 0x63, 0x2f, 0x6a, 0x78, 0x74, 0x76, 0x76, 0x4a, 0x47, 0x4a, 0x56, + 0x32, 0x56, 0x44, 0x69, 0x72, 0x53, 0x38, 0x77, 0x39, 0x67, 0x54, 0x49, 0x47, 0x7a, 0x49, 0x36, 0x4b, 0x78, + 0x48, 0x6a, 0x58, 0x6c, 0x37, 0x31, 0x6a, 0x73, 0x56, 0x45, 0x74, 0x32, 0x6f, 0x36, 0x5a, 0x53, 0x56, 0x46, + 0x57, 0x70, 0x64, 0x4e, 0x5a, 0x5a, 0x31, 0x44, 0x72, 0x31, 0x2b, 0x44, 0x37, 0x39, 0x35, 0x36, 0x53, 0x76, + 0x77, 0x5c, 0x0a, + 0x09, 0x6f, 0x30, 0x38, 0x36, 0x4e, 0x7a, 0x41, 0x39, 0x57, 0x72, 0x61, 0x65, 0x66, 0x67, 0x6e, 0x41, 0x4f, + 0x37, 0x4a, 0x48, 0x50, 0x73, 0x57, 0x55, 0x37, 0x33, 0x72, 0x51, 0x52, 0x67, 0x48, 0x41, 0x4e, 0x67, 0x41, + 0x48, 0x5a, 0x63, 0x71, 0x6b, 0x30, 0x6c, 0x73, 0x41, 0x49, 0x4f, 0x41, 0x76, 0x50, 0x2f, 0x6b, 0x31, 0x76, + 0x50, 0x34, 0x74, 0x62, 0x34, 0x2b, 0x58, 0x6b, 0x6f, 0x6a, 0x4d, 0x49, 0x67, 0x55, 0x79, 0x51, 0x69, 0x66, + 0x76, 0x5c, 0x0a, + 0x09, 0x56, 0x45, 0x33, 0x4a, 0x6c, 0x31, 0x51, 0x45, 0x63, 0x68, 0x55, 0x79, 0x2b, 0x34, 0x63, 0x34, 0x4b, + 0x67, 0x57, 0x79, 0x52, 0x32, 0x2b, 0x72, 0x51, 0x70, 0x42, 0x6e, 0x2f, 0x47, 0x4f, 0x34, 0x46, 0x72, 0x68, + 0x6f, 0x49, 0x77, 0x74, 0x39, 0x4e, 0x42, 0x6d, 0x4f, 0x61, 0x6c, 0x56, 0x63, 0x30, 0x38, 0x37, 0x53, 0x39, + 0x41, 0x78, 0x39, 0x4f, 0x4c, 0x64, 0x37, 0x7a, 0x78, 0x37, 0x38, 0x2b, 0x69, 0x2b, 0x38, 0x47, 0x4d, 0x39, + 0x34, 0x5c, 0x0a, + 0x09, 0x7a, 0x42, 0x6c, 0x4b, 0x6a, 0x6a, 0x70, 0x38, 0x73, 0x65, 0x38, 0x36, 0x74, 0x62, 0x65, 0x4d, 0x4e, + 0x44, 0x4a, 0x67, 0x4f, 0x2f, 0x37, 0x63, 0x77, 0x67, 0x43, 0x2f, 0x2f, 0x37, 0x63, 0x66, 0x78, 0x77, 0x63, + 0x2b, 0x2b, 0x43, 0x46, 0x37, 0x32, 0x73, 0x53, 0x36, 0x74, 0x62, 0x49, 0x71, 0x66, 0x56, 0x36, 0x54, 0x6b, + 0x42, 0x2b, 0x41, 0x4c, 0x4d, 0x38, 0x41, 0x45, 0x4d, 0x71, 0x79, 0x41, 0x47, 0x55, 0x5a, 0x71, 0x44, 0x72, + 0x6d, 0x5c, 0x0a, + 0x09, 0x4d, 0x74, 0x4c, 0x48, 0x38, 0x62, 0x76, 0x6d, 0x6a, 0x34, 0x47, 0x44, 0x2b, 0x56, 0x67, 0x7a, 0x64, + 0x33, 0x77, 0x56, 0x52, 0x50, 0x67, 0x34, 0x4c, 0x42, 0x44, 0x4a, 0x73, 0x68, 0x7a, 0x76, 0x65, 0x74, 0x4e, + 0x72, 0x38, 0x62, 0x54, 0x7a, 0x54, 0x76, 0x63, 0x64, 0x57, 0x6d, 0x73, 0x6f, 0x38, 0x76, 0x68, 0x31, 0x63, + 0x4f, 0x34, 0x4e, 0x6d, 0x77, 0x38, 0x41, 0x69, 0x4d, 0x34, 0x41, 0x33, 0x4c, 0x63, 0x61, 0x6a, 0x62, 0x4b, + 0x69, 0x5c, 0x0a, + 0x09, 0x47, 0x2b, 0x38, 0x2b, 0x69, 0x47, 0x65, 0x2f, 0x2f, 0x44, 0x56, 0x59, 0x57, 0x6c, 0x77, 0x53, 0x43, + 0x75, 0x74, 0x30, 0x75, 0x78, 0x67, 0x66, 0x48, 0x30, 0x65, 0x33, 0x33, 0x30, 0x65, 0x6e, 0x30, 0x30, 0x47, + 0x57, 0x35, 0x56, 0x55, 0x7a, 0x4a, 0x52, 0x77, 0x63, 0x79, 0x6d, 0x47, 0x4a, 0x30, 0x76, 0x6c, 0x6e, 0x34, + 0x6c, 0x33, 0x70, 0x55, 0x4a, 0x61, 0x46, 0x2f, 0x33, 0x51, 0x46, 0x55, 0x43, 0x6d, 0x75, 0x4c, 0x4d, 0x75, + 0x59, 0x5c, 0x0a, + 0x09, 0x70, 0x70, 0x57, 0x6c, 0x65, 0x71, 0x74, 0x4c, 0x57, 0x45, 0x43, 0x4b, 0x5a, 0x51, 0x41, 0x51, 0x6f, + 0x58, 0x43, 0x6c, 0x47, 0x62, 0x30, 0x41, 0x43, 0x49, 0x4d, 0x4d, 0x31, 0x35, 0x4e, 0x73, 0x41, 0x62, 0x61, + 0x54, 0x36, 0x41, 0x79, 0x47, 0x55, 0x31, 0x4e, 0x2f, 0x76, 0x4e, 0x77, 0x62, 0x66, 0x2b, 0x32, 0x58, 0x38, + 0x61, 0x4e, 0x50, 0x50, 0x43, 0x39, 0x31, 0x57, 0x4c, 0x46, 0x41, 0x78, 0x52, 0x32, 0x64, 0x5a, 0x77, 0x46, + 0x47, 0x5c, 0x0a, + 0x09, 0x52, 0x68, 0x41, 0x37, 0x54, 0x35, 0x31, 0x30, 0x66, 0x6e, 0x45, 0x5a, 0x72, 0x33, 0x7a, 0x6e, 0x58, + 0x2b, 0x4c, 0x79, 0x79, 0x7a, 0x2b, 0x64, 0x4f, 0x4a, 0x45, 0x46, 0x57, 0x48, 0x6d, 0x65, 0x49, 0x38, 0x74, + 0x7a, 0x35, 0x48, 0x6e, 0x4f, 0x6d, 0x69, 0x56, 0x51, 0x52, 0x70, 0x58, 0x63, 0x67, 0x70, 0x4e, 0x35, 0x2f, + 0x58, 0x6c, 0x48, 0x4c, 0x79, 0x74, 0x57, 0x58, 0x50, 0x72, 0x4a, 0x77, 0x4c, 0x71, 0x4d, 0x41, 0x67, 0x77, + 0x74, 0x5c, 0x0a, + 0x09, 0x31, 0x4a, 0x4a, 0x78, 0x5a, 0x53, 0x6e, 0x34, 0x61, 0x5a, 0x7a, 0x69, 0x57, 0x5a, 0x47, 0x2f, 0x61, + 0x74, 0x59, 0x4d, 0x49, 0x45, 0x5a, 0x57, 0x78, 0x34, 0x48, 0x6d, 0x78, 0x4a, 0x4e, 0x50, 0x77, 0x74, 0x2b, + 0x39, 0x39, 0x54, 0x65, 0x77, 0x77, 0x33, 0x70, 0x51, 0x69, 0x4e, 0x75, 0x35, 0x50, 0x2f, 0x64, 0x4f, 0x77, + 0x50, 0x31, 0x69, 0x64, 0x74, 0x62, 0x47, 0x41, 0x63, 0x44, 0x47, 0x72, 0x41, 0x45, 0x34, 0x74, 0x79, 0x4f, + 0x39, 0x5c, 0x0a, + 0x09, 0x50, 0x5a, 0x4f, 0x6d, 0x73, 0x65, 0x2f, 0x35, 0x75, 0x30, 0x39, 0x67, 0x6b, 0x54, 0x33, 0x72, 0x6a, + 0x59, 0x78, 0x77, 0x30, 0x6b, 0x6d, 0x6e, 0x59, 0x48, 0x4c, 0x72, 0x56, 0x70, 0x52, 0x6c, 0x69, 0x62, 0x49, + 0x6f, 0x55, 0x4a, 0x51, 0x6c, 0x69, 0x73, 0x49, 0x2f, 0x64, 0x31, 0x34, 0x55, 0x4a, 0x63, 0x70, 0x69, 0x36, + 0x43, 0x4e, 0x47, 0x41, 0x5a, 0x54, 0x6b, 0x54, 0x53, 0x52, 0x44, 0x6a, 0x68, 0x49, 0x46, 0x73, 0x6a, 0x4b, + 0x4c, 0x5c, 0x0a, + 0x09, 0x4c, 0x39, 0x71, 0x67, 0x4c, 0x41, 0x50, 0x4b, 0x45, 0x73, 0x34, 0x42, 0x57, 0x65, 0x61, 0x4e, 0x4c, + 0x68, 0x68, 0x67, 0x31, 0x46, 0x57, 0x57, 0x69, 0x65, 0x77, 0x67, 0x42, 0x38, 0x58, 0x4d, 0x67, 0x47, 0x4c, + 0x36, 0x55, 0x58, 0x32, 0x72, 0x79, 0x75, 0x72, 0x6e, 0x76, 0x2f, 0x55, 0x4c, 0x50, 0x75, 0x4f, 0x31, 0x59, + 0x48, 0x52, 0x55, 0x47, 0x35, 0x57, 0x31, 0x31, 0x6d, 0x43, 0x6d, 0x78, 0x70, 0x42, 0x74, 0x76, 0x66, 0x46, + 0x74, 0x5c, 0x0a, + 0x09, 0x37, 0x38, 0x56, 0x35, 0x70, 0x2f, 0x38, 0x33, 0x6e, 0x48, 0x6e, 0x79, 0x54, 0x75, 0x6e, 0x6f, 0x6f, + 0x78, 0x62, 0x39, 0x43, 0x45, 0x62, 0x32, 0x70, 0x63, 0x76, 0x70, 0x36, 0x51, 0x50, 0x77, 0x2f, 0x6f, 0x39, + 0x39, 0x41, 0x5a, 0x64, 0x66, 0x2f, 0x6d, 0x6b, 0x6d, 0x67, 0x37, 0x72, 0x6f, 0x32, 0x4d, 0x51, 0x34, 0x2b, + 0x6d, 0x4e, 0x39, 0x39, 0x48, 0x70, 0x6a, 0x79, 0x50, 0x49, 0x4d, 0x57, 0x64, 0x36, 0x42, 0x4b, 0x38, 0x73, + 0x49, 0x5c, 0x0a, + 0x09, 0x77, 0x4d, 0x34, 0x35, 0x46, 0x50, 0x47, 0x59, 0x41, 0x58, 0x52, 0x31, 0x6a, 0x4e, 0x4a, 0x56, 0x2b, + 0x73, 0x68, 0x51, 0x6c, 0x6d, 0x58, 0x4d, 0x41, 0x76, 0x67, 0x6e, 0x38, 0x68, 0x79, 0x75, 0x4b, 0x41, 0x41, + 0x69, 0x5a, 0x45, 0x61, 0x6d, 0x46, 0x72, 0x6a, 0x79, 0x2b, 0x6d, 0x43, 0x67, 0x70, 0x4e, 0x63, 0x4d, 0x46, + 0x46, 0x43, 0x48, 0x4d, 0x6e, 0x6f, 0x4b, 0x6d, 0x41, 0x42, 0x35, 0x41, 0x41, 0x59, 0x4f, 0x32, 0x6d, 0x78, + 0x36, 0x5c, 0x0a, + 0x09, 0x65, 0x4f, 0x63, 0x64, 0x64, 0x2b, 0x42, 0x2f, 0x2f, 0x65, 0x74, 0x58, 0x38, 0x64, 0x4a, 0x6e, 0x58, + 0x69, 0x67, 0x56, 0x79, 0x51, 0x55, 0x66, 0x32, 0x33, 0x63, 0x37, 0x6a, 0x51, 0x4c, 0x72, 0x53, 0x68, 0x75, + 0x31, 0x44, 0x32, 0x41, 0x48, 0x41, 0x4e, 0x53, 0x33, 0x75, 0x78, 0x68, 0x56, 0x33, 0x2b, 0x39, 0x36, 0x63, + 0x41, 0x37, 0x2f, 0x38, 0x49, 0x2f, 0x2f, 0x58, 0x4a, 0x33, 0x7a, 0x48, 0x79, 0x65, 0x64, 0x63, 0x69, 0x71, + 0x6d, 0x5c, 0x0a, + 0x09, 0x64, 0x2b, 0x78, 0x41, 0x6e, 0x75, 0x58, 0x49, 0x73, 0x67, 0x78, 0x5a, 0x37, 0x6a, 0x38, 0x37, 0x48, + 0x66, 0x2b, 0x49, 0x5a, 0x70, 0x35, 0x6e, 0x79, 0x4c, 0x49, 0x63, 0x52, 0x4f, 0x51, 0x4e, 0x45, 0x46, 0x6d, + 0x4d, 0x4e, 0x6c, 0x6d, 0x65, 0x67, 0x37, 0x49, 0x4d, 0x65, 0x62, 0x68, 0x4f, 0x42, 0x47, 0x52, 0x68, 0x2b, + 0x41, 0x35, 0x5a, 0x6c, 0x6f, 0x45, 0x6f, 0x51, 0x7a, 0x44, 0x36, 0x36, 0x45, 0x4d, 0x5a, 0x45, 0x31, 0x47, + 0x6f, 0x5c, 0x0a, + 0x09, 0x4a, 0x36, 0x4a, 0x4f, 0x7a, 0x58, 0x2b, 0x57, 0x5a, 0x66, 0x35, 0x53, 0x31, 0x4b, 0x2b, 0x2f, 0x48, + 0x46, 0x2b, 0x52, 0x35, 0x62, 0x78, 0x44, 0x36, 0x37, 0x66, 0x4a, 0x36, 0x42, 0x51, 0x7a, 0x4c, 0x49, 0x6a, + 0x35, 0x4c, 0x6f, 0x31, 0x55, 0x56, 0x43, 0x51, 0x51, 0x44, 0x6b, 0x75, 0x4c, 0x69, 0x2f, 0x6a, 0x6a, 0x6a, + 0x31, 0x7a, 0x4f, 0x5a, 0x4f, 0x56, 0x69, 0x64, 0x70, 0x4e, 0x57, 0x71, 0x4a, 0x67, 0x4b, 0x54, 0x69, 0x32, + 0x41, 0x5c, 0x0a, + 0x09, 0x57, 0x41, 0x4d, 0x4d, 0x41, 0x78, 0x4c, 0x6e, 0x63, 0x50, 0x2f, 0x68, 0x42, 0x62, 0x7a, 0x2f, 0x4c, + 0x2f, 0x39, 0x61, 0x39, 0x4e, 0x33, 0x72, 0x39, 0x33, 0x48, 0x69, 0x4b, 0x61, 0x66, 0x69, 0x59, 0x59, 0x38, + 0x34, 0x43, 0x36, 0x66, 0x73, 0x4f, 0x77, 0x33, 0x48, 0x37, 0x64, 0x71, 0x44, 0x4c, 0x56, 0x4e, 0x54, 0x36, + 0x49, 0x2b, 0x4e, 0x49, 0x38, 0x38, 0x7a, 0x35, 0x4a, 0x6e, 0x58, 0x43, 0x54, 0x49, 0x2f, 0x4a, 0x65, 0x74, + 0x6b, 0x5c, 0x0a, + 0x09, 0x4f, 0x53, 0x67, 0x6a, 0x45, 0x44, 0x48, 0x64, 0x78, 0x4f, 0x4d, 0x73, 0x79, 0x6a, 0x32, 0x72, 0x35, + 0x4d, 0x37, 0x66, 0x4c, 0x78, 0x69, 0x35, 0x79, 0x76, 0x4d, 0x49, 0x64, 0x42, 0x6c, 0x6c, 0x45, 0x54, 0x37, + 0x72, 0x4d, 0x58, 0x69, 0x4a, 0x42, 0x64, 0x31, 0x5a, 0x36, 0x30, 0x41, 0x4f, 0x48, 0x70, 0x41, 0x43, 0x43, + 0x46, 0x73, 0x4c, 0x79, 0x67, 0x6c, 0x34, 0x4f, 0x79, 0x54, 0x74, 0x78, 0x4f, 0x73, 0x42, 0x47, 0x42, 0x7a, + 0x77, 0x5c, 0x0a, + 0x09, 0x6a, 0x35, 0x2f, 0x36, 0x66, 0x47, 0x68, 0x41, 0x79, 0x5a, 0x32, 0x56, 0x39, 0x35, 0x6e, 0x41, 0x54, + 0x67, 0x50, 0x54, 0x31, 0x35, 0x55, 0x32, 0x42, 0x67, 0x43, 0x49, 0x74, 0x6b, 0x63, 0x44, 0x62, 0x5a, 0x69, + 0x44, 0x58, 0x6e, 0x62, 0x6c, 0x74, 0x7a, 0x43, 0x73, 0x49, 0x6a, 0x75, 0x42, 0x30, 0x4f, 0x76, 0x33, 0x73, + 0x57, 0x76, 0x6e, 0x62, 0x6e, 0x54, 0x79, 0x48, 0x4a, 0x52, 0x6e, 0x4e, 0x51, 0x68, 0x6b, 0x33, 0x6e, 0x6a, + 0x38, 0x5c, 0x0a, + 0x09, 0x33, 0x4c, 0x39, 0x79, 0x66, 0x41, 0x34, 0x43, 0x6c, 0x46, 0x55, 0x47, 0x52, 0x2f, 0x35, 0x38, 0x5a, + 0x58, 0x43, 0x41, 0x51, 0x30, 0x62, 0x6b, 0x6a, 0x61, 0x6e, 0x53, 0x59, 0x41, 0x30, 0x43, 0x58, 0x6b, 0x4d, + 0x4a, 0x43, 0x49, 0x54, 0x37, 0x79, 0x41, 0x77, 0x6f, 0x67, 0x73, 0x46, 0x56, 0x63, 0x63, 0x63, 0x44, 0x6a, + 0x54, 0x4c, 0x61, 0x75, 0x48, 0x71, 0x4e, 0x47, 0x67, 0x79, 0x73, 0x39, 0x38, 0x77, 0x6c, 0x61, 0x61, 0x64, + 0x4c, 0x5c, 0x0a, + 0x09, 0x6a, 0x54, 0x62, 0x55, 0x35, 0x57, 0x44, 0x67, 0x34, 0x50, 0x43, 0x52, 0x66, 0x2f, 0x77, 0x59, 0x37, + 0x70, 0x75, 0x5a, 0x6a, 0x37, 0x79, 0x4c, 0x56, 0x44, 0x4e, 0x59, 0x71, 0x4d, 0x34, 0x4f, 0x6e, 0x4a, 0x59, + 0x2f, 0x79, 0x38, 0x4a, 0x63, 0x74, 0x50, 0x61, 0x59, 0x75, 0x6e, 0x37, 0x30, 0x69, 0x71, 0x73, 0x78, 0x4e, + 0x7a, 0x65, 0x48, 0x38, 0x43, 0x61, 0x65, 0x54, 0x74, 0x37, 0x42, 0x67, 0x54, 0x4d, 0x66, 0x67, 0x65, 0x4e, + 0x32, 0x5c, 0x0a, + 0x09, 0x37, 0x6b, 0x53, 0x2f, 0x31, 0x30, 0x65, 0x65, 0x2b, 0x56, 0x54, 0x66, 0x79, 0x37, 0x72, 0x53, 0x54, + 0x51, 0x55, 0x43, 0x6e, 0x64, 0x79, 0x44, 0x41, 0x49, 0x67, 0x38, 0x43, 0x47, 0x63, 0x77, 0x51, 0x43, 0x43, + 0x72, 0x51, 0x4b, 0x44, 0x57, 0x42, 0x35, 0x65, 0x6a, 0x53, 0x46, 0x51, 0x43, 0x43, 0x44, 0x69, 0x48, 0x6e, + 0x4f, 0x6c, 0x4d, 0x67, 0x33, 0x4c, 0x51, 0x6e, 0x5a, 0x37, 0x71, 0x36, 0x6a, 0x73, 0x46, 0x31, 0x74, 0x75, + 0x54, 0x5c, 0x0a, + 0x09, 0x78, 0x52, 0x75, 0x4f, 0x34, 0x65, 0x71, 0x6d, 0x46, 0x51, 0x43, 0x48, 0x4f, 0x69, 0x47, 0x4c, 0x75, + 0x4f, 0x61, 0x61, 0x61, 0x33, 0x44, 0x48, 0x67, 0x30, 0x66, 0x53, 0x7a, 0x45, 0x6f, 0x41, 0x43, 0x51, 0x48, + 0x4f, 0x6e, 0x58, 0x44, 0x35, 0x6c, 0x36, 0x2f, 0x65, 0x30, 0x4a, 0x38, 0x4a, 0x57, 0x39, 0x63, 0x70, 0x77, + 0x49, 0x46, 0x39, 0x70, 0x2b, 0x48, 0x4e, 0x72, 0x33, 0x34, 0x5a, 0x6e, 0x76, 0x33, 0x6b, 0x78, 0x2b, 0x30, + 0x51, 0x5c, 0x0a, + 0x09, 0x74, 0x30, 0x65, 0x4d, 0x74, 0x50, 0x58, 0x72, 0x33, 0x37, 0x36, 0x35, 0x2b, 0x75, 0x70, 0x54, 0x72, + 0x4e, 0x30, 0x6e, 0x6e, 0x49, 0x42, 0x4f, 0x72, 0x34, 0x74, 0x69, 0x4f, 0x41, 0x53, 0x49, 0x4d, 0x4d, 0x51, + 0x51, 0x57, 0x53, 0x58, 0x77, 0x34, 0x58, 0x42, 0x59, 0x75, 0x36, 0x4e, 0x7a, 0x79, 0x44, 0x73, 0x35, 0x55, + 0x4a, 0x43, 0x66, 0x44, 0x6e, 0x51, 0x79, 0x59, 0x46, 0x68, 0x4e, 0x42, 0x7a, 0x49, 0x2b, 0x48, 0x63, 0x68, + 0x52, 0x5c, 0x0a, + 0x09, 0x75, 0x67, 0x49, 0x5a, 0x41, 0x53, 0x37, 0x50, 0x66, 0x66, 0x72, 0x75, 0x58, 0x45, 0x77, 0x2f, 0x77, + 0x33, 0x76, 0x7a, 0x71, 0x49, 0x6f, 0x45, 0x6c, 0x47, 0x55, 0x2b, 0x39, 0x61, 0x77, 0x6f, 0x69, 0x39, 0x4d, + 0x42, 0x50, 0x77, 0x37, 0x76, 0x6e, 0x4e, 0x55, 0x51, 0x73, 0x69, 0x79, 0x75, 0x43, 0x66, 0x67, 0x53, 0x46, + 0x52, 0x42, 0x51, 0x48, 0x66, 0x32, 0x54, 0x37, 0x44, 0x44, 0x36, 0x48, 0x67, 0x4d, 0x4b, 0x49, 0x2f, 0x72, + 0x72, 0x5c, 0x0a, + 0x09, 0x32, 0x31, 0x6e, 0x42, 0x38, 0x46, 0x78, 0x5a, 0x34, 0x76, 0x50, 0x58, 0x33, 0x59, 0x52, 0x6e, 0x58, + 0x58, 0x42, 0x57, 0x62, 0x43, 0x75, 0x38, 0x77, 0x65, 0x62, 0x49, 0x34, 0x6c, 0x49, 0x55, 0x38, 0x61, 0x41, + 0x6f, 0x6b, 0x52, 0x45, 0x68, 0x4a, 0x7a, 0x2b, 0x32, 0x54, 0x70, 0x5a, 0x6a, 0x76, 0x4e, 0x64, 0x42, 0x76, + 0x39, 0x76, 0x42, 0x65, 0x43, 0x39, 0x50, 0x73, 0x37, 0x49, 0x49, 0x46, 0x4d, 0x41, 0x58, 0x76, 0x2f, 0x35, + 0x4e, 0x5c, 0x0a, + 0x09, 0x6b, 0x66, 0x7a, 0x73, 0x4f, 0x66, 0x45, 0x6b, 0x6a, 0x49, 0x33, 0x31, 0x55, 0x51, 0x78, 0x4c, 0x4f, + 0x41, 0x41, 0x35, 0x61, 0x69, 0x63, 0x59, 0x73, 0x6a, 0x66, 0x65, 0x6c, 0x67, 0x43, 0x6f, 0x41, 0x50, 0x49, + 0x4d, 0x4b, 0x46, 0x45, 0x41, 0x4a, 0x5a, 0x42, 0x6e, 0x48, 0x52, 0x51, 0x6f, 0x67, 0x44, 0x4c, 0x7a, 0x4a, + 0x54, 0x49, 0x67, 0x4b, 0x77, 0x6b, 0x6c, 0x2f, 0x46, 0x54, 0x50, 0x46, 0x62, 0x36, 0x6a, 0x70, 0x75, 0x6b, + 0x41, 0x5c, 0x0a, + 0x09, 0x34, 0x45, 0x48, 0x41, 0x46, 0x59, 0x55, 0x48, 0x5a, 0x55, 0x42, 0x4e, 0x42, 0x77, 0x49, 0x35, 0x76, + 0x39, 0x35, 0x51, 0x51, 0x69, 0x7a, 0x61, 0x36, 0x62, 0x57, 0x4b, 0x78, 0x6b, 0x56, 0x4a, 0x6b, 0x6c, 0x4f, + 0x32, 0x65, 0x4d, 0x75, 0x52, 0x74, 0x53, 0x55, 0x57, 0x46, 0x36, 0x76, 0x7a, 0x6c, 0x33, 0x33, 0x31, 0x6d, + 0x2f, 0x69, 0x65, 0x68, 0x2b, 0x2b, 0x7a, 0x32, 0x2f, 0x51, 0x4d, 0x6f, 0x48, 0x44, 0x6c, 0x43, 0x54, 0x2f, + 0x2f, 0x5c, 0x0a, + 0x09, 0x2b, 0x72, 0x66, 0x32, 0x75, 0x74, 0x33, 0x75, 0x6f, 0x4c, 0x6e, 0x67, 0x32, 0x74, 0x4b, 0x36, 0x72, + 0x77, 0x47, 0x38, 0x2b, 0x73, 0x33, 0x76, 0x6e, 0x72, 0x35, 0x76, 0x6f, 0x62, 0x6a, 0x6f, 0x39, 0x42, 0x4e, + 0x33, 0x6a, 0x79, 0x78, 0x33, 0x31, 0x54, 0x58, 0x58, 0x69, 0x66, 0x6e, 0x56, 0x74, 0x75, 0x30, 0x37, 0x6b, + 0x47, 0x55, 0x5a, 0x58, 0x46, 0x68, 0x4d, 0x36, 0x6e, 0x51, 0x77, 0x4a, 0x4b, 0x41, 0x63, 0x46, 0x73, 0x6a, + 0x7a, 0x5c, 0x0a, + 0x09, 0x48, 0x41, 0x56, 0x38, 0x4f, 0x74, 0x4f, 0x68, 0x4c, 0x6f, 0x62, 0x44, 0x5a, 0x65, 0x52, 0x35, 0x42, + 0x72, 0x6a, 0x63, 0x72, 0x78, 0x77, 0x54, 0x49, 0x61, 0x64, 0x71, 0x2f, 0x70, 0x2f, 0x4a, 0x4e, 0x59, 0x48, + 0x77, 0x34, 0x6b, 0x35, 0x6b, 0x42, 0x46, 0x63, 0x43, 0x63, 0x4b, 0x55, 0x43, 0x41, 0x59, 0x5a, 0x52, 0x46, + 0x56, 0x41, 0x45, 0x79, 0x6f, 0x68, 0x51, 0x4f, 0x68, 0x66, 0x39, 0x75, 0x5a, 0x36, 0x42, 0x2b, 0x68, 0x58, + 0x68, 0x5c, 0x0a, + 0x09, 0x73, 0x69, 0x79, 0x6b, 0x6b, 0x54, 0x45, 0x67, 0x69, 0x50, 0x65, 0x31, 0x39, 0x5a, 0x30, 0x43, 0x59, + 0x76, 0x65, 0x37, 0x41, 0x5a, 0x45, 0x56, 0x57, 0x41, 0x74, 0x61, 0x2f, 0x4e, 0x7a, 0x62, 0x2f, 0x76, 0x53, + 0x44, 0x65, 0x50, 0x2b, 0x48, 0x74, 0x75, 0x43, 0x42, 0x42, 0x78, 0x37, 0x45, 0x6f, 0x55, 0x4d, 0x48, 0x73, + 0x54, 0x78, 0x59, 0x54, 0x75, 0x65, 0x37, 0x4d, 0x41, 0x79, 0x36, 0x75, 0x6a, 0x34, 0x32, 0x4d, 0x59, 0x62, + 0x74, 0x5c, 0x0a, + 0x09, 0x32, 0x33, 0x64, 0x67, 0x32, 0x39, 0x51, 0x30, 0x4a, 0x72, 0x64, 0x4f, 0x59, 0x75, 0x65, 0x32, 0x62, + 0x54, 0x68, 0x75, 0x2b, 0x7a, 0x53, 0x32, 0x54, 0x57, 0x33, 0x42, 0x72, 0x6d, 0x33, 0x54, 0x2b, 0x4f, 0x49, + 0x56, 0x58, 0x78, 0x61, 0x38, 0x37, 0x74, 0x69, 0x31, 0x45, 0x33, 0x6e, 0x65, 0x41, 0x64, 0x77, 0x51, 0x42, + 0x47, 0x41, 0x49, 0x6f, 0x45, 0x4d, 0x64, 0x46, 0x45, 0x57, 0x42, 0x54, 0x71, 0x63, 0x54, 0x51, 0x55, 0x41, + 0x37, 0x5c, 0x0a, + 0x09, 0x56, 0x77, 0x6e, 0x2f, 0x6b, 0x74, 0x49, 0x63, 0x75, 0x51, 0x4b, 0x42, 0x44, 0x46, 0x6c, 0x4a, 0x4b, + 0x46, 0x79, 0x42, 0x4c, 0x49, 0x4a, 0x79, 0x79, 0x55, 0x41, 0x67, 0x71, 0x38, 0x62, 0x4f, 0x4d, 0x75, 0x70, + 0x71, 0x4c, 0x59, 0x66, 0x72, 0x41, 0x78, 0x41, 0x35, 0x41, 0x44, 0x77, 0x49, 0x5a, 0x48, 0x41, 0x4d, 0x6c, + 0x4c, 0x6b, 0x38, 0x68, 0x42, 0x7a, 0x5a, 0x4a, 0x39, 0x65, 0x5a, 0x6c, 0x6e, 0x56, 0x6a, 0x39, 0x6c, 0x44, + 0x56, 0x5c, 0x0a, + 0x09, 0x65, 0x65, 0x50, 0x2f, 0x65, 0x4a, 0x65, 0x38, 0x48, 0x63, 0x6e, 0x57, 0x45, 0x56, 0x69, 0x62, 0x4f, + 0x79, 0x59, 0x6d, 0x4a, 0x30, 0x37, 0x61, 0x73, 0x32, 0x76, 0x6e, 0x54, 0x64, 0x67, 0x67, 0x32, 0x6f, 0x68, + 0x46, 0x77, 0x4e, 0x50, 0x65, 0x2f, 0x49, 0x37, 0x33, 0x2f, 0x69, 0x69, 0x41, 0x78, 0x41, 0x43, 0x74, 0x56, + 0x7a, 0x41, 0x48, 0x6f, 0x55, 0x31, 0x4f, 0x54, 0x73, 0x62, 0x55, 0x50, 0x73, 0x59, 0x57, 0x6c, 0x32, 0x50, + 0x59, 0x5c, 0x0a, + 0x09, 0x41, 0x57, 0x68, 0x49, 0x30, 0x51, 0x43, 0x70, 0x4c, 0x4e, 0x48, 0x70, 0x65, 0x42, 0x44, 0x49, 0x34, + 0x72, 0x62, 0x4e, 0x49, 0x63, 0x71, 0x69, 0x52, 0x45, 0x61, 0x5a, 0x57, 0x68, 0x67, 0x45, 0x73, 0x72, 0x4b, + 0x73, 0x51, 0x43, 0x42, 0x44, 0x6c, 0x6a, 0x6d, 0x55, 0x4d, 0x66, 0x49, 0x51, 0x79, 0x68, 0x41, 0x31, 0x57, + 0x43, 0x59, 0x67, 0x72, 0x4d, 0x2b, 0x35, 0x79, 0x75, 0x69, 0x41, 0x65, 0x68, 0x72, 0x67, 0x79, 0x7a, 0x76, + 0x34, 0x5c, 0x0a, + 0x09, 0x4c, 0x61, 0x63, 0x63, 0x4d, 0x50, 0x51, 0x39, 0x2f, 0x57, 0x67, 0x55, 0x4c, 0x4f, 0x6f, 0x6e, 0x35, + 0x34, 0x32, 0x49, 0x4a, 0x51, 0x77, 0x70, 0x6f, 0x41, 0x38, 0x42, 0x64, 0x39, 0x78, 0x2b, 0x75, 0x2b, 0x67, + 0x72, 0x72, 0x6a, 0x74, 0x51, 0x65, 0x69, 0x74, 0x52, 0x79, 0x39, 0x76, 0x42, 0x59, 0x57, 0x46, 0x75, 0x41, + 0x51, 0x76, 0x7a, 0x64, 0x2b, 0x44, 0x4f, 0x4f, 0x2b, 0x35, 0x49, 0x51, 0x49, 0x50, 0x50, 0x63, 0x51, 0x45, + 0x67, 0x5c, 0x0a, + 0x09, 0x79, 0x33, 0x4e, 0x4d, 0x62, 0x5a, 0x6e, 0x79, 0x69, 0x33, 0x6f, 0x56, 0x4b, 0x4f, 0x63, 0x41, 0x43, + 0x67, 0x4b, 0x79, 0x61, 0x6a, 0x79, 0x64, 0x6a, 0x67, 0x65, 0x44, 0x6f, 0x6d, 0x44, 0x4c, 0x4c, 0x62, 0x33, + 0x58, 0x52, 0x38, 0x55, 0x41, 0x41, 0x43, 0x41, 0x41, 0x53, 0x55, 0x52, 0x42, 0x56, 0x42, 0x57, 0x56, 0x5a, + 0x51, 0x45, 0x51, 0x6b, 0x47, 0x63, 0x63, 0x42, 0x41, 0x6f, 0x67, 0x49, 0x2b, 0x54, 0x49, 0x55, 0x62, 0x71, + 0x79, 0x5c, 0x0a, + 0x09, 0x63, 0x6d, 0x35, 0x72, 0x59, 0x52, 0x42, 0x52, 0x48, 0x33, 0x46, 0x68, 0x4d, 0x49, 0x41, 0x41, 0x67, + 0x44, 0x4a, 0x4a, 0x73, 0x52, 0x67, 0x6f, 0x46, 0x30, 0x57, 0x4d, 0x36, 0x6e, 0x70, 0x38, 0x34, 0x59, 0x33, + 0x47, 0x63, 0x56, 0x46, 0x57, 0x36, 0x53, 0x55, 0x43, 0x41, 0x34, 0x2f, 0x38, 0x31, 0x58, 0x63, 0x4f, 0x47, + 0x6f, 0x45, 0x76, 0x6b, 0x62, 0x55, 0x45, 0x55, 0x46, 0x65, 0x73, 0x50, 0x65, 0x75, 0x53, 0x70, 0x2b, 0x38, + 0x34, 0x5c, 0x0a, + 0x09, 0x64, 0x50, 0x44, 0x67, 0x70, 0x67, 0x4b, 0x41, 0x5a, 0x4b, 0x37, 0x4c, 0x35, 0x38, 0x63, 0x61, 0x5a, + 0x59, 0x4d, 0x52, 0x39, 0x2f, 0x70, 0x2b, 0x37, 0x2f, 0x5a, 0x77, 0x47, 0x63, 0x68, 0x7a, 0x78, 0x78, 0x76, + 0x43, 0x30, 0x41, 0x31, 0x42, 0x63, 0x41, 0x67, 0x33, 0x6d, 0x68, 0x77, 0x48, 0x67, 0x51, 0x79, 0x41, 0x38, + 0x31, 0x66, 0x4b, 0x73, 0x76, 0x52, 0x52, 0x50, 0x30, 0x77, 0x48, 0x4b, 0x49, 0x43, 0x41, 0x58, 0x34, 0x6b, + 0x4f, 0x5c, 0x0a, + 0x09, 0x36, 0x77, 0x5a, 0x6c, 0x34, 0x65, 0x38, 0x47, 0x79, 0x4c, 0x73, 0x44, 0x6a, 0x47, 0x63, 0x69, 0x63, + 0x59, 0x73, 0x77, 0x49, 0x30, 0x4c, 0x68, 0x77, 0x68, 0x52, 0x41, 0x52, 0x64, 0x65, 0x73, 0x76, 0x71, 0x32, + 0x6c, 0x6c, 0x53, 0x39, 0x53, 0x66, 0x42, 0x37, 0x52, 0x53, 0x52, 0x70, 0x61, 0x6c, 0x4a, 0x4f, 0x36, 0x68, + 0x38, 0x33, 0x4c, 0x57, 0x74, 0x48, 0x4c, 0x4d, 0x6b, 0x35, 0x42, 0x4a, 0x45, 0x45, 0x70, 0x76, 0x74, 0x4b, + 0x62, 0x5c, 0x0a, + 0x09, 0x38, 0x78, 0x6d, 0x6d, 0x75, 0x48, 0x48, 0x73, 0x2f, 0x6c, 0x79, 0x2f, 0x33, 0x30, 0x65, 0x6e, 0x32, + 0x77, 0x48, 0x59, 0x62, 0x31, 0x73, 0x34, 0x35, 0x30, 0x41, 0x75, 0x78, 0x37, 0x42, 0x44, 0x6f, 0x4b, 0x4c, + 0x77, 0x30, 0x7a, 0x46, 0x32, 0x2b, 0x79, 0x38, 0x36, 0x54, 0x74, 0x56, 0x57, 0x50, 0x52, 0x30, 0x49, 0x49, + 0x4a, 0x42, 0x44, 0x54, 0x67, 0x63, 0x51, 0x49, 0x33, 0x78, 0x39, 0x74, 0x30, 0x62, 0x65, 0x46, 0x59, 0x68, + 0x4f, 0x5c, 0x0a, + 0x09, 0x47, 0x71, 0x5a, 0x6f, 0x52, 0x4d, 0x69, 0x63, 0x42, 0x77, 0x47, 0x65, 0x6b, 0x51, 0x58, 0x5a, 0x42, + 0x50, 0x32, 0x4b, 0x73, 0x55, 0x62, 0x32, 0x35, 0x49, 0x71, 0x2b, 0x30, 0x42, 0x55, 0x6b, 0x43, 0x44, 0x54, + 0x75, 0x44, 0x53, 0x42, 0x6d, 0x76, 0x38, 0x61, 0x59, 0x49, 0x36, 0x42, 0x58, 0x31, 0x2f, 0x65, 0x65, 0x73, + 0x48, 0x76, 0x48, 0x4a, 0x52, 0x65, 0x63, 0x47, 0x31, 0x38, 0x4d, 0x6b, 0x70, 0x33, 0x31, 0x35, 0x46, 0x52, + 0x50, 0x5c, 0x0a, + 0x09, 0x61, 0x30, 0x6a, 0x72, 0x41, 0x67, 0x42, 0x68, 0x39, 0x39, 0x39, 0x72, 0x66, 0x76, 0x59, 0x2f, 0x34, + 0x33, 0x66, 0x65, 0x39, 0x7a, 0x38, 0x54, 0x77, 0x51, 0x72, 0x44, 0x56, 0x59, 0x49, 0x50, 0x52, 0x74, 0x37, + 0x74, 0x64, 0x4e, 0x51, 0x74, 0x61, 0x70, 0x38, 0x4a, 0x4f, 0x44, 0x66, 0x30, 0x36, 0x53, 0x5a, 0x71, 0x4a, + 0x52, 0x56, 0x67, 0x6d, 0x55, 0x41, 0x78, 0x46, 0x43, 0x75, 0x64, 0x4a, 0x53, 0x6f, 0x51, 0x71, 0x47, 0x61, + 0x4d, 0x5c, 0x0a, + 0x09, 0x57, 0x52, 0x61, 0x6d, 0x41, 0x31, 0x52, 0x6e, 0x41, 0x6a, 0x6d, 0x78, 0x39, 0x4a, 0x4e, 0x51, 0x6c, + 0x68, 0x6e, 0x43, 0x42, 0x71, 0x49, 0x34, 0x48, 0x65, 0x43, 0x33, 0x43, 0x4a, 0x30, 0x54, 0x74, 0x77, 0x6a, + 0x35, 0x32, 0x47, 0x49, 0x66, 0x70, 0x52, 0x46, 0x35, 0x41, 0x68, 0x42, 0x53, 0x62, 0x55, 0x42, 0x38, 0x63, + 0x55, 0x2b, 0x73, 0x66, 0x49, 0x50, 0x45, 0x4f, 0x2f, 0x64, 0x35, 0x2b, 0x37, 0x45, 0x39, 0x39, 0x73, 0x6c, + 0x54, 0x5c, 0x0a, + 0x09, 0x7a, 0x76, 0x35, 0x59, 0x48, 0x35, 0x4e, 0x62, 0x37, 0x48, 0x64, 0x50, 0x50, 0x48, 0x44, 0x2f, 0x2f, + 0x61, 0x4c, 0x2f, 0x71, 0x6d, 0x47, 0x70, 0x43, 0x77, 0x64, 0x70, 0x30, 0x4f, 0x51, 0x42, 0x4f, 0x65, 0x2f, + 0x6b, 0x6f, 0x69, 0x30, 0x69, 0x2f, 0x36, 0x4d, 0x58, 0x6e, 0x53, 0x7a, 0x48, 0x45, 0x41, 0x36, 0x35, 0x79, + 0x31, 0x45, 0x55, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x2f, 0x4d, 0x42, 0x79, 0x4a, 0x7a, 0x58, 0x67, 0x66, 0x4d, + 0x72, 0x5c, 0x0a, + 0x09, 0x2f, 0x6f, 0x55, 0x41, 0x67, 0x53, 0x48, 0x4c, 0x42, 0x44, 0x4b, 0x66, 0x6e, 0x59, 0x48, 0x67, 0x73, + 0x68, 0x78, 0x55, 0x46, 0x69, 0x4e, 0x76, 0x45, 0x54, 0x72, 0x6e, 0x36, 0x69, 0x6b, 0x61, 0x6b, 0x56, 0x2b, + 0x6a, 0x59, 0x51, 0x59, 0x54, 0x73, 0x6a, 0x4d, 0x48, 0x76, 0x37, 0x45, 0x6f, 0x2f, 0x68, 0x41, 0x4e, 0x56, + 0x49, 0x51, 0x32, 0x35, 0x4b, 0x74, 0x76, 0x52, 0x59, 0x37, 0x61, 0x72, 0x78, 0x48, 0x4b, 0x62, 0x35, 0x32, + 0x61, 0x5c, 0x0a, + 0x09, 0x51, 0x71, 0x39, 0x36, 0x65, 0x47, 0x77, 0x55, 0x58, 0x58, 0x44, 0x57, 0x36, 0x54, 0x39, 0x2b, 0x31, + 0x69, 0x6d, 0x37, 0x75, 0x67, 0x41, 0x2b, 0x42, 0x65, 0x66, 0x6d, 0x67, 0x36, 0x2b, 0x73, 0x31, 0x2b, 0x61, + 0x67, 0x4e, 0x64, 0x38, 0x49, 0x46, 0x4c, 0x66, 0x2b, 0x2b, 0x75, 0x7a, 0x73, 0x50, 0x33, 0x33, 0x39, 0x6c, + 0x6e, 0x74, 0x66, 0x2b, 0x6f, 0x34, 0x50, 0x2f, 0x73, 0x4e, 0x7a, 0x51, 0x4a, 0x54, 0x78, 0x4c, 0x5a, 0x37, + 0x31, 0x5c, 0x0a, + 0x09, 0x73, 0x55, 0x2f, 0x76, 0x50, 0x76, 0x32, 0x76, 0x6e, 0x34, 0x6d, 0x37, 0x37, 0x77, 0x44, 0x67, 0x34, + 0x71, 0x63, 0x2f, 0x45, 0x79, 0x42, 0x43, 0x4d, 0x53, 0x78, 0x51, 0x6c, 0x50, 0x34, 0x64, 0x38, 0x30, 0x55, + 0x78, 0x39, 0x43, 0x6e, 0x6d, 0x63, 0x42, 0x6c, 0x46, 0x36, 0x66, 0x78, 0x69, 0x59, 0x46, 0x47, 0x69, 0x4b, + 0x41, 0x75, 0x55, 0x52, 0x59, 0x48, 0x53, 0x2b, 0x51, 0x30, 0x2f, 0x77, 0x2b, 0x6f, 0x70, 0x77, 0x4c, 0x4a, + 0x30, 0x5c, 0x0a, + 0x09, 0x4b, 0x41, 0x73, 0x2f, 0x48, 0x58, 0x44, 0x4f, 0x4e, 0x57, 0x77, 0x57, 0x38, 0x6d, 0x35, 0x63, 0x4f, + 0x6c, 0x64, 0x46, 0x48, 0x74, 0x38, 0x2f, 0x33, 0x79, 0x63, 0x51, 0x65, 0x41, 0x59, 0x51, 0x6f, 0x30, 0x35, + 0x41, 0x70, 0x7a, 0x54, 0x39, 0x5a, 0x4c, 0x49, 0x6f, 0x43, 0x7a, 0x4f, 0x39, 0x4e, 0x39, 0x50, 0x7a, 0x6b, + 0x42, 0x6e, 0x6f, 0x6a, 0x45, 0x4a, 0x46, 0x46, 0x31, 0x35, 0x33, 0x2f, 0x2f, 0x34, 0x44, 0x65, 0x4e, 0x4f, + 0x6c, 0x5c, 0x0a, + 0x09, 0x4c, 0x38, 0x48, 0x55, 0x65, 0x42, 0x38, 0x54, 0x76, 0x51, 0x36, 0x32, 0x6a, 0x50, 0x66, 0x38, 0x63, + 0x77, 0x4f, 0x69, 0x59, 0x52, 0x58, 0x68, 0x71, 0x71, 0x59, 0x4f, 0x4c, 0x77, 0x78, 0x77, 0x5a, 0x47, 0x45, + 0x4a, 0x63, 0x30, 0x76, 0x4c, 0x6d, 0x46, 0x31, 0x63, 0x78, 0x74, 0x7a, 0x69, 0x49, 0x75, 0x35, 0x35, 0x38, + 0x44, 0x41, 0x4f, 0x48, 0x70, 0x37, 0x46, 0x66, 0x51, 0x63, 0x50, 0x34, 0x37, 0x61, 0x37, 0x37, 0x38, 0x56, + 0x6c, 0x5c, 0x0a, + 0x09, 0x6c, 0x33, 0x30, 0x79, 0x38, 0x6a, 0x43, 0x35, 0x64, 0x51, 0x73, 0x65, 0x2f, 0x38, 0x51, 0x6e, 0x59, + 0x31, 0x67, 0x73, 0x6f, 0x79, 0x78, 0x4b, 0x4c, 0x43, 0x38, 0x76, 0x56, 0x2b, 0x6c, 0x2b, 0x67, 0x58, 0x49, + 0x34, 0x52, 0x4f, 0x6b, 0x63, 0x68, 0x6d, 0x55, 0x42, 0x4e, 0x79, 0x77, 0x78, 0x4c, 0x50, 0x78, 0x54, 0x65, + 0x76, 0x47, 0x36, 0x4b, 0x2f, 0x33, 0x2b, 0x67, 0x4b, 0x48, 0x66, 0x78, 0x31, 0x47, 0x36, 0x61, 0x6d, 0x39, + 0x41, 0x5c, 0x0a, + 0x09, 0x61, 0x65, 0x38, 0x54, 0x4b, 0x45, 0x72, 0x2f, 0x53, 0x31, 0x42, 0x38, 0x45, 0x62, 0x5a, 0x70, 0x73, + 0x78, 0x43, 0x41, 0x4f, 0x6a, 0x75, 0x4c, 0x61, 0x77, 0x4b, 0x57, 0x54, 0x70, 0x77, 0x41, 0x41, 0x53, 0x45, + 0x50, 0x61, 0x2b, 0x46, 0x50, 0x5a, 0x51, 0x66, 0x4a, 0x47, 0x67, 0x77, 0x72, 0x51, 0x30, 0x52, 0x34, 0x33, + 0x35, 0x74, 0x2f, 0x45, 0x30, 0x39, 0x2b, 0x35, 0x44, 0x34, 0x35, 0x5a, 0x57, 0x78, 0x61, 0x61, 0x50, 0x51, + 0x44, 0x5c, 0x0a, + 0x09, 0x75, 0x41, 0x64, 0x45, 0x66, 0x77, 0x62, 0x6e, 0x33, 0x67, 0x62, 0x67, 0x62, 0x6d, 0x42, 0x39, 0x51, + 0x47, 0x42, 0x4e, 0x4d, 0x77, 0x44, 0x32, 0x76, 0x72, 0x4f, 0x4c, 0x51, 0x66, 0x51, 0x4f, 0x41, 0x47, 0x65, + 0x65, 0x75, 0x32, 0x38, 0x33, 0x2f, 0x75, 0x6a, 0x58, 0x58, 0x69, 0x4b, 0x46, 0x59, 0x74, 0x77, 0x4b, 0x66, + 0x4d, 0x71, 0x4e, 0x33, 0x38, 0x48, 0x74, 0x74, 0x39, 0x31, 0x57, 0x74, 0x31, 0x57, 0x57, 0x36, 0x49, 0x2b, + 0x4e, 0x5c, 0x0a, + 0x09, 0x41, 0x53, 0x42, 0x51, 0x45, 0x59, 0x54, 0x61, 0x38, 0x55, 0x61, 0x53, 0x64, 0x77, 0x41, 0x4d, 0x67, + 0x55, 0x34, 0x48, 0x42, 0x52, 0x58, 0x41, 0x73, 0x46, 0x4c, 0x51, 0x73, 0x41, 0x41, 0x79, 0x6f, 0x4a, 0x4e, + 0x33, 0x4d, 0x43, 0x79, 0x47, 0x79, 0x48, 0x4f, 0x71, 0x68, 0x6a, 0x79, 0x73, 0x70, 0x77, 0x4f, 0x77, 0x46, + 0x67, 0x5a, 0x4c, 0x66, 0x33, 0x63, 0x67, 0x70, 0x70, 0x2b, 0x4f, 0x5a, 0x51, 0x4a, 0x68, 0x73, 0x78, 0x44, + 0x56, 0x5c, 0x0a, + 0x09, 0x55, 0x53, 0x63, 0x59, 0x5a, 0x6b, 0x77, 0x2f, 0x41, 0x5a, 0x46, 0x62, 0x56, 0x6c, 0x59, 0x54, 0x6f, + 0x70, 0x63, 0x76, 0x57, 0x68, 0x75, 0x51, 0x54, 0x74, 0x31, 0x44, 0x39, 0x61, 0x5a, 0x64, 0x68, 0x45, 0x30, + 0x72, 0x31, 0x69, 0x65, 0x63, 0x73, 0x42, 0x76, 0x6e, 0x6e, 0x38, 0x36, 0x65, 0x73, 0x62, 0x4c, 0x41, 0x6e, + 0x61, 0x72, 0x2f, 0x43, 0x45, 0x4c, 0x75, 0x55, 0x78, 0x4e, 0x39, 0x54, 0x45, 0x33, 0x30, 0x55, 0x44, 0x74, + 0x4b, 0x5c, 0x0a, + 0x09, 0x35, 0x51, 0x6c, 0x56, 0x6d, 0x56, 0x76, 0x75, 0x4f, 0x34, 0x78, 0x50, 0x58, 0x48, 0x5a, 0x35, 0x35, + 0x48, 0x6c, 0x35, 0x73, 0x49, 0x78, 0x4f, 0x78, 0x39, 0x39, 0x36, 0x58, 0x63, 0x59, 0x41, 0x48, 0x56, 0x65, + 0x62, 0x6b, 0x6c, 0x39, 0x32, 0x4b, 0x5a, 0x44, 0x44, 0x6f, 0x63, 0x7a, 0x39, 0x77, 0x75, 0x42, 0x77, 0x4f, + 0x50, 0x53, 0x4c, 0x75, 0x4d, 0x36, 0x42, 0x48, 0x50, 0x6b, 0x73, 0x4c, 0x66, 0x65, 0x72, 0x39, 0x79, 0x69, + 0x42, 0x5c, 0x0a, + 0x09, 0x67, 0x67, 0x6f, 0x51, 0x73, 0x55, 0x7a, 0x41, 0x5a, 0x55, 0x41, 0x5a, 0x31, 0x67, 0x54, 0x38, 0x59, + 0x6d, 0x32, 0x5a, 0x35, 0x30, 0x77, 0x66, 0x4f, 0x68, 0x4e, 0x67, 0x4a, 0x68, 0x57, 0x6d, 0x41, 0x32, 0x4b, + 0x4e, 0x68, 0x75, 0x76, 0x45, 0x70, 0x7a, 0x47, 0x55, 0x65, 0x62, 0x73, 0x53, 0x74, 0x77, 0x52, 0x44, 0x39, + 0x6f, 0x4d, 0x55, 0x6d, 0x50, 0x6e, 0x55, 0x7a, 0x46, 0x70, 0x41, 0x35, 0x47, 0x56, 0x4f, 0x4f, 0x2f, 0x36, + 0x34, 0x5c, 0x0a, + 0x09, 0x32, 0x71, 0x62, 0x6a, 0x32, 0x6f, 0x35, 0x4c, 0x51, 0x53, 0x43, 0x63, 0x49, 0x39, 0x6f, 0x44, 0x34, + 0x46, 0x64, 0x42, 0x65, 0x44, 0x45, 0x63, 0x6e, 0x67, 0x7a, 0x67, 0x75, 0x6c, 0x52, 0x35, 0x71, 0x30, 0x39, + 0x72, 0x74, 0x67, 0x2b, 0x67, 0x76, 0x4f, 0x36, 0x54, 0x71, 0x4b, 0x7a, 0x34, 0x46, 0x30, 0x48, 0x30, 0x4c, + 0x77, 0x44, 0x4f, 0x39, 0x46, 0x63, 0x43, 0x68, 0x44, 0x5a, 0x55, 0x72, 0x41, 0x52, 0x79, 0x36, 0x73, 0x6b, + 0x6e, 0x5c, 0x0a, + 0x09, 0x56, 0x61, 0x58, 0x39, 0x47, 0x73, 0x44, 0x69, 0x34, 0x69, 0x4c, 0x79, 0x50, 0x45, 0x65, 0x33, 0x30, + 0x30, 0x48, 0x57, 0x79, 0x64, 0x48, 0x70, 0x64, 0x50, 0x31, 0x47, 0x6b, 0x37, 0x7a, 0x6a, 0x74, 0x77, 0x50, + 0x6e, 0x48, 0x57, 0x52, 0x55, 0x33, 0x58, 0x2f, 0x75, 0x31, 0x50, 0x73, 0x41, 0x77, 0x6a, 0x33, 0x70, 0x54, + 0x71, 0x63, 0x4c, 0x45, 0x4d, 0x58, 0x4e, 0x51, 0x6d, 0x48, 0x2f, 0x51, 0x45, 0x35, 0x36, 0x73, 0x31, 0x43, + 0x31, 0x5c, 0x0a, + 0x09, 0x75, 0x53, 0x51, 0x61, 0x55, 0x39, 0x67, 0x50, 0x51, 0x47, 0x79, 0x66, 0x51, 0x48, 0x55, 0x74, 0x4c, + 0x41, 0x37, 0x6c, 0x75, 0x56, 0x42, 0x32, 0x32, 0x43, 0x55, 0x51, 0x7a, 0x49, 0x67, 0x62, 0x58, 0x74, 0x79, + 0x32, 0x7a, 0x49, 0x79, 0x4d, 0x52, 0x78, 0x43, 0x52, 0x68, 0x6a, 0x73, 0x6e, 0x72, 0x6f, 0x66, 0x79, 0x4f, + 0x76, 0x30, 0x4d, 0x49, 0x4c, 0x4a, 0x6a, 0x32, 0x33, 0x51, 0x38, 0x59, 0x7a, 0x71, 0x2f, 0x71, 0x68, 0x64, + 0x42, 0x5c, 0x0a, + 0x09, 0x49, 0x46, 0x34, 0x4c, 0x58, 0x73, 0x51, 0x69, 0x5a, 0x6a, 0x57, 0x75, 0x48, 0x5a, 0x4e, 0x6a, 0x6b, + 0x52, 0x63, 0x43, 0x59, 0x62, 0x43, 0x30, 0x35, 0x4b, 0x63, 0x2b, 0x65, 0x59, 0x35, 0x4f, 0x70, 0x31, 0x64, + 0x39, 0x64, 0x76, 0x7a, 0x57, 0x33, 0x38, 0x78, 0x76, 0x2f, 0x38, 0x30, 0x6f, 0x38, 0x7a, 0x72, 0x49, 0x73, + 0x2b, 0x70, 0x38, 0x56, 0x6d, 0x33, 0x64, 0x39, 0x76, 0x73, 0x7a, 0x38, 0x6a, 0x78, 0x48, 0x33, 0x76, 0x48, + 0x6e, 0x5c, 0x0a, + 0x09, 0x63, 0x37, 0x5a, 0x5a, 0x4b, 0x4d, 0x38, 0x36, 0x6c, 0x55, 0x35, 0x79, 0x68, 0x41, 0x31, 0x43, 0x47, + 0x63, 0x68, 0x76, 0x49, 0x38, 0x68, 0x71, 0x77, 0x37, 0x48, 0x32, 0x43, 0x55, 0x52, 0x4a, 0x4d, 0x35, 0x33, + 0x55, 0x6d, 0x37, 0x63, 0x49, 0x33, 0x50, 0x41, 0x63, 0x6b, 0x4f, 0x67, 0x6a, 0x5a, 0x41, 0x4d, 0x61, 0x6a, + 0x44, 0x55, 0x51, 0x38, 0x30, 0x2f, 0x41, 0x36, 0x79, 0x72, 0x63, 0x31, 0x64, 0x6d, 0x39, 0x65, 0x77, 0x2f, + 0x32, 0x5c, 0x0a, + 0x09, 0x37, 0x70, 0x79, 0x71, 0x5a, 0x53, 0x73, 0x79, 0x41, 0x4f, 0x4d, 0x63, 0x31, 0x34, 0x48, 0x44, 0x4c, + 0x68, 0x44, 0x39, 0x41, 0x62, 0x41, 0x2b, 0x4c, 0x77, 0x78, 0x64, 0x45, 0x77, 0x41, 0x6f, 0x72, 0x2f, 0x31, + 0x6b, 0x47, 0x4f, 0x64, 0x7a, 0x41, 0x4c, 0x77, 0x64, 0x67, 0x46, 0x2b, 0x36, 0x64, 0x62, 0x55, 0x6a, 0x2b, + 0x41, 0x2f, 0x31, 0x79, 0x53, 0x34, 0x64, 0x4f, 0x4f, 0x30, 0x55, 0x41, 0x50, 0x56, 0x43, 0x31, 0x70, 0x48, + 0x5a, 0x5c, 0x0a, + 0x09, 0x49, 0x33, 0x36, 0x6a, 0x53, 0x54, 0x64, 0x48, 0x4a, 0x38, 0x2b, 0x52, 0x42, 0x65, 0x66, 0x76, 0x64, + 0x69, 0x6f, 0x51, 0x79, 0x4a, 0x46, 0x33, 0x4f, 0x76, 0x35, 0x61, 0x74, 0x55, 0x73, 0x77, 0x62, 0x45, 0x7a, + 0x78, 0x42, 0x75, 0x64, 0x33, 0x6f, 0x51, 0x48, 0x77, 0x52, 0x70, 0x64, 0x33, 0x34, 0x6c, 0x32, 0x43, 0x75, + 0x42, 0x4f, 0x4e, 0x36, 0x73, 0x31, 0x43, 0x65, 0x64, 0x79, 0x51, 0x51, 0x73, 0x6b, 0x4f, 0x4e, 0x54, 0x45, + 0x33, 0x5c, 0x0a, + 0x09, 0x44, 0x38, 0x61, 0x6e, 0x6c, 0x72, 0x6c, 0x7a, 0x37, 0x73, 0x77, 0x36, 0x6b, 0x6d, 0x54, 0x31, 0x74, + 0x62, 0x67, 0x7a, 0x45, 0x48, 0x55, 0x61, 0x47, 0x39, 0x32, 0x4d, 0x7a, 0x55, 0x31, 0x35, 0x2b, 0x57, 0x43, + 0x51, 0x76, 0x44, 0x77, 0x41, 0x37, 0x44, 0x73, 0x35, 0x52, 0x48, 0x2b, 0x2b, 0x59, 0x4b, 0x63, 0x7a, 0x45, + 0x5a, 0x4c, 0x66, 0x31, 0x56, 0x30, 0x4e, 0x55, 0x54, 0x2b, 0x43, 0x41, 0x62, 0x42, 0x31, 0x76, 0x49, 0x76, + 0x39, 0x5c, 0x0a, + 0x09, 0x42, 0x77, 0x35, 0x45, 0x6e, 0x54, 0x6a, 0x6e, 0x73, 0x4c, 0x43, 0x34, 0x69, 0x45, 0x34, 0x6c, 0x38, + 0x32, 0x36, 0x33, 0x68, 0x37, 0x78, 0x54, 0x67, 0x34, 0x42, 0x33, 0x37, 0x67, 0x35, 0x79, 0x71, 0x6e, 0x59, + 0x44, 0x52, 0x6e, 0x44, 0x49, 0x32, 0x41, 0x61, 0x75, 0x43, 0x71, 0x41, 0x5a, 0x43, 0x46, 0x41, 0x45, 0x67, + 0x64, 0x72, 0x35, 0x69, 0x51, 0x69, 0x55, 0x5a, 0x38, 0x67, 0x6f, 0x72, 0x39, 0x5a, 0x6f, 0x36, 0x73, 0x31, + 0x57, 0x5c, 0x0a, + 0x09, 0x4e, 0x51, 0x6a, 0x34, 0x7a, 0x34, 0x7a, 0x72, 0x68, 0x75, 0x6b, 0x6b, 0x49, 0x36, 0x36, 0x66, 0x61, + 0x6a, 0x32, 0x6e, 0x4f, 0x67, 0x34, 0x50, 0x47, 0x46, 0x6e, 0x62, 0x74, 0x6d, 0x50, 0x47, 0x35, 0x61, 0x54, + 0x73, 0x59, 0x37, 0x70, 0x66, 0x42, 0x61, 0x68, 0x51, 0x68, 0x6f, 0x68, 0x77, 0x33, 0x6a, 0x6d, 0x50, 0x4e, + 0x4b, 0x4b, 0x39, 0x5a, 0x66, 0x73, 0x61, 0x42, 0x43, 0x6a, 0x55, 0x75, 0x52, 0x68, 0x45, 0x50, 0x77, 0x69, + 0x73, 0x5c, 0x0a, + 0x09, 0x50, 0x51, 0x69, 0x73, 0x35, 0x55, 0x37, 0x41, 0x63, 0x54, 0x69, 0x38, 0x79, 0x78, 0x39, 0x57, 0x45, + 0x5a, 0x38, 0x50, 0x57, 0x71, 0x53, 0x61, 0x53, 0x4d, 0x36, 0x66, 0x66, 0x75, 0x49, 0x4a, 0x56, 0x54, 0x58, + 0x2f, 0x37, 0x35, 0x34, 0x37, 0x37, 0x76, 0x54, 0x4f, 0x54, 0x6a, 0x34, 0x4c, 0x36, 0x48, 0x61, 0x37, 0x79, + 0x44, 0x76, 0x42, 0x79, 0x54, 0x50, 0x6b, 0x65, 0x62, 0x66, 0x4b, 0x42, 0x44, 0x78, 0x41, 0x64, 0x44, 0x6f, + 0x64, 0x5c, 0x0a, + 0x09, 0x55, 0x4d, 0x63, 0x62, 0x56, 0x56, 0x35, 0x46, 0x48, 0x63, 0x6f, 0x38, 0x61, 0x41, 0x42, 0x2b, 0x52, + 0x64, 0x6c, 0x48, 0x71, 0x73, 0x6f, 0x49, 0x77, 0x34, 0x37, 0x42, 0x4c, 0x49, 0x43, 0x41, 0x6a, 0x7a, 0x70, + 0x41, 0x5a, 0x56, 0x79, 0x5a, 0x4e, 0x4c, 0x71, 0x6a, 0x41, 0x59, 0x45, 0x73, 0x70, 0x76, 0x44, 0x47, 0x6b, + 0x6c, 0x47, 0x6d, 0x56, 0x70, 0x79, 0x72, 0x6f, 0x54, 0x76, 0x32, 0x54, 0x34, 0x67, 0x6c, 0x74, 0x46, 0x4c, + 0x35, 0x5c, 0x0a, + 0x09, 0x63, 0x45, 0x68, 0x62, 0x4f, 0x55, 0x44, 0x73, 0x50, 0x2b, 0x6c, 0x34, 0x33, 0x67, 0x57, 0x59, 0x51, + 0x53, 0x6c, 0x79, 0x30, 0x75, 0x6d, 0x4a, 0x41, 0x55, 0x4d, 0x77, 0x52, 0x6d, 0x33, 0x41, 0x52, 0x48, 0x6a, + 0x34, 0x77, 0x30, 0x36, 0x76, 0x4d, 0x78, 0x55, 0x69, 0x48, 0x48, 0x7a, 0x77, 0x51, 0x58, 0x51, 0x37, 0x6e, + 0x65, 0x6a, 0x30, 0x58, 0x5a, 0x55, 0x4a, 0x35, 0x48, 0x6d, 0x4f, 0x76, 0x4e, 0x76, 0x78, 0x4f, 0x73, 0x68, + 0x71, 0x5c, 0x0a, + 0x09, 0x52, 0x38, 0x2b, 0x79, 0x76, 0x4d, 0x34, 0x45, 0x34, 0x72, 0x62, 0x75, 0x72, 0x4e, 0x37, 0x4b, 0x6e, + 0x58, 0x4d, 0x51, 0x51, 0x41, 0x55, 0x55, 0x55, 0x4e, 0x75, 0x47, 0x4b, 0x62, 0x4b, 0x6e, 0x51, 0x55, 0x43, + 0x77, 0x4c, 0x55, 0x43, 0x67, 0x42, 0x6d, 0x54, 0x48, 0x50, 0x6c, 0x30, 0x41, 0x41, 0x53, 0x55, 0x72, 0x6e, + 0x64, 0x72, 0x7a, 0x7a, 0x36, 0x41, 0x37, 0x73, 0x5a, 0x5a, 0x54, 0x58, 0x58, 0x76, 0x73, 0x32, 0x51, 0x2b, + 0x76, 0x5c, 0x0a, + 0x09, 0x5a, 0x53, 0x73, 0x59, 0x43, 0x6e, 0x4b, 0x76, 0x50, 0x76, 0x6e, 0x55, 0x68, 0x4d, 0x76, 0x64, 0x30, + 0x35, 0x38, 0x43, 0x57, 0x50, 0x4f, 0x33, 0x42, 0x71, 0x38, 0x64, 0x41, 0x42, 0x43, 0x39, 0x43, 0x45, 0x53, + 0x56, 0x52, 0x66, 0x4c, 0x49, 0x77, 0x79, 0x30, 0x65, 0x36, 0x6e, 0x78, 0x4e, 0x46, 0x35, 0x31, 0x39, 0x75, + 0x6a, 0x68, 0x31, 0x37, 0x7a, 0x31, 0x33, 0x59, 0x62, 0x67, 0x38, 0x52, 0x4c, 0x66, 0x58, 0x52, 0x5a, 0x62, + 0x6c, 0x5c, 0x0a, + 0x09, 0x79, 0x4c, 0x50, 0x4d, 0x67, 0x30, 0x43, 0x33, 0x34, 0x36, 0x63, 0x44, 0x48, 0x5a, 0x39, 0x36, 0x78, + 0x71, 0x66, 0x50, 0x73, 0x67, 0x79, 0x64, 0x33, 0x45, 0x38, 0x58, 0x59, 0x72, 0x70, 0x5a, 0x58, 0x51, 0x2f, + 0x62, 0x68, 0x6e, 0x6b, 0x6d, 0x51, 0x45, 0x54, 0x79, 0x32, 0x59, 0x47, 0x73, 0x33, 0x6e, 0x49, 0x4d, 0x49, + 0x4b, 0x61, 0x66, 0x52, 0x35, 0x30, 0x4a, 0x56, 0x4e, 0x2f, 0x7a, 0x4d, 0x4e, 0x38, 0x55, 0x71, 0x61, 0x64, + 0x48, 0x5c, 0x0a, + 0x09, 0x2b, 0x79, 0x79, 0x58, 0x4b, 0x53, 0x78, 0x69, 0x53, 0x57, 0x5a, 0x6b, 0x6f, 0x6b, 0x35, 0x64, 0x52, + 0x70, 0x44, 0x7a, 0x2f, 0x58, 0x37, 0x50, 0x67, 0x5a, 0x50, 0x72, 0x45, 0x34, 0x6d, 0x63, 0x5a, 0x58, 0x6e, + 0x47, 0x65, 0x47, 0x71, 0x6f, 0x70, 0x44, 0x49, 0x44, 0x7a, 0x77, 0x77, 0x65, 0x66, 0x65, 0x5a, 0x2b, 0x77, + 0x63, 0x75, 0x64, 0x64, 0x39, 0x36, 0x4f, 0x72, 0x41, 0x4c, 0x6a, 0x43, 0x41, 0x49, 0x68, 0x45, 0x2b, 0x68, + 0x32, 0x5c, 0x0a, + 0x09, 0x34, 0x70, 0x4f, 0x61, 0x49, 0x52, 0x76, 0x4c, 0x71, 0x71, 0x32, 0x2b, 0x6e, 0x64, 0x78, 0x48, 0x38, + 0x67, 0x41, 0x53, 0x47, 0x57, 0x55, 0x4d, 0x6f, 0x48, 0x4d, 0x66, 0x36, 0x53, 0x73, 0x51, 0x36, 0x47, 0x53, + 0x64, 0x57, 0x68, 0x38, 0x4b, 0x42, 0x4a, 0x44, 0x56, 0x64, 0x79, 0x45, 0x79, 0x49, 0x58, 0x65, 0x53, 0x4d, + 0x6d, 0x56, 0x62, 0x75, 0x59, 0x50, 0x42, 0x38, 0x7a, 0x51, 0x2b, 0x57, 0x6d, 0x43, 0x59, 0x58, 0x6a, 0x69, + 0x59, 0x5c, 0x0a, + 0x09, 0x4f, 0x75, 0x44, 0x54, 0x4d, 0x73, 0x75, 0x63, 0x51, 0x7a, 0x62, 0x33, 0x31, 0x50, 0x50, 0x50, 0x72, + 0x47, 0x57, 0x70, 0x4d, 0x39, 0x38, 0x41, 0x74, 0x6b, 0x48, 0x47, 0x73, 0x52, 0x45, 0x6d, 0x66, 0x77, 0x38, + 0x51, 0x4f, 0x77, 0x47, 0x38, 0x45, 0x47, 0x74, 0x4d, 0x71, 0x77, 0x34, 0x41, 0x62, 0x4e, 0x58, 0x2f, 0x2b, + 0x66, 0x47, 0x6b, 0x4d, 0x69, 0x53, 0x5a, 0x59, 0x33, 0x46, 0x72, 0x72, 0x46, 0x50, 0x4f, 0x66, 0x62, 0x75, + 0x6d, 0x5c, 0x0a, + 0x09, 0x63, 0x63, 0x34, 0x35, 0x35, 0x38, 0x52, 0x30, 0x6b, 0x30, 0x43, 0x34, 0x39, 0x5a, 0x61, 0x62, 0x30, + 0x59, 0x6e, 0x47, 0x31, 0x66, 0x56, 0x70, 0x66, 0x54, 0x55, 0x64, 0x36, 0x46, 0x54, 0x54, 0x67, 0x45, 0x36, + 0x6e, 0x4d, 0x73, 0x5a, 0x4f, 0x78, 0x30, 0x65, 0x64, 0x4c, 0x41, 0x4e, 0x31, 0x73, 0x67, 0x6f, 0x63, 0x73, + 0x72, 0x68, 0x4f, 0x49, 0x44, 0x4b, 0x42, 0x76, 0x49, 0x4d, 0x38, 0x7a, 0x30, 0x54, 0x71, 0x58, 0x32, 0x63, + 0x43, 0x5c, 0x0a, + 0x09, 0x46, 0x43, 0x4e, 0x48, 0x76, 0x56, 0x63, 0x64, 0x73, 0x57, 0x37, 0x59, 0x74, 0x77, 0x37, 0x55, 0x69, + 0x33, 0x4f, 0x55, 0x79, 0x39, 0x74, 0x6a, 0x50, 0x42, 0x50, 0x67, 0x35, 0x4f, 0x65, 0x67, 0x57, 0x52, 0x31, + 0x70, 0x39, 0x42, 0x53, 0x64, 0x71, 0x49, 0x37, 0x32, 0x4d, 0x42, 0x79, 0x66, 0x6c, 0x66, 0x75, 0x65, 0x78, + 0x7a, 0x34, 0x47, 0x75, 0x36, 0x62, 0x44, 0x6a, 0x38, 0x30, 0x77, 0x77, 0x30, 0x72, 0x53, 0x65, 0x30, 0x6a, + 0x6a, 0x5c, 0x0a, + 0x09, 0x69, 0x35, 0x48, 0x65, 0x4b, 0x57, 0x4f, 0x74, 0x79, 0x72, 0x6d, 0x4b, 0x55, 0x77, 0x49, 0x75, 0x4f, + 0x75, 0x65, 0x4d, 0x79, 0x49, 0x65, 0x44, 0x77, 0x33, 0x31, 0x33, 0x33, 0x59, 0x58, 0x35, 0x75, 0x56, 0x6d, + 0x66, 0x64, 0x59, 0x57, 0x73, 0x4c, 0x4b, 0x34, 0x4a, 0x73, 0x43, 0x79, 0x67, 0x6d, 0x75, 0x76, 0x6e, 0x57, + 0x59, 0x5a, 0x4f, 0x4a, 0x36, 0x2f, 0x65, 0x32, 0x79, 0x43, 0x6e, 0x41, 0x33, 0x6b, 0x65, 0x73, 0x72, 0x52, + 0x71, 0x5c, 0x0a, + 0x09, 0x48, 0x59, 0x65, 0x38, 0x37, 0x42, 0x47, 0x6d, 0x62, 0x6b, 0x51, 0x67, 0x34, 0x69, 0x43, 0x51, 0x65, + 0x31, 0x33, 0x6d, 0x51, 0x52, 0x2f, 0x56, 0x73, 0x78, 0x78, 0x42, 0x62, 0x75, 0x77, 0x54, 0x71, 0x45, 0x43, + 0x67, 0x47, 0x72, 0x64, 0x66, 0x6f, 0x39, 0x48, 0x36, 0x38, 0x4d, 0x64, 0x5a, 0x6c, 0x72, 0x4d, 0x5a, 0x6c, + 0x4a, 0x79, 0x47, 0x38, 0x54, 0x61, 0x54, 0x39, 0x5a, 0x70, 0x4b, 0x52, 0x6b, 0x39, 0x36, 0x34, 0x68, 0x4f, + 0x77, 0x5c, 0x0a, + 0x09, 0x64, 0x39, 0x63, 0x30, 0x77, 0x44, 0x4b, 0x44, 0x36, 0x50, 0x52, 0x69, 0x76, 0x53, 0x55, 0x63, 0x75, + 0x6d, 0x59, 0x64, 0x41, 0x55, 0x2f, 0x56, 0x75, 0x6c, 0x35, 0x74, 0x57, 0x71, 0x73, 0x4d, 0x49, 0x41, 0x50, + 0x63, 0x52, 0x66, 0x37, 0x51, 0x70, 0x63, 0x62, 0x47, 0x42, 0x79, 0x31, 0x51, 0x44, 0x2b, 0x42, 0x6f, 0x2b, + 0x4c, 0x53, 0x4c, 0x48, 0x6c, 0x63, 0x64, 0x65, 0x69, 0x56, 0x38, 0x38, 0x39, 0x70, 0x72, 0x41, 0x50, 0x67, + 0x64, 0x5c, 0x0a, + 0x09, 0x5a, 0x67, 0x45, 0x45, 0x38, 0x72, 0x43, 0x77, 0x56, 0x4b, 0x30, 0x4a, 0x2b, 0x4b, 0x67, 0x65, 0x4d, + 0x6f, 0x46, 0x4f, 0x7a, 0x41, 0x51, 0x6f, 0x4c, 0x50, 0x37, 0x46, 0x70, 0x77, 0x4c, 0x39, 0x77, 0x71, 0x41, + 0x33, 0x51, 0x4c, 0x2f, 0x67, 0x6c, 0x46, 0x56, 0x47, 0x49, 0x68, 0x59, 0x47, 0x77, 0x33, 0x53, 0x41, 0x38, + 0x6f, 0x6f, 0x58, 0x44, 0x67, 0x4a, 0x38, 0x59, 0x56, 0x43, 0x6c, 0x69, 0x6a, 0x6f, 0x54, 0x34, 0x47, 0x58, + 0x55, 0x5c, 0x0a, + 0x09, 0x50, 0x44, 0x7a, 0x4c, 0x63, 0x6e, 0x45, 0x72, 0x74, 0x42, 0x59, 0x48, 0x57, 0x35, 0x6a, 0x69, 0x6e, + 0x39, 0x46, 0x67, 0x61, 0x6d, 0x64, 0x38, 0x36, 0x75, 0x4d, 0x65, 0x58, 0x63, 0x75, 0x59, 0x55, 0x35, 0x41, + 0x33, 0x31, 0x30, 0x48, 0x73, 0x67, 0x2b, 0x6c, 0x44, 0x52, 0x79, 0x55, 0x64, 0x75, 0x52, 0x78, 0x77, 0x34, + 0x50, 0x68, 0x74, 0x65, 0x4e, 0x53, 0x6a, 0x48, 0x69, 0x58, 0x34, 0x75, 0x66, 0x47, 0x47, 0x47, 0x39, 0x44, + 0x72, 0x5c, 0x0a, + 0x09, 0x64, 0x66, 0x33, 0x36, 0x53, 0x38, 0x67, 0x47, 0x38, 0x68, 0x7a, 0x64, 0x54, 0x72, 0x66, 0x4b, 0x43, + 0x4c, 0x70, 0x78, 0x59, 0x62, 0x44, 0x54, 0x37, 0x53, 0x41, 0x6a, 0x42, 0x67, 0x4c, 0x56, 0x4e, 0x43, 0x43, + 0x5a, 0x44, 0x72, 0x43, 0x70, 0x67, 0x6e, 0x79, 0x41, 0x4b, 0x43, 0x77, 0x4d, 0x56, 0x69, 0x41, 0x51, 0x73, + 0x71, 0x73, 0x34, 0x50, 0x66, 0x4e, 0x33, 0x61, 0x34, 0x51, 0x65, 0x4e, 0x41, 0x68, 0x55, 0x59, 0x36, 0x37, + 0x31, 0x5c, 0x0a, + 0x09, 0x55, 0x53, 0x2b, 0x76, 0x68, 0x6a, 0x45, 0x46, 0x55, 0x42, 0x62, 0x72, 0x4c, 0x30, 0x7a, 0x57, 0x51, + 0x72, 0x77, 0x4d, 0x75, 0x41, 0x6d, 0x45, 0x35, 0x31, 0x78, 0x38, 0x45, 0x63, 0x53, 0x63, 0x54, 0x71, 0x6f, + 0x36, 0x36, 0x69, 0x33, 0x52, 0x6b, 0x2f, 0x43, 0x48, 0x57, 0x47, 0x6d, 0x76, 0x76, 0x5a, 0x69, 0x37, 0x65, + 0x72, 0x51, 0x32, 0x41, 0x45, 0x44, 0x59, 0x43, 0x77, 0x64, 0x2f, 0x41, 0x39, 0x72, 0x46, 0x2f, 0x39, 0x68, + 0x31, 0x5c, 0x0a, + 0x09, 0x6c, 0x51, 0x47, 0x49, 0x72, 0x4b, 0x42, 0x47, 0x77, 0x32, 0x64, 0x66, 0x64, 0x42, 0x37, 0x36, 0x2f, + 0x62, 0x46, 0x34, 0x65, 0x6d, 0x46, 0x2b, 0x48, 0x74, 0x64, 0x64, 0x65, 0x31, 0x30, 0x56, 0x35, 0x58, 0x4e, + 0x30, 0x75, 0x78, 0x31, 0x30, 0x75, 0x7a, 0x31, 0x30, 0x77, 0x6e, 0x53, 0x67, 0x57, 0x68, 0x50, 0x6f, 0x64, + 0x50, 0x49, 0x59, 0x67, 0x54, 0x70, 0x64, 0x6e, 0x79, 0x6e, 0x6b, 0x65, 0x59, 0x34, 0x73, 0x58, 0x4b, 0x39, + 0x41, 0x5c, 0x0a, + 0x09, 0x49, 0x45, 0x51, 0x65, 0x4d, 0x52, 0x33, 0x49, 0x4d, 0x6b, 0x44, 0x4e, 0x4e, 0x65, 0x75, 0x37, 0x41, + 0x79, 0x79, 0x79, 0x5a, 0x6d, 0x79, 0x56, 0x4f, 0x56, 0x4d, 0x70, 0x70, 0x77, 0x61, 0x42, 0x53, 0x6f, 0x6c, + 0x31, 0x35, 0x4f, 0x48, 0x7a, 0x53, 0x32, 0x39, 0x6b, 0x59, 0x54, 0x6f, 0x51, 0x72, 0x78, 0x45, 0x6c, 0x78, + 0x68, 0x55, 0x2b, 0x39, 0x53, 0x37, 0x4b, 0x79, 0x63, 0x6b, 0x4a, 0x2f, 0x4f, 0x43, 0x46, 0x35, 0x36, 0x52, + 0x36, 0x5c, 0x0a, + 0x09, 0x53, 0x46, 0x61, 0x61, 0x30, 0x33, 0x6d, 0x39, 0x69, 0x46, 0x53, 0x36, 0x44, 0x76, 0x45, 0x79, 0x6e, + 0x74, 0x64, 0x6e, 0x58, 0x66, 0x77, 0x6b, 0x77, 0x63, 0x38, 0x33, 0x72, 0x37, 0x6b, 0x61, 0x68, 0x32, 0x64, + 0x6d, 0x4a, 0x41, 0x68, 0x55, 0x43, 0x34, 0x4f, 0x64, 0x62, 0x69, 0x39, 0x6d, 0x42, 0x78, 0x59, 0x49, 0x45, + 0x46, 0x47, 0x38, 0x6c, 0x56, 0x68, 0x6e, 0x41, 0x33, 0x56, 0x6b, 0x62, 0x31, 0x77, 0x59, 0x44, 0x4a, 0x6c, + 0x41, 0x5c, 0x0a, + 0x09, 0x58, 0x6a, 0x2f, 0x65, 0x37, 0x66, 0x58, 0x68, 0x6e, 0x58, 0x6f, 0x6b, 0x43, 0x49, 0x54, 0x73, 0x72, + 0x4c, 0x70, 0x46, 0x4b, 0x50, 0x50, 0x52, 0x4f, 0x71, 0x72, 0x48, 0x4b, 0x51, 0x55, 0x58, 0x44, 0x64, 0x4e, + 0x64, 0x33, 0x48, 0x2f, 0x41, 0x4d, 0x72, 0x2b, 0x7a, 0x7a, 0x7a, 0x6b, 0x62, 0x33, 0x2f, 0x2f, 0x6f, 0x4d, + 0x36, 0x41, 0x61, 0x54, 0x57, 0x33, 0x63, 0x6d, 0x6d, 0x4c, 0x5a, 0x30, 0x36, 0x37, 0x6a, 0x45, 0x69, 0x5a, + 0x57, 0x5c, 0x0a, + 0x09, 0x6d, 0x56, 0x59, 0x66, 0x41, 0x48, 0x78, 0x6b, 0x6e, 0x42, 0x62, 0x7a, 0x53, 0x5a, 0x59, 0x71, 0x65, + 0x57, 0x4b, 0x47, 0x79, 0x41, 0x63, 0x65, 0x55, 0x30, 0x35, 0x2f, 0x2f, 0x71, 0x54, 0x6a, 0x70, 0x76, 0x42, + 0x6a, 0x7a, 0x33, 0x39, 0x32, 0x76, 0x64, 0x42, 0x43, 0x77, 0x4e, 0x56, 0x66, 0x2f, 0x54, 0x66, 0x4d, 0x7a, + 0x42, 0x78, 0x43, 0x6e, 0x6e, 0x65, 0x52, 0x64, 0x37, 0x73, 0x2b, 0x45, 0x2b, 0x6a, 0x32, 0x2f, 0x4a, 0x70, + 0x41, 0x5c, 0x0a, + 0x09, 0x74, 0x52, 0x62, 0x51, 0x79, 0x61, 0x76, 0x50, 0x63, 0x4b, 0x75, 0x77, 0x30, 0x30, 0x47, 0x6e, 0x4d, + 0x71, 0x69, 0x73, 0x57, 0x69, 0x76, 0x67, 0x68, 0x74, 0x66, 0x70, 0x2b, 0x46, 0x64, 0x37, 0x35, 0x39, 0x56, + 0x4c, 0x4c, 0x50, 0x49, 0x71, 0x46, 0x59, 0x32, 0x5a, 0x41, 0x49, 0x46, 0x6c, 0x41, 0x74, 0x55, 0x35, 0x49, + 0x42, 0x6f, 0x61, 0x77, 0x4e, 0x63, 0x45, 0x58, 0x42, 0x77, 0x57, 0x6f, 0x45, 0x41, 0x67, 0x52, 0x68, 0x36, + 0x65, 0x5c, 0x0a, + 0x09, 0x42, 0x64, 0x53, 0x66, 0x56, 0x45, 0x57, 0x65, 0x69, 0x49, 0x47, 0x6f, 0x6e, 0x5a, 0x4e, 0x76, 0x65, + 0x49, 0x6b, 0x70, 0x61, 0x58, 0x58, 0x74, 0x52, 0x35, 0x2f, 0x37, 0x4c, 0x4f, 0x7a, 0x5a, 0x74, 0x6f, 0x58, + 0x4a, 0x47, 0x2f, 0x4b, 0x59, 0x4c, 0x2f, 0x54, 0x70, 0x4e, 0x4c, 0x54, 0x4b, 0x5a, 0x4f, 0x7a, 0x4e, 0x4b, + 0x6c, 0x77, 0x76, 0x33, 0x6f, 0x43, 0x66, 0x2b, 0x2f, 0x68, 0x7a, 0x63, 0x4f, 0x72, 0x65, 0x76, 0x57, 0x49, + 0x75, 0x5c, 0x0a, + 0x09, 0x66, 0x4d, 0x58, 0x6e, 0x50, 0x77, 0x38, 0x43, 0x6f, 0x64, 0x76, 0x31, 0x47, 0x56, 0x61, 0x6e, 0x36, + 0x38, 0x47, 0x67, 0x6d, 0x33, 0x66, 0x51, 0x71, 0x62, 0x49, 0x79, 0x6e, 0x51, 0x6e, 0x6b, 0x56, 0x54, 0x59, + 0x47, 0x71, 0x6d, 0x2f, 0x4e, 0x69, 0x6b, 0x79, 0x67, 0x41, 0x75, 0x7a, 0x77, 0x58, 0x59, 0x42, 0x41, 0x70, + 0x71, 0x63, 0x44, 0x66, 0x6d, 0x6f, 0x58, 0x30, 0x33, 0x7a, 0x6f, 0x57, 0x34, 0x51, 0x79, 0x75, 0x2b, 0x49, + 0x4c, 0x5c, 0x0a, + 0x09, 0x67, 0x33, 0x6d, 0x79, 0x4e, 0x6c, 0x50, 0x72, 0x78, 0x47, 0x63, 0x4d, 0x4b, 0x53, 0x42, 0x62, 0x49, + 0x41, 0x77, 0x48, 0x2f, 0x4f, 0x49, 0x4c, 0x6e, 0x34, 0x4e, 0x65, 0x4a, 0x34, 0x65, 0x77, 0x2b, 0x57, 0x53, + 0x36, 0x61, 0x30, 0x79, 0x7a, 0x4c, 0x46, 0x44, 0x32, 0x4e, 0x6e, 0x38, 0x49, 0x61, 0x30, 0x79, 0x72, 0x44, + 0x77, 0x42, 0x2b, 0x62, 0x4b, 0x55, 0x2b, 0x45, 0x57, 0x46, 0x52, 0x72, 0x77, 0x45, 0x45, 0x45, 0x6f, 0x41, + 0x52, 0x5c, 0x0a, + 0x09, 0x71, 0x6a, 0x69, 0x38, 0x39, 0x4a, 0x49, 0x6e, 0x59, 0x50, 0x75, 0x4f, 0x48, 0x53, 0x4a, 0x74, 0x2f, + 0x75, 0x54, 0x48, 0x2f, 0x77, 0x55, 0x4c, 0x43, 0x2f, 0x50, 0x6f, 0x56, 0x4b, 0x6c, 0x2b, 0x48, 0x66, 0x45, + 0x39, 0x43, 0x47, 0x52, 0x35, 0x57, 0x50, 0x33, 0x50, 0x34, 0x39, 0x32, 0x42, 0x76, 0x4a, 0x6f, 0x75, 0x35, + 0x4e, 0x58, 0x37, 0x42, 0x4d, 0x4c, 0x43, 0x59, 0x46, 0x77, 0x54, 0x43, 0x4f, 0x38, 0x51, 0x79, 0x41, 0x67, + 0x55, 0x5c, 0x0a, + 0x09, 0x4d, 0x67, 0x45, 0x4b, 0x61, 0x77, 0x4a, 0x5a, 0x73, 0x6b, 0x2f, 0x41, 0x41, 0x30, 0x4f, 0x34, 0x4a, + 0x56, 0x57, 0x39, 0x58, 0x30, 0x44, 0x73, 0x45, 0x36, 0x69, 0x4e, 0x52, 0x4b, 0x77, 0x4a, 0x78, 0x4d, 0x67, + 0x6a, 0x4d, 0x34, 0x48, 0x67, 0x31, 0x41, 0x46, 0x49, 0x39, 0x44, 0x36, 0x42, 0x63, 0x4d, 0x77, 0x58, 0x6e, + 0x51, 0x42, 0x67, 0x35, 0x36, 0x35, 0x64, 0x65, 0x4f, 0x6b, 0x6c, 0x54, 0x30, 0x72, 0x58, 0x55, 0x73, 0x51, + 0x71, 0x5c, 0x0a, + 0x09, 0x50, 0x39, 0x4c, 0x35, 0x66, 0x54, 0x77, 0x30, 0x73, 0x67, 0x44, 0x47, 0x71, 0x39, 0x62, 0x4c, 0x78, + 0x46, 0x67, 0x58, 0x4c, 0x33, 0x2f, 0x68, 0x38, 0x78, 0x6d, 0x6d, 0x45, 0x2b, 0x36, 0x39, 0x35, 0x79, 0x35, + 0x38, 0x34, 0x58, 0x4f, 0x66, 0x42, 0x5a, 0x43, 0x68, 0x32, 0x2f, 0x56, 0x37, 0x4d, 0x75, 0x70, 0x70, 0x57, + 0x67, 0x65, 0x64, 0x76, 0x42, 0x74, 0x54, 0x2f, 0x51, 0x41, 0x43, 0x65, 0x53, 0x64, 0x48, 0x4a, 0x2b, 0x67, + 0x6a, 0x5c, 0x0a, + 0x09, 0x79, 0x32, 0x4d, 0x57, 0x46, 0x64, 0x63, 0x4d, 0x71, 0x6b, 0x77, 0x67, 0x72, 0x42, 0x30, 0x63, 0x44, + 0x51, 0x68, 0x34, 0x55, 0x4b, 0x36, 0x6e, 0x57, 0x68, 0x47, 0x67, 0x72, 0x62, 0x73, 0x44, 0x51, 0x53, 0x63, + 0x55, 0x33, 0x67, 0x39, 0x52, 0x54, 0x77, 0x4c, 0x71, 0x6b, 0x64, 0x55, 0x4c, 0x74, 0x51, 0x46, 0x34, 0x2b, + 0x5a, 0x6f, 0x41, 0x76, 0x31, 0x50, 0x7a, 0x37, 0x42, 0x2b, 0x2b, 0x42, 0x45, 0x38, 0x35, 0x4a, 0x2f, 0x7a, + 0x61, 0x5c, 0x0a, + 0x09, 0x6e, 0x51, 0x5a, 0x5a, 0x37, 0x75, 0x54, 0x73, 0x32, 0x4a, 0x4a, 0x35, 0x4f, 0x4f, 0x39, 0x42, 0x35, + 0x4b, 0x62, 0x47, 0x4d, 0x71, 0x74, 0x45, 0x2b, 0x65, 0x74, 0x66, 0x2f, 0x2f, 0x70, 0x56, 0x62, 0x64, 0x44, + 0x64, 0x64, 0x7a, 0x50, 0x67, 0x67, 0x65, 0x56, 0x56, 0x49, 0x75, 0x6f, 0x49, 0x51, 0x37, 0x4a, 0x41, 0x51, + 0x45, 0x38, 0x44, 0x2f, 0x50, 0x48, 0x6b, 0x57, 0x41, 0x2f, 0x62, 0x6a, 0x7a, 0x38, 0x52, 0x6c, 0x33, 0x33, + 0x6d, 0x5c, 0x0a, + 0x09, 0x69, 0x37, 0x48, 0x6b, 0x63, 0x4c, 0x43, 0x4d, 0x57, 0x32, 0x37, 0x36, 0x44, 0x6e, 0x62, 0x76, 0x33, + 0x6f, 0x4d, 0x74, 0x57, 0x36, 0x65, 0x71, 0x64, 0x6c, 0x46, 0x50, 0x4e, 0x79, 0x71, 0x42, 0x65, 0x34, 0x66, + 0x78, 0x62, 0x59, 0x56, 0x6e, 0x2b, 0x6f, 0x4e, 0x79, 0x48, 0x4f, 0x72, 0x55, 0x73, 0x48, 0x37, 0x71, 0x69, + 0x37, 0x33, 0x6f, 0x6f, 0x7a, 0x70, 0x32, 0x6a, 0x6b, 0x66, 0x72, 0x63, 0x4f, 0x79, 0x64, 0x31, 0x6a, 0x39, + 0x41, 0x5c, 0x0a, + 0x09, 0x78, 0x4d, 0x63, 0x6b, 0x30, 0x30, 0x33, 0x2b, 0x50, 0x62, 0x79, 0x43, 0x4c, 0x46, 0x42, 0x34, 0x6b, + 0x30, 0x33, 0x74, 0x33, 0x4b, 0x7a, 0x39, 0x77, 0x44, 0x59, 0x54, 0x52, 0x57, 0x77, 0x33, 0x66, 0x4b, 0x2f, + 0x2b, 0x76, 0x65, 0x6e, 0x56, 0x76, 0x34, 0x42, 0x48, 0x6e, 0x58, 0x36, 0x43, 0x6a, 0x50, 0x5a, 0x31, 0x35, + 0x79, 0x49, 0x61, 0x4c, 0x53, 0x30, 0x58, 0x75, 0x50, 0x7a, 0x71, 0x37, 0x2b, 0x44, 0x50, 0x2f, 0x75, 0x6d, + 0x7a, 0x5c, 0x0a, + 0x09, 0x2b, 0x50, 0x4f, 0x50, 0x66, 0x68, 0x6f, 0x66, 0x2b, 0x75, 0x51, 0x56, 0x2b, 0x4f, 0x71, 0x4e, 0x64, + 0x77, 0x4a, 0x35, 0x44, 0x36, 0x66, 0x75, 0x6e, 0x4a, 0x5a, 0x70, 0x72, 0x37, 0x67, 0x4e, 0x4b, 0x50, 0x56, + 0x31, 0x35, 0x73, 0x6d, 0x37, 0x38, 0x65, 0x33, 0x37, 0x5a, 0x6e, 0x48, 0x44, 0x6a, 0x64, 0x2b, 0x4a, 0x70, + 0x77, 0x38, 0x2b, 0x2b, 0x41, 0x42, 0x6d, 0x5a, 0x6d, 0x5a, 0x77, 0x2f, 0x50, 0x45, 0x6e, 0x6f, 0x74, 0x66, + 0x72, 0x5c, 0x0a, + 0x09, 0x65, 0x67, 0x6c, 0x56, 0x66, 0x4e, 0x63, 0x6a, 0x35, 0x45, 0x2f, 0x4a, 0x49, 0x55, 0x59, 0x37, 0x79, + 0x6f, 0x68, 0x6a, 0x47, 0x67, 0x50, 0x41, 0x71, 0x6b, 0x35, 0x47, 0x6c, 0x54, 0x77, 0x71, 0x4f, 0x56, 0x66, + 0x6a, 0x35, 0x32, 0x56, 0x41, 0x74, 0x5a, 0x61, 0x53, 0x36, 0x52, 0x68, 0x62, 0x58, 0x37, 0x47, 0x75, 0x68, + 0x65, 0x73, 0x31, 0x4b, 0x4e, 0x65, 0x36, 0x63, 0x47, 0x43, 0x4c, 0x75, 0x45, 0x7a, 0x32, 0x6e, 0x45, 0x34, + 0x2f, 0x5c, 0x0a, + 0x09, 0x63, 0x41, 0x42, 0x76, 0x76, 0x66, 0x52, 0x46, 0x6d, 0x4f, 0x68, 0x33, 0x70, 0x65, 0x79, 0x31, 0x6a, + 0x53, 0x76, 0x62, 0x53, 0x4c, 0x4b, 0x44, 0x64, 0x46, 0x72, 0x77, 0x64, 0x6a, 0x6a, 0x38, 0x47, 0x2b, 0x30, + 0x2b, 0x44, 0x57, 0x74, 0x46, 0x61, 0x77, 0x4d, 0x41, 0x52, 0x41, 0x73, 0x67, 0x65, 0x69, 0x57, 0x63, 0x36, + 0x39, 0x56, 0x47, 0x79, 0x49, 0x79, 0x49, 0x4b, 0x52, 0x38, 0x49, 0x78, 0x32, 0x42, 0x47, 0x44, 0x49, 0x47, + 0x61, 0x5c, 0x0a, + 0x09, 0x5a, 0x35, 0x32, 0x79, 0x42, 0x34, 0x66, 0x51, 0x78, 0x56, 0x56, 0x58, 0x58, 0x78, 0x63, 0x56, 0x50, + 0x31, 0x77, 0x65, 0x34, 0x73, 0x5a, 0x76, 0x58, 0x34, 0x2b, 0x5a, 0x77, 0x34, 0x63, 0x41, 0x2b, 0x44, 0x63, + 0x43, 0x39, 0x63, 0x62, 0x36, 0x63, 0x59, 0x48, 0x46, 0x4c, 0x2b, 0x52, 0x41, 0x4b, 0x4d, 0x32, 0x4a, 0x71, + 0x45, 0x68, 0x77, 0x42, 0x4a, 0x41, 0x6a, 0x31, 0x6e, 0x30, 0x77, 0x54, 0x76, 0x38, 0x51, 0x6b, 0x4c, 0x43, + 0x76, 0x5c, 0x0a, + 0x09, 0x47, 0x50, 0x49, 0x63, 0x77, 0x6a, 0x71, 0x79, 0x42, 0x34, 0x48, 0x4b, 0x75, 0x4b, 0x67, 0x32, 0x59, + 0x71, 0x6c, 0x6e, 0x5a, 0x6e, 0x78, 0x73, 0x45, 0x51, 0x71, 0x78, 0x36, 0x64, 0x43, 0x4a, 0x42, 0x42, 0x6b, + 0x69, 0x38, 0x6e, 0x76, 0x56, 0x6c, 0x63, 0x48, 0x78, 0x68, 0x31, 0x46, 0x65, 0x2f, 0x4d, 0x49, 0x66, 0x77, + 0x30, 0x75, 0x65, 0x66, 0x6f, 0x47, 0x55, 0x72, 0x54, 0x6c, 0x33, 0x42, 0x36, 0x36, 0x34, 0x2f, 0x6e, 0x62, + 0x38, 0x5c, 0x0a, + 0x09, 0x38, 0x75, 0x2b, 0x2f, 0x48, 0x33, 0x2f, 0x2b, 0x77, 0x51, 0x2f, 0x6a, 0x32, 0x75, 0x75, 0x2b, 0x69, + 0x64, 0x74, 0x75, 0x76, 0x77, 0x31, 0x33, 0x33, 0x6e, 0x45, 0x58, 0x72, 0x76, 0x33, 0x47, 0x4e, 0x2f, 0x45, + 0x50, 0x6c, 0x2f, 0x30, 0x72, 0x76, 0x6e, 0x6a, 0x39, 0x48, 0x54, 0x6a, 0x37, 0x6a, 0x50, 0x33, 0x59, 0x4f, + 0x61, 0x56, 0x2b, 0x74, 0x6c, 0x37, 0x72, 0x70, 0x6a, 0x72, 0x38, 0x33, 0x72, 0x50, 0x50, 0x77, 0x47, 0x65, + 0x76, 0x5c, 0x0a, + 0x09, 0x76, 0x67, 0x48, 0x33, 0x33, 0x2f, 0x39, 0x41, 0x50, 0x48, 0x2f, 0x34, 0x30, 0x43, 0x46, 0x38, 0x2b, + 0x31, 0x76, 0x66, 0x42, 0x43, 0x6a, 0x44, 0x32, 0x4e, 0x67, 0x59, 0x78, 0x73, 0x62, 0x36, 0x55, 0x54, 0x5a, + 0x78, 0x78, 0x50, 0x71, 0x42, 0x70, 0x69, 0x44, 0x6e, 0x49, 0x41, 0x58, 0x4c, 0x53, 0x51, 0x49, 0x41, 0x4f, + 0x74, 0x6e, 0x47, 0x4b, 0x42, 0x43, 0x51, 0x2f, 0x4d, 0x70, 0x33, 0x4b, 0x46, 0x6a, 0x72, 0x4e, 0x52, 0x34, + 0x45, 0x5c, 0x0a, + 0x09, 0x4d, 0x70, 0x51, 0x49, 0x75, 0x79, 0x2b, 0x6a, 0x4a, 0x71, 0x72, 0x72, 0x69, 0x4c, 0x6f, 0x49, 0x59, + 0x45, 0x42, 0x45, 0x32, 0x4c, 0x48, 0x6a, 0x4f, 0x4c, 0x7a, 0x6e, 0x64, 0x5a, 0x66, 0x69, 0x31, 0x4a, 0x31, + 0x54, 0x4b, 0x73, 0x67, 0x5a, 0x6c, 0x47, 0x77, 0x4f, 0x34, 0x73, 0x4e, 0x4d, 0x6e, 0x50, 0x38, 0x42, 0x4f, + 0x50, 0x63, 0x53, 0x41, 0x49, 0x4f, 0x31, 0x42, 0x49, 0x42, 0x56, 0x66, 0x78, 0x6a, 0x49, 0x37, 0x31, 0x78, + 0x79, 0x5c, 0x0a, + 0x09, 0x41, 0x50, 0x41, 0x52, 0x67, 0x48, 0x34, 0x6f, 0x69, 0x66, 0x5a, 0x4a, 0x5a, 0x45, 0x45, 0x4b, 0x43, + 0x49, 0x41, 0x55, 0x6c, 0x48, 0x4d, 0x59, 0x46, 0x41, 0x36, 0x76, 0x2f, 0x37, 0x4f, 0x2f, 0x78, 0x34, 0x63, + 0x2b, 0x2f, 0x42, 0x47, 0x42, 0x78, 0x76, 0x79, 0x7a, 0x31, 0x2b, 0x39, 0x68, 0x32, 0x2f, 0x62, 0x6a, 0x73, + 0x48, 0x56, 0x36, 0x47, 0x75, 0x50, 0x6a, 0x34, 0x2b, 0x6a, 0x31, 0x65, 0x76, 0x55, 0x74, 0x77, 0x36, 0x7a, + 0x61, 0x5c, 0x0a, + 0x09, 0x54, 0x31, 0x34, 0x4d, 0x4d, 0x52, 0x7a, 0x36, 0x68, 0x34, 0x57, 0x47, 0x52, 0x65, 0x46, 0x66, 0x4c, + 0x6a, 0x6f, 0x73, 0x55, 0x4a, 0x62, 0x56, 0x67, 0x79, 0x6e, 0x56, 0x51, 0x30, 0x54, 0x44, 0x34, 0x54, 0x4b, + 0x41, 0x2b, 0x6b, 0x57, 0x6a, 0x5a, 0x56, 0x6d, 0x4b, 0x46, 0x31, 0x6a, 0x57, 0x44, 0x78, 0x43, 0x56, 0x37, + 0x47, 0x65, 0x6f, 0x79, 0x75, 0x70, 0x52, 0x34, 0x6b, 0x6f, 0x57, 0x37, 0x46, 0x48, 0x69, 0x4d, 0x48, 0x51, + 0x41, 0x5c, 0x0a, + 0x09, 0x79, 0x57, 0x76, 0x49, 0x2b, 0x51, 0x4d, 0x72, 0x44, 0x67, 0x36, 0x75, 0x4b, 0x4f, 0x76, 0x73, 0x68, + 0x4b, 0x30, 0x4a, 0x65, 0x4c, 0x48, 0x34, 0x38, 0x79, 0x39, 0x34, 0x33, 0x72, 0x50, 0x77, 0x75, 0x70, 0x2f, + 0x36, 0x59, 0x58, 0x51, 0x37, 0x32, 0x51, 0x6a, 0x44, 0x38, 0x68, 0x55, 0x2f, 0x63, 0x50, 0x6c, 0x58, 0x38, + 0x61, 0x61, 0x33, 0x76, 0x68, 0x76, 0x44, 0x34, 0x52, 0x41, 0x6e, 0x37, 0x7a, 0x30, 0x56, 0x7a, 0x33, 0x76, + 0x36, 0x5c, 0x0a, + 0x09, 0x78, 0x54, 0x6a, 0x33, 0x59, 0x61, 0x64, 0x69, 0x57, 0x4a, 0x53, 0x34, 0x38, 0x76, 0x71, 0x62, 0x38, + 0x44, 0x63, 0x66, 0x2b, 0x53, 0x63, 0x38, 0x65, 0x50, 0x38, 0x44, 0x6d, 0x4a, 0x71, 0x65, 0x78, 0x6e, 0x2f, + 0x2f, 0x39, 0x66, 0x38, 0x58, 0x54, 0x7a, 0x37, 0x37, 0x4e, 0x4d, 0x6d, 0x77, 0x70, 0x52, 0x4d, 0x41, 0x4e, + 0x39, 0x38, 0x33, 0x67, 0x35, 0x39, 0x2f, 0x77, 0x7a, 0x76, 0x77, 0x6e, 0x65, 0x6f, 0x33, 0x41, 0x66, 0x68, + 0x30, 0x5c, 0x0a, + 0x09, 0x68, 0x6b, 0x41, 0x59, 0x47, 0x78, 0x2f, 0x48, 0x38, 0x53, 0x65, 0x64, 0x6a, 0x4b, 0x6e, 0x70, 0x61, + 0x55, 0x78, 0x4f, 0x62, 0x45, 0x46, 0x76, 0x72, 0x49, 0x64, 0x4f, 0x70, 0x34, 0x4f, 0x79, 0x4c, 0x46, 0x45, + 0x4d, 0x68, 0x2f, 0x48, 0x68, 0x6f, 0x4f, 0x46, 0x77, 0x57, 0x4c, 0x33, 0x67, 0x74, 0x66, 0x43, 0x2f, 0x2f, + 0x56, 0x43, 0x57, 0x2f, 0x71, 0x47, 0x68, 0x30, 0x71, 0x47, 0x6f, 0x5a, 0x46, 0x2b, 0x57, 0x52, 0x61, 0x57, + 0x44, 0x5c, 0x0a, + 0x09, 0x45, 0x6b, 0x58, 0x31, 0x77, 0x42, 0x65, 0x63, 0x41, 0x38, 0x72, 0x71, 0x6f, 0x61, 0x50, 0x53, 0x77, + 0x54, 0x6e, 0x2f, 0x78, 0x43, 0x44, 0x58, 0x55, 0x2f, 0x6c, 0x64, 0x50, 0x45, 0x41, 0x55, 0x39, 0x42, 0x41, + 0x66, 0x45, 0x6f, 0x71, 0x5a, 0x59, 0x66, 0x71, 0x6f, 0x4e, 0x51, 0x41, 0x63, 0x76, 0x2b, 0x64, 0x34, 0x76, + 0x50, 0x4e, 0x31, 0x6c, 0x2b, 0x4b, 0x38, 0x66, 0x58, 0x75, 0x6b, 0x44, 0x75, 0x4b, 0x55, 0x53, 0x67, 0x55, + 0x35, 0x5c, 0x0a, + 0x09, 0x50, 0x67, 0x31, 0x57, 0x41, 0x4a, 0x33, 0x6f, 0x30, 0x4c, 0x6b, 0x66, 0x41, 0x2f, 0x42, 0x42, 0x59, + 0x47, 0x30, 0x66, 0x43, 0x6c, 0x71, 0x54, 0x70, 0x77, 0x48, 0x39, 0x63, 0x77, 0x42, 0x30, 0x4d, 0x59, 0x43, + 0x50, 0x43, 0x32, 0x46, 0x6f, 0x45, 0x67, 0x36, 0x66, 0x48, 0x43, 0x52, 0x43, 0x47, 0x53, 0x77, 0x58, 0x65, + 0x4d, 0x39, 0x48, 0x50, 0x34, 0x73, 0x2f, 0x2f, 0x4f, 0x4f, 0x2f, 0x45, 0x4b, 0x2f, 0x63, 0x53, 0x74, 0x42, + 0x5a, 0x5c, 0x0a, + 0x09, 0x55, 0x59, 0x6a, 0x2b, 0x6e, 0x54, 0x78, 0x48, 0x74, 0x39, 0x39, 0x48, 0x72, 0x39, 0x2f, 0x33, 0x69, + 0x30, 0x7a, 0x38, 0x78, 0x61, 0x47, 0x35, 0x33, 0x4b, 0x77, 0x44, 0x49, 0x50, 0x36, 0x57, 0x58, 0x48, 0x67, + 0x69, 0x7a, 0x62, 0x50, 0x6b, 0x2f, 0x43, 0x75, 0x6e, 0x79, 0x62, 0x2f, 0x53, 0x4f, 0x72, 0x7a, 0x31, 0x70, + 0x6e, 0x37, 0x6d, 0x33, 0x37, 0x47, 0x33, 0x43, 0x66, 0x6b, 0x6e, 0x45, 0x50, 0x6e, 0x38, 0x75, 0x2b, 0x53, + 0x4f, 0x5c, 0x0a, + 0x09, 0x62, 0x72, 0x77, 0x6e, 0x67, 0x45, 0x65, 0x59, 0x4f, 0x72, 0x44, 0x56, 0x42, 0x70, 0x68, 0x6e, 0x47, + 0x56, 0x37, 0x78, 0x73, 0x7a, 0x2b, 0x46, 0x6c, 0x2f, 0x2f, 0x67, 0x45, 0x2b, 0x73, 0x35, 0x72, 0x6b, 0x34, + 0x66, 0x6d, 0x58, 0x46, 0x39, 0x38, 0x4e, 0x4e, 0x58, 0x34, 0x6a, 0x64, 0x2f, 0x37, 0x77, 0x2f, 0x67, 0x34, + 0x50, 0x43, 0x66, 0x58, 0x2f, 0x41, 0x38, 0x76, 0x4f, 0x6f, 0x46, 0x33, 0x31, 0x38, 0x2f, 0x49, 0x56, 0x69, + 0x56, 0x5c, 0x0a, + 0x09, 0x75, 0x66, 0x2f, 0x77, 0x41, 0x6e, 0x37, 0x6a, 0x66, 0x58, 0x2b, 0x44, 0x54, 0x31, 0x7a, 0x2b, 0x53, + 0x66, 0x54, 0x37, 0x59, 0x2f, 0x6a, 0x54, 0x74, 0x2f, 0x77, 0x47, 0x48, 0x6e, 0x76, 0x67, 0x70, 0x46, 0x51, + 0x48, 0x71, 0x5a, 0x48, 0x69, 0x33, 0x70, 0x6c, 0x35, 0x2f, 0x4e, 0x71, 0x37, 0x2f, 0x69, 0x63, 0x2b, 0x38, + 0x39, 0x6e, 0x50, 0x43, 0x66, 0x6e, 0x72, 0x34, 0x37, 0x71, 0x4b, 0x77, 0x2f, 0x6a, 0x45, 0x4f, 0x4d, 0x62, + 0x47, 0x5c, 0x0a, + 0x09, 0x4a, 0x39, 0x45, 0x62, 0x36, 0x79, 0x48, 0x50, 0x71, 0x6c, 0x75, 0x33, 0x6d, 0x63, 0x2b, 0x43, 0x73, + 0x71, 0x78, 0x2b, 0x34, 0x57, 0x64, 0x5a, 0x44, 0x72, 0x33, 0x6f, 0x55, 0x44, 0x6c, 0x6f, 0x36, 0x65, 0x4a, + 0x6a, 0x32, 0x6d, 0x56, 0x52, 0x6f, 0x75, 0x42, 0x50, 0x45, 0x51, 0x59, 0x39, 0x4f, 0x48, 0x38, 0x39, 0x50, + 0x46, 0x48, 0x6f, 0x66, 0x2f, 0x75, 0x78, 0x65, 0x6d, 0x53, 0x34, 0x65, 0x6e, 0x4b, 0x7a, 0x72, 0x4f, 0x62, + 0x7a, 0x5c, 0x0a, + 0x09, 0x34, 0x49, 0x37, 0x4f, 0x5a, 0x4f, 0x31, 0x56, 0x6b, 0x6a, 0x36, 0x69, 0x7a, 0x73, 0x64, 0x78, 0x34, + 0x59, 0x55, 0x58, 0x34, 0x49, 0x30, 0x76, 0x2b, 0x33, 0x39, 0x77, 0x79, 0x6e, 0x46, 0x68, 0x43, 0x73, 0x70, + 0x74, 0x52, 0x30, 0x55, 0x6e, 0x64, 0x68, 0x64, 0x46, 0x67, 0x49, 0x4b, 0x75, 0x56, 0x2b, 0x76, 0x78, 0x74, + 0x51, 0x42, 0x2b, 0x42, 0x31, 0x6a, 0x37, 0x4a, 0x77, 0x4c, 0x58, 0x43, 0x41, 0x41, 0x2b, 0x46, 0x56, 0x44, + 0x77, 0x5c, 0x0a, + 0x09, 0x44, 0x2b, 0x48, 0x77, 0x38, 0x6b, 0x59, 0x41, 0x41, 0x47, 0x79, 0x45, 0x62, 0x4b, 0x4a, 0x4b, 0x55, + 0x56, 0x66, 0x64, 0x66, 0x41, 0x2f, 0x65, 0x2b, 0x63, 0x47, 0x50, 0x34, 0x74, 0x50, 0x2f, 0x2b, 0x74, 0x6e, + 0x71, 0x4e, 0x4d, 0x73, 0x68, 0x6f, 0x59, 0x41, 0x67, 0x4f, 0x46, 0x43, 0x59, 0x35, 0x79, 0x6c, 0x6c, 0x57, + 0x34, 0x2f, 0x57, 0x38, 0x68, 0x52, 0x50, 0x37, 0x38, 0x50, 0x58, 0x6b, 0x56, 0x6c, 0x38, 0x68, 0x7a, 0x4a, + 0x32, 0x5c, 0x0a, + 0x09, 0x42, 0x6b, 0x59, 0x38, 0x4d, 0x75, 0x71, 0x32, 0x72, 0x4c, 0x4c, 0x68, 0x48, 0x44, 0x2f, 0x2b, 0x33, + 0x73, 0x63, 0x39, 0x44, 0x71, 0x2f, 0x36, 0x79, 0x65, 0x66, 0x67, 0x30, 0x65, 0x47, 0x4a, 0x76, 0x35, 0x69, + 0x61, 0x75, 0x2f, 0x71, 0x59, 0x79, 0x58, 0x4e, 0x70, 0x4d, 0x4d, 0x52, 0x50, 0x2f, 0x4e, 0x59, 0x37, 0x63, + 0x65, 0x58, 0x58, 0x72, 0x73, 0x4c, 0x4c, 0x66, 0x2b, 0x59, 0x6e, 0x38, 0x63, 0x76, 0x50, 0x66, 0x51, 0x71, + 0x4c, 0x5c, 0x0a, + 0x09, 0x54, 0x74, 0x57, 0x67, 0x71, 0x2b, 0x2b, 0x4c, 0x67, 0x77, 0x4b, 0x2f, 0x39, 0x74, 0x36, 0x2f, 0x78, + 0x54, 0x2f, 0x2b, 0x30, 0x37, 0x2f, 0x67, 0x42, 0x63, 0x39, 0x37, 0x46, 0x74, 0x37, 0x34, 0x6b, 0x6d, 0x64, + 0x42, 0x47, 0x71, 0x2f, 0x57, 0x51, 0x31, 0x31, 0x33, 0x65, 0x65, 0x6a, 0x77, 0x56, 0x35, 0x2f, 0x36, 0x4e, + 0x37, 0x7a, 0x33, 0x41, 0x78, 0x2f, 0x43, 0x76, 0x66, 0x66, 0x65, 0x6b, 0x77, 0x4b, 0x61, 0x6d, 0x6d, 0x4e, + 0x7a, 0x5c, 0x0a, + 0x09, 0x30, 0x6d, 0x4d, 0x56, 0x4c, 0x34, 0x49, 0x4a, 0x75, 0x6c, 0x56, 0x74, 0x52, 0x62, 0x41, 0x33, 0x5a, + 0x4b, 0x6a, 0x50, 0x6a, 0x36, 0x7a, 0x50, 0x35, 0x43, 0x76, 0x4b, 0x61, 0x6a, 0x4e, 0x6b, 0x2f, 0x6e, 0x7a, + 0x4b, 0x33, 0x6c, 0x50, 0x78, 0x34, 0x68, 0x63, 0x38, 0x43, 0x79, 0x39, 0x34, 0x34, 0x71, 0x50, 0x51, 0x36, + 0x32, 0x59, 0x69, 0x4f, 0x78, 0x4e, 0x52, 0x33, 0x33, 0x4c, 0x73, 0x30, 0x46, 0x6a, 0x55, 0x6d, 0x37, 0x36, + 0x47, 0x5c, 0x0a, + 0x09, 0x65, 0x2b, 0x44, 0x63, 0x79, 0x77, 0x46, 0x38, 0x47, 0x46, 0x69, 0x66, 0x78, 0x34, 0x48, 0x58, 0x37, + 0x48, 0x30, 0x41, 0x31, 0x59, 0x35, 0x41, 0x41, 0x74, 0x46, 0x76, 0x41, 0x48, 0x67, 0x4e, 0x67, 0x44, 0x45, + 0x7a, 0x55, 0x76, 0x45, 0x55, 0x56, 0x36, 0x52, 0x46, 0x47, 0x6a, 0x32, 0x68, 0x36, 0x67, 0x46, 0x58, 0x33, + 0x33, 0x49, 0x50, 0x50, 0x76, 0x36, 0x56, 0x61, 0x33, 0x48, 0x31, 0x4e, 0x32, 0x2f, 0x45, 0x31, 0x36, 0x36, + 0x38, 0x5c, 0x0a, + 0x09, 0x45, 0x76, 0x4e, 0x7a, 0x38, 0x37, 0x36, 0x59, 0x4d, 0x6a, 0x54, 0x4c, 0x43, 0x48, 0x57, 0x30, 0x31, + 0x32, 0x2f, 0x62, 0x43, 0x65, 0x30, 0x6b, 0x42, 0x74, 0x70, 0x77, 0x72, 0x6a, 0x70, 0x68, 0x41, 0x6b, 0x6d, + 0x43, 0x61, 0x58, 0x47, 0x38, 0x61, 0x61, 0x54, 0x55, 0x6b, 0x65, 0x66, 0x6b, 0x55, 0x30, 0x2f, 0x42, 0x45, + 0x79, 0x39, 0x34, 0x4c, 0x4a, 0x37, 0x35, 0x2b, 0x50, 0x4e, 0x78, 0x77, 0x52, 0x6b, 0x6e, 0x48, 0x52, 0x31, + 0x51, 0x5c, 0x0a, + 0x09, 0x73, 0x6b, 0x37, 0x6d, 0x42, 0x30, 0x50, 0x38, 0x30, 0x35, 0x65, 0x2b, 0x69, 0x65, 0x64, 0x64, 0x64, + 0x4c, 0x62, 0x4d, 0x78, 0x41, 0x77, 0x6a, 0x6e, 0x56, 0x74, 0x63, 0x78, 0x76, 0x2f, 0x2b, 0x30, 0x72, 0x56, + 0x34, 0x2f, 0x6b, 0x58, 0x6e, 0x2b, 0x73, 0x30, 0x36, 0x69, 0x58, 0x55, 0x37, 0x6f, 0x33, 0x35, 0x74, 0x30, + 0x45, 0x63, 0x57, 0x42, 0x76, 0x6a, 0x48, 0x4c, 0x31, 0x32, 0x4c, 0x54, 0x33, 0x33, 0x6c, 0x61, 0x6e, 0x7a, + 0x32, 0x5c, 0x0a, + 0x09, 0x63, 0x31, 0x2f, 0x41, 0x34, 0x75, 0x4c, 0x43, 0x69, 0x67, 0x41, 0x51, 0x78, 0x71, 0x33, 0x6c, 0x33, + 0x53, 0x68, 0x66, 0x41, 0x48, 0x71, 0x64, 0x51, 0x4c, 0x2b, 0x77, 0x77, 0x33, 0x78, 0x7a, 0x30, 0x67, 0x68, + 0x77, 0x48, 0x37, 0x58, 0x41, 0x35, 0x35, 0x7a, 0x44, 0x32, 0x57, 0x63, 0x2f, 0x45, 0x75, 0x65, 0x63, 0x39, + 0x58, 0x41, 0x38, 0x34, 0x64, 0x47, 0x50, 0x77, 0x42, 0x4d, 0x66, 0x63, 0x52, 0x72, 0x47, 0x2b, 0x39, 0x57, + 0x62, 0x5c, 0x0a, + 0x09, 0x70, 0x49, 0x38, 0x6d, 0x6c, 0x57, 0x66, 0x79, 0x54, 0x57, 0x30, 0x2f, 0x6e, 0x4d, 0x63, 0x69, 0x67, + 0x44, 0x66, 0x41, 0x34, 0x64, 0x32, 0x41, 0x76, 0x2f, 0x58, 0x33, 0x66, 0x2f, 0x30, 0x4c, 0x51, 0x64, 0x69, + 0x57, 0x59, 0x4d, 0x41, 0x2f, 0x45, 0x2f, 0x42, 0x6a, 0x41, 0x43, 0x34, 0x41, 0x38, 0x4d, 0x6a, 0x71, 0x62, + 0x7a, 0x52, 0x5a, 0x4b, 0x46, 0x71, 0x33, 0x78, 0x38, 0x6f, 0x41, 0x41, 0x47, 0x46, 0x78, 0x4d, 0x4d, 0x54, + 0x4e, 0x5c, 0x0a, + 0x09, 0x39, 0x78, 0x37, 0x43, 0x72, 0x66, 0x63, 0x66, 0x78, 0x45, 0x31, 0x33, 0x33, 0x49, 0x65, 0x37, 0x48, + 0x7a, 0x69, 0x49, 0x75, 0x2b, 0x2b, 0x37, 0x48, 0x33, 0x66, 0x64, 0x63, 0x78, 0x39, 0x75, 0x75, 0x66, 0x6b, + 0x57, 0x7a, 0x4d, 0x33, 0x4f, 0x2b, 0x69, 0x6f, 0x6a, 0x6f, 0x70, 0x43, 0x2b, 0x4c, 0x68, 0x79, 0x79, 0x41, + 0x55, 0x43, 0x53, 0x6c, 0x48, 0x65, 0x46, 0x7a, 0x4d, 0x4c, 0x4d, 0x54, 0x75, 0x42, 0x66, 0x73, 0x58, 0x33, + 0x36, 0x5c, 0x0a, + 0x09, 0x36, 0x61, 0x66, 0x6a, 0x31, 0x46, 0x4e, 0x50, 0x78, 0x72, 0x36, 0x54, 0x6a, 0x73, 0x65, 0x5a, 0x65, + 0x30, 0x2f, 0x43, 0x6d, 0x61, 0x63, 0x65, 0x6a, 0x34, 0x63, 0x64, 0x76, 0x78, 0x31, 0x5a, 0x54, 0x70, 0x45, + 0x6a, 0x51, 0x31, 0x42, 0x49, 0x6e, 0x48, 0x4a, 0x55, 0x78, 0x4e, 0x46, 0x31, 0x47, 0x36, 0x2f, 0x70, 0x6f, + 0x67, 0x31, 0x47, 0x4c, 0x71, 0x5a, 0x34, 0x64, 0x61, 0x67, 0x38, 0x73, 0x72, 0x43, 0x4d, 0x36, 0x32, 0x36, + 0x39, 0x5c, 0x0a, + 0x09, 0x42, 0x39, 0x66, 0x63, 0x64, 0x41, 0x65, 0x2b, 0x66, 0x65, 0x75, 0x64, 0x75, 0x4f, 0x58, 0x32, 0x4f, + 0x33, 0x44, 0x44, 0x74, 0x32, 0x2f, 0x45, 0x6f, 0x55, 0x4f, 0x48, 0x52, 0x41, 0x51, 0x58, 0x30, 0x64, 0x6c, + 0x79, 0x32, 0x42, 0x58, 0x6b, 0x7a, 0x6b, 0x48, 0x42, 0x63, 0x6d, 0x51, 0x74, 0x36, 0x33, 0x72, 0x6b, 0x73, + 0x72, 0x33, 0x6a, 0x54, 0x7a, 0x67, 0x42, 0x4a, 0x35, 0x39, 0x79, 0x45, 0x6b, 0x37, 0x63, 0x76, 0x51, 0x74, + 0x37, 0x5c, 0x0a, + 0x09, 0x64, 0x75, 0x37, 0x41, 0x33, 0x75, 0x4e, 0x33, 0x34, 0x66, 0x51, 0x54, 0x64, 0x32, 0x48, 0x2f, 0x43, + 0x54, 0x75, 0x77, 0x50, 0x66, 0x7a, 0x2b, 0x34, 0x71, 0x68, 0x46, 0x50, 0x43, 0x45, 0x58, 0x50, 0x67, 0x57, + 0x6f, 0x50, 0x32, 0x79, 0x51, 0x63, 0x41, 0x44, 0x6f, 0x43, 0x33, 0x44, 0x75, 0x38, 0x61, 0x47, 0x5a, 0x39, + 0x66, 0x79, 0x70, 0x73, 0x4c, 0x56, 0x2f, 0x49, 0x78, 0x42, 0x2f, 0x6e, 0x4e, 0x48, 0x33, 0x39, 0x57, 0x77, + 0x51, 0x5c, 0x0a, + 0x09, 0x2f, 0x5a, 0x30, 0x6f, 0x4a, 0x46, 0x4b, 0x76, 0x4a, 0x70, 0x52, 0x73, 0x4f, 0x4f, 0x5a, 0x6b, 0x47, + 0x58, 0x2b, 0x6c, 0x34, 0x4e, 0x6d, 0x46, 0x4a, 0x64, 0x78, 0x2f, 0x5a, 0x41, 0x47, 0x48, 0x35, 0x68, 0x5a, + 0x78, 0x61, 0x47, 0x34, 0x42, 0x68, 0x32, 0x63, 0x58, 0x4d, 0x4c, 0x65, 0x34, 0x69, 0x50, 0x6d, 0x46, 0x4a, + 0x53, 0x77, 0x73, 0x2b, 0x54, 0x66, 0x67, 0x7a, 0x43, 0x30, 0x73, 0x59, 0x6d, 0x46, 0x78, 0x43, 0x58, 0x4d, + 0x4c, 0x5c, 0x0a, + 0x09, 0x43, 0x31, 0x68, 0x65, 0x48, 0x6d, 0x4b, 0x32, 0x41, 0x67, 0x32, 0x41, 0x73, 0x4c, 0x43, 0x34, 0x69, + 0x4b, 0x58, 0x42, 0x4d, 0x67, 0x68, 0x2b, 0x76, 0x6e, 0x39, 0x6f, 0x70, 0x74, 0x36, 0x6a, 0x73, 0x57, 0x58, + 0x4c, 0x46, 0x6e, 0x53, 0x72, 0x7a, 0x55, 0x52, 0x45, 0x68, 0x4b, 0x31, 0x62, 0x4a, 0x6a, 0x30, 0x4c, 0x57, + 0x59, 0x61, 0x74, 0x6b, 0x35, 0x50, 0x59, 0x4d, 0x6a, 0x47, 0x4f, 0x79, 0x59, 0x6c, 0x78, 0x54, 0x49, 0x36, + 0x50, 0x5c, 0x0a, + 0x09, 0x59, 0x57, 0x4a, 0x38, 0x44, 0x4a, 0x4e, 0x6a, 0x66, 0x55, 0x79, 0x4f, 0x39, 0x37, 0x46, 0x39, 0x61, + 0x67, 0x76, 0x32, 0x62, 0x4e, 0x75, 0x4b, 0x48, 0x56, 0x76, 0x47, 0x73, 0x58, 0x74, 0x71, 0x41, 0x6d, 0x4f, + 0x39, 0x6a, 0x68, 0x79, 0x48, 0x64, 0x57, 0x7a, 0x4a, 0x69, 0x35, 0x2b, 0x72, 0x68, 0x53, 0x46, 0x6c, 0x6f, + 0x39, 0x76, 0x51, 0x35, 0x30, 0x33, 0x35, 0x42, 0x52, 0x6b, 0x61, 0x37, 0x57, 0x6b, 0x6a, 0x46, 0x39, 0x6b, + 0x61, 0x5c, 0x0a, + 0x09, 0x7a, 0x31, 0x42, 0x6b, 0x74, 0x6e, 0x4c, 0x76, 0x6f, 0x54, 0x6e, 0x63, 0x65, 0x33, 0x67, 0x57, 0x39, + 0x38, 0x33, 0x4d, 0x34, 0x39, 0x36, 0x44, 0x4d, 0x35, 0x69, 0x64, 0x58, 0x38, 0x54, 0x63, 0x34, 0x68, 0x4c, + 0x6d, 0x35, 0x68, 0x63, 0x78, 0x75, 0x37, 0x69, 0x49, 0x75, 0x64, 0x6c, 0x35, 0x7a, 0x4d, 0x37, 0x4e, 0x59, + 0x62, 0x62, 0x4b, 0x35, 0x67, 0x62, 0x4c, 0x79, 0x31, 0x68, 0x59, 0x58, 0x50, 0x49, 0x74, 0x4b, 0x62, 0x6c, + 0x76, 0x5c, 0x0a, + 0x09, 0x6d, 0x39, 0x34, 0x57, 0x58, 0x7a, 0x49, 0x79, 0x50, 0x6a, 0x36, 0x47, 0x58, 0x74, 0x66, 0x66, 0x68, + 0x75, 0x76, 0x32, 0x65, 0x68, 0x6a, 0x72, 0x39, 0x37, 0x46, 0x6c, 0x66, 0x42, 0x7a, 0x6a, 0x6b, 0x32, 0x50, + 0x59, 0x4f, 0x6a, 0x36, 0x4f, 0x69, 0x66, 0x45, 0x2b, 0x4a, 0x76, 0x6f, 0x39, 0x72, 0x34, 0x75, 0x78, 0x48, + 0x71, 0x61, 0x32, 0x54, 0x47, 0x44, 0x37, 0x6c, 0x6e, 0x48, 0x73, 0x6e, 0x4a, 0x72, 0x45, 0x63, 0x56, 0x76, + 0x47, 0x5c, 0x0a, + 0x09, 0x61, 0x39, 0x6b, 0x48, 0x6e, 0x67, 0x55, 0x77, 0x73, 0x6d, 0x79, 0x55, 0x6b, 0x35, 0x61, 0x54, 0x4d, + 0x36, 0x36, 0x74, 0x42, 0x42, 0x71, 0x65, 0x76, 0x67, 0x33, 0x67, 0x6a, 0x50, 0x56, 0x2b, 0x48, 0x79, 0x43, + 0x77, 0x44, 0x67, 0x44, 0x41, 0x71, 0x66, 0x70, 0x64, 0x77, 0x4a, 0x38, 0x45, 0x38, 0x4f, 0x63, 0x41, 0x6a, + 0x49, 0x69, 0x6c, 0x55, 0x6c, 0x73, 0x39, 0x58, 0x37, 0x58, 0x71, 0x48, 0x45, 0x33, 0x4b, 0x4e, 0x51, 0x49, + 0x59, 0x5c, 0x0a, + 0x09, 0x6d, 0x76, 0x73, 0x30, 0x2b, 0x6f, 0x75, 0x73, 0x4e, 0x44, 0x67, 0x6c, 0x70, 0x34, 0x5a, 0x46, 0x4f, + 0x65, 0x6b, 0x34, 0x49, 0x77, 0x43, 0x75, 0x61, 0x65, 0x70, 0x6a, 0x4f, 0x72, 0x49, 0x31, 0x31, 0x57, 0x67, + 0x79, 0x4f, 0x73, 0x4f, 0x68, 0x78, 0x64, 0x69, 0x4d, 0x61, 0x31, 0x59, 0x32, 0x4d, 0x56, 0x4c, 0x2b, 0x7a, + 0x42, 0x6d, 0x61, 0x6a, 0x46, 0x2b, 0x74, 0x49, 0x30, 0x67, 0x41, 0x55, 0x58, 0x77, 0x6c, 0x55, 0x30, 0x4c, + 0x47, 0x5c, 0x0a, + 0x09, 0x6f, 0x78, 0x6b, 0x63, 0x72, 0x4d, 0x7a, 0x47, 0x34, 0x4f, 0x6b, 0x6f, 0x31, 0x6a, 0x64, 0x45, 0x50, + 0x35, 0x78, 0x45, 0x47, 0x64, 0x6a, 0x6a, 0x46, 0x54, 0x70, 0x6e, 0x59, 0x30, 0x7a, 0x6c, 0x63, 0x67, 0x68, + 0x77, 0x32, 0x77, 0x46, 0x67, 0x76, 0x58, 0x38, 0x6e, 0x63, 0x48, 0x31, 0x2f, 0x47, 0x59, 0x68, 0x55, 0x6e, + 0x30, 0x45, 0x49, 0x32, 0x73, 0x6d, 0x42, 0x57, 0x6c, 0x42, 0x4f, 0x66, 0x59, 0x39, 0x31, 0x72, 0x43, 0x6a, + 0x46, 0x5c, 0x0a, + 0x09, 0x79, 0x6c, 0x72, 0x47, 0x71, 0x64, 0x74, 0x4d, 0x6a, 0x67, 0x32, 0x44, 0x30, 0x50, 0x33, 0x78, 0x64, + 0x6e, 0x6c, 0x5a, 0x67, 0x6e, 0x47, 0x4f, 0x55, 0x76, 0x42, 0x77, 0x31, 0x58, 0x2b, 0x4f, 0x6a, 0x34, 0x6c, + 0x64, 0x4a, 0x45, 0x6a, 0x44, 0x34, 0x6d, 0x33, 0x7a, 0x66, 0x6f, 0x56, 0x42, 0x68, 0x6e, 0x34, 0x4a, 0x6f, + 0x6b, 0x46, 0x74, 0x74, 0x43, 0x34, 0x34, 0x51, 0x58, 0x43, 0x53, 0x68, 0x6f, 0x6a, 0x6d, 0x77, 0x6a, 0x58, + 0x6c, 0x5c, 0x0a, + 0x09, 0x58, 0x46, 0x61, 0x45, 0x71, 0x77, 0x65, 0x6c, 0x2b, 0x4e, 0x46, 0x6c, 0x64, 0x4c, 0x75, 0x73, 0x6e, + 0x53, 0x41, 0x54, 0x41, 0x64, 0x43, 0x36, 0x50, 0x72, 0x63, 0x56, 0x4a, 0x65, 0x4d, 0x77, 0x6c, 0x73, 0x67, + 0x72, 0x30, 0x72, 0x5a, 0x69, 0x66, 0x53, 0x4f, 0x53, 0x77, 0x36, 0x56, 0x74, 0x43, 0x48, 0x6c, 0x43, 0x6e, + 0x68, 0x63, 0x41, 0x47, 0x4d, 0x5a, 0x4c, 0x36, 0x58, 0x68, 0x72, 0x5a, 0x75, 0x72, 0x78, 0x38, 0x2f, 0x6f, + 0x31, 0x5c, 0x0a, + 0x09, 0x48, 0x39, 0x73, 0x41, 0x64, 0x49, 0x33, 0x4b, 0x61, 0x30, 0x34, 0x62, 0x38, 0x4e, 0x4e, 0x67, 0x33, + 0x42, 0x6c, 0x47, 0x52, 0x43, 0x4e, 0x53, 0x43, 0x6d, 0x38, 0x4b, 0x61, 0x46, 0x45, 0x4a, 0x6b, 0x45, 0x49, + 0x64, 0x6c, 0x58, 0x6f, 0x46, 0x4a, 0x34, 0x4f, 0x54, 0x39, 0x65, 0x4a, 0x35, 0x6b, 0x75, 0x31, 0x6f, 0x67, + 0x30, 0x77, 0x56, 0x6d, 0x41, 0x4b, 0x56, 0x61, 0x4a, 0x65, 0x55, 0x59, 0x62, 0x48, 0x50, 0x34, 0x46, 0x69, + 0x78, 0x5c, 0x0a, + 0x09, 0x58, 0x7a, 0x62, 0x6d, 0x36, 0x4b, 0x51, 0x6a, 0x6f, 0x71, 0x6a, 0x6c, 0x66, 0x4d, 0x5a, 0x68, 0x37, + 0x44, 0x50, 0x4b, 0x52, 0x50, 0x47, 0x6b, 0x51, 0x5a, 0x6a, 0x4c, 0x4e, 0x59, 0x34, 0x66, 0x54, 0x45, 0x62, + 0x38, 0x55, 0x34, 0x31, 0x58, 0x38, 0x41, 0x63, 0x6b, 0x44, 0x68, 0x66, 0x59, 0x31, 0x69, 0x41, 0x57, 0x4c, + 0x76, 0x4c, 0x32, 0x65, 0x41, 0x53, 0x4e, 0x49, 0x4f, 0x54, 0x53, 0x74, 0x6f, 0x6e, 0x58, 0x34, 0x55, 0x77, + 0x70, 0x5c, 0x0a, + 0x09, 0x4a, 0x30, 0x36, 0x79, 0x48, 0x53, 0x67, 0x52, 0x57, 0x76, 0x62, 0x4a, 0x36, 0x6f, 0x63, 0x79, 0x5a, + 0x69, 0x42, 0x53, 0x64, 0x54, 0x69, 0x49, 0x52, 0x46, 0x42, 0x53, 0x31, 0x32, 0x73, 0x66, 0x32, 0x4a, 0x41, + 0x66, 0x43, 0x74, 0x32, 0x6f, 0x48, 0x77, 0x64, 0x4e, 0x55, 0x37, 0x64, 0x41, 0x53, 0x53, 0x6f, 0x63, 0x4c, + 0x7a, 0x51, 0x59, 0x50, 0x4b, 0x76, 0x44, 0x6f, 0x34, 0x70, 0x49, 0x57, 0x31, 0x56, 0x45, 0x44, 0x63, 0x62, + 0x76, 0x5c, 0x0a, + 0x09, 0x64, 0x46, 0x6e, 0x56, 0x64, 0x32, 0x78, 0x62, 0x4b, 0x55, 0x34, 0x37, 0x4e, 0x51, 0x65, 0x50, 0x70, + 0x67, 0x77, 0x69, 0x38, 0x4d, 0x4c, 0x37, 0x34, 0x56, 0x6b, 0x44, 0x35, 0x7a, 0x30, 0x36, 0x50, 0x36, 0x54, + 0x52, 0x36, 0x43, 0x6c, 0x41, 0x4b, 0x42, 0x76, 0x6c, 0x78, 0x79, 0x4b, 0x5a, 0x48, 0x6f, 0x38, 0x6c, 0x4e, + 0x2b, 0x32, 0x41, 0x31, 0x6c, 0x52, 0x44, 0x52, 0x48, 0x34, 0x6d, 0x4d, 0x33, 0x59, 0x71, 0x38, 0x69, 0x68, + 0x6b, 0x5c, 0x0a, + 0x09, 0x6f, 0x74, 0x72, 0x68, 0x73, 0x72, 0x41, 0x79, 0x4a, 0x64, 0x36, 0x67, 0x6e, 0x6d, 0x4a, 0x77, 0x2b, + 0x66, 0x4d, 0x4d, 0x49, 0x4d, 0x71, 0x64, 0x38, 0x61, 0x39, 0x31, 0x4b, 0x51, 0x64, 0x63, 0x79, 0x35, 0x6f, + 0x44, 0x50, 0x62, 0x63, 0x46, 0x79, 0x77, 0x61, 0x69, 0x72, 0x4a, 0x79, 0x73, 0x4a, 0x2b, 0x52, 0x75, 0x6a, + 0x51, 0x56, 0x53, 0x70, 0x72, 0x79, 0x6f, 0x30, 0x4c, 0x63, 0x44, 0x67, 0x46, 0x33, 0x4e, 0x55, 0x57, 0x37, + 0x74, 0x5c, 0x0a, + 0x09, 0x61, 0x41, 0x4d, 0x41, 0x77, 0x45, 0x42, 0x4f, 0x4b, 0x31, 0x49, 0x6e, 0x43, 0x4f, 0x74, 0x67, 0x47, + 0x7a, 0x77, 0x6a, 0x62, 0x58, 0x52, 0x42, 0x57, 0x61, 0x46, 0x65, 0x76, 0x4f, 0x5a, 0x59, 0x65, 0x2b, 0x48, + 0x34, 0x4b, 0x50, 0x6b, 0x4f, 0x68, 0x7a, 0x72, 0x54, 0x34, 0x49, 0x46, 0x61, 0x54, 0x44, 0x39, 0x34, 0x74, + 0x42, 0x72, 0x52, 0x5a, 0x70, 0x4b, 0x32, 0x4b, 0x32, 0x66, 0x69, 0x71, 0x58, 0x4d, 0x77, 0x50, 0x70, 0x35, + 0x68, 0x5c, 0x0a, + 0x09, 0x68, 0x44, 0x6f, 0x69, 0x61, 0x75, 0x76, 0x72, 0x44, 0x64, 0x30, 0x6e, 0x37, 0x59, 0x41, 0x42, 0x45, + 0x77, 0x63, 0x6f, 0x48, 0x58, 0x57, 0x35, 0x67, 0x33, 0x44, 0x65, 0x6b, 0x62, 0x59, 0x6c, 0x6a, 0x6b, 0x66, + 0x78, 0x35, 0x57, 0x53, 0x35, 0x6d, 0x47, 0x30, 0x78, 0x70, 0x67, 0x56, 0x51, 0x61, 0x54, 0x36, 0x63, 0x6c, + 0x4c, 0x4f, 0x5a, 0x70, 0x53, 0x48, 0x74, 0x57, 0x2b, 0x43, 0x30, 0x6b, 0x7a, 0x72, 0x57, 0x66, 0x59, 0x58, + 0x72, 0x5c, 0x0a, + 0x09, 0x77, 0x71, 0x6b, 0x56, 0x79, 0x4e, 0x70, 0x7a, 0x66, 0x51, 0x56, 0x71, 0x34, 0x4d, 0x64, 0x37, 0x30, + 0x71, 0x6e, 0x4a, 0x32, 0x74, 0x50, 0x47, 0x54, 0x77, 0x48, 0x4d, 0x4e, 0x4a, 0x45, 0x35, 0x71, 0x58, 0x41, + 0x65, 0x70, 0x35, 0x53, 0x6a, 0x6b, 0x62, 0x67, 0x69, 0x4b, 0x38, 0x32, 0x57, 0x42, 0x64, 0x52, 0x35, 0x35, + 0x6a, 0x68, 0x36, 0x6a, 0x6d, 0x32, 0x6d, 0x74, 0x5a, 0x54, 0x32, 0x49, 0x62, 0x49, 0x56, 0x58, 0x56, 0x62, + 0x78, 0x5c, 0x0a, + 0x09, 0x5a, 0x59, 0x31, 0x64, 0x7a, 0x37, 0x6d, 0x31, 0x51, 0x57, 0x6e, 0x65, 0x65, 0x66, 0x5a, 0x67, 0x6a, + 0x56, 0x31, 0x45, 0x61, 0x78, 0x56, 0x46, 0x6f, 0x32, 0x7a, 0x54, 0x5a, 0x6d, 0x30, 0x6a, 0x5a, 0x41, 0x59, + 0x72, 0x70, 0x67, 0x74, 0x49, 0x35, 0x53, 0x5a, 0x4f, 0x51, 0x6d, 0x55, 0x42, 0x41, 0x62, 0x53, 0x51, 0x79, + 0x69, 0x4a, 0x38, 0x4f, 0x6c, 0x37, 0x66, 0x43, 0x42, 0x61, 0x38, 0x4c, 0x32, 0x73, 0x61, 0x45, 0x4f, 0x54, + 0x53, 0x5c, 0x0a, + 0x09, 0x35, 0x49, 0x42, 0x4f, 0x79, 0x56, 0x67, 0x37, 0x4a, 0x4b, 0x38, 0x54, 0x51, 0x63, 0x2b, 0x77, 0x4c, + 0x77, 0x35, 0x34, 0x49, 0x53, 0x73, 0x52, 0x51, 0x4b, 0x31, 0x73, 0x6a, 0x4f, 0x76, 0x62, 0x6d, 0x6b, 0x71, + 0x73, 0x77, 0x37, 0x50, 0x2f, 0x46, 0x6d, 0x31, 0x63, 0x42, 0x68, 0x43, 0x2f, 0x63, 0x67, 0x64, 0x53, 0x44, + 0x71, 0x6b, 0x52, 0x4e, 0x35, 0x59, 0x33, 0x44, 0x44, 0x2f, 0x4a, 0x42, 0x6e, 0x69, 0x45, 0x4e, 0x76, 0x6f, + 0x4c, 0x5c, 0x0a, + 0x09, 0x6a, 0x68, 0x6b, 0x4d, 0x62, 0x73, 0x56, 0x30, 0x6c, 0x55, 0x63, 0x64, 0x41, 0x2b, 0x6e, 0x44, 0x30, + 0x48, 0x69, 0x6b, 0x35, 0x6b, 0x43, 0x6c, 0x69, 0x54, 0x75, 0x4d, 0x6d, 0x63, 0x36, 0x6a, 0x72, 0x6b, 0x65, + 0x4d, 0x56, 0x35, 0x33, 0x65, 0x57, 0x79, 0x54, 0x41, 0x69, 0x51, 0x4d, 0x6c, 0x62, 0x35, 0x63, 0x5a, 0x71, + 0x41, 0x61, 0x76, 0x78, 0x47, 0x69, 0x5a, 0x7a, 0x4d, 0x53, 0x6e, 0x49, 0x51, 0x63, 0x4f, 0x7a, 0x4b, 0x4a, + 0x39, 0x5c, 0x0a, + 0x09, 0x42, 0x70, 0x7a, 0x63, 0x4f, 0x58, 0x53, 0x35, 0x30, 0x4c, 0x36, 0x59, 0x74, 0x6a, 0x54, 0x49, 0x6e, + 0x6d, 0x63, 0x6f, 0x63, 0x5a, 0x78, 0x4b, 0x42, 0x6c, 0x6f, 0x75, 0x4d, 0x61, 0x4e, 0x67, 0x38, 0x6b, 0x69, + 0x79, 0x47, 0x33, 0x36, 0x42, 0x79, 0x59, 0x70, 0x6e, 0x42, 0x54, 0x77, 0x44, 0x45, 0x48, 0x70, 0x69, 0x50, + 0x4f, 0x69, 0x78, 0x43, 0x5a, 0x59, 0x53, 0x38, 0x4e, 0x71, 0x52, 0x4d, 0x72, 0x7a, 0x32, 0x74, 0x4d, 0x34, + 0x41, 0x5c, 0x0a, + 0x09, 0x6f, 0x46, 0x43, 0x66, 0x43, 0x78, 0x35, 0x6f, 0x6a, 0x74, 0x69, 0x6b, 0x46, 0x4b, 0x48, 0x6e, 0x74, + 0x41, 0x47, 0x42, 0x74, 0x59, 0x45, 0x30, 0x39, 0x63, 0x76, 0x6e, 0x63, 0x6a, 0x70, 0x71, 0x36, 0x66, 0x71, + 0x78, 0x50, 0x4c, 0x75, 0x6d, 0x41, 0x59, 0x46, 0x6e, 0x4b, 0x74, 0x45, 0x41, 0x46, 0x4c, 0x39, 0x57, 0x70, + 0x6d, 0x50, 0x31, 0x5a, 0x55, 0x57, 0x6b, 0x4f, 0x41, 0x78, 0x6d, 0x38, 0x46, 0x62, 0x6d, 0x59, 0x37, 0x55, + 0x62, 0x5c, 0x0a, + 0x09, 0x2b, 0x47, 0x62, 0x73, 0x4a, 0x4f, 0x33, 0x46, 0x63, 0x55, 0x41, 0x61, 0x71, 0x70, 0x56, 0x68, 0x43, + 0x44, 0x6b, 0x78, 0x35, 0x7a, 0x4d, 0x7a, 0x49, 0x6b, 0x4f, 0x33, 0x53, 0x66, 0x2b, 0x51, 0x4f, 0x75, 0x42, + 0x39, 0x4b, 0x2f, 0x2b, 0x58, 0x37, 0x65, 0x69, 0x4c, 0x70, 0x41, 0x70, 0x71, 0x30, 0x67, 0x37, 0x48, 0x48, + 0x5a, 0x4b, 0x6b, 0x6e, 0x48, 0x54, 0x51, 0x74, 0x36, 0x5a, 0x6c, 0x53, 0x52, 0x5a, 0x70, 0x38, 0x51, 0x67, + 0x70, 0x5c, 0x0a, + 0x09, 0x51, 0x35, 0x48, 0x64, 0x4a, 0x4f, 0x31, 0x74, 0x33, 0x34, 0x41, 0x6c, 0x67, 0x41, 0x31, 0x61, 0x42, + 0x42, 0x52, 0x52, 0x7a, 0x48, 0x42, 0x4f, 0x67, 0x65, 0x78, 0x47, 0x76, 0x57, 0x67, 0x63, 0x77, 0x66, 0x43, + 0x59, 0x51, 0x35, 0x67, 0x47, 0x36, 0x53, 0x41, 0x64, 0x52, 0x6a, 0x75, 0x52, 0x69, 0x68, 0x7a, 0x57, 0x33, + 0x43, 0x2b, 0x32, 0x68, 0x62, 0x71, 0x4e, 0x5a, 0x47, 0x35, 0x76, 0x39, 0x4b, 0x6c, 0x54, 0x58, 0x64, 0x57, + 0x45, 0x5c, 0x0a, + 0x09, 0x62, 0x55, 0x44, 0x71, 0x65, 0x77, 0x49, 0x65, 0x54, 0x73, 0x6e, 0x48, 0x73, 0x54, 0x2b, 0x6f, 0x73, + 0x52, 0x6b, 0x4e, 0x57, 0x38, 0x44, 0x44, 0x51, 0x54, 0x57, 0x43, 0x6e, 0x5a, 0x5a, 0x62, 0x77, 0x78, 0x68, + 0x6a, 0x4a, 0x61, 0x54, 0x6c, 0x56, 0x35, 0x72, 0x32, 0x43, 0x4c, 0x6d, 0x7a, 0x76, 0x72, 0x6e, 0x73, 0x43, + 0x49, 0x59, 0x74, 0x42, 0x42, 0x35, 0x56, 0x74, 0x72, 0x44, 0x53, 0x74, 0x45, 0x39, 0x63, 0x5a, 0x7a, 0x72, + 0x55, 0x5c, 0x0a, + 0x09, 0x77, 0x4b, 0x65, 0x72, 0x4a, 0x6e, 0x4a, 0x77, 0x61, 0x56, 0x6b, 0x74, 0x43, 0x32, 0x4c, 0x6e, 0x75, + 0x65, 0x35, 0x46, 0x4e, 0x68, 0x5a, 0x70, 0x68, 0x77, 0x6e, 0x36, 0x61, 0x30, 0x77, 0x62, 0x41, 0x77, 0x43, + 0x6d, 0x30, 0x43, 0x43, 0x64, 0x44, 0x51, 0x33, 0x43, 0x46, 0x6e, 0x4d, 0x73, 0x35, 0x66, 0x6a, 0x52, 0x38, + 0x4b, 0x73, 0x36, 0x4f, 0x6c, 0x33, 0x6d, 0x68, 0x75, 0x52, 0x55, 0x6d, 0x31, 0x59, 0x30, 0x74, 0x4f, 0x61, + 0x52, 0x5c, 0x0a, + 0x09, 0x65, 0x69, 0x37, 0x6e, 0x47, 0x70, 0x54, 0x4e, 0x30, 0x32, 0x51, 0x78, 0x70, 0x32, 0x53, 0x52, 0x79, + 0x71, 0x6d, 0x32, 0x64, 0x63, 0x71, 0x75, 0x35, 0x53, 0x49, 0x69, 0x69, 0x53, 0x61, 0x53, 0x39, 0x54, 0x69, + 0x49, 0x78, 0x67, 0x79, 0x4b, 0x39, 0x78, 0x4d, 0x48, 0x78, 0x49, 0x7a, 0x66, 0x4b, 0x47, 0x4e, 0x46, 0x37, + 0x69, 0x5a, 0x51, 0x34, 0x50, 0x33, 0x79, 0x39, 0x6a, 0x57, 0x77, 0x78, 0x33, 0x4a, 0x38, 0x54, 0x45, 0x79, + 0x4f, 0x5c, 0x0a, + 0x09, 0x44, 0x55, 0x6d, 0x48, 0x48, 0x43, 0x37, 0x76, 0x45, 0x7a, 0x4a, 0x71, 0x43, 0x36, 0x42, 0x6c, 0x6c, + 0x55, 0x66, 0x50, 0x77, 0x52, 0x45, 0x7a, 0x4e, 0x36, 0x66, 0x4f, 0x63, 0x2f, 0x41, 0x51, 0x30, 0x31, 0x54, + 0x44, 0x52, 0x71, 0x30, 0x70, 0x6b, 0x35, 0x42, 0x76, 0x67, 0x34, 0x31, 0x68, 0x55, 0x30, 0x77, 0x42, 0x6d, + 0x4a, 0x43, 0x34, 0x34, 0x31, 0x6b, 0x49, 0x6e, 0x67, 0x67, 0x59, 0x68, 0x6d, 0x49, 0x67, 0x36, 0x34, 0x6a, + 0x72, 0x5c, 0x0a, + 0x09, 0x34, 0x62, 0x77, 0x32, 0x56, 0x43, 0x65, 0x2f, 0x38, 0x72, 0x62, 0x44, 0x5a, 0x36, 0x4f, 0x68, 0x4f, + 0x48, 0x6c, 0x4f, 0x74, 0x4b, 0x47, 0x63, 0x4c, 0x36, 0x34, 0x72, 0x49, 0x44, 0x30, 0x57, 0x55, 0x55, 0x2b, + 0x50, 0x6b, 0x62, 0x4f, 0x71, 0x51, 0x63, 0x43, 0x4b, 0x63, 0x67, 0x77, 0x77, 0x7a, 0x4f, 0x6b, 0x4c, 0x62, + 0x38, 0x63, 0x5a, 0x35, 0x78, 0x56, 0x6f, 0x38, 0x6a, 0x47, 0x46, 0x4b, 0x45, 0x75, 0x42, 0x62, 0x77, 0x36, + 0x32, 0x5c, 0x0a, + 0x09, 0x6a, 0x4e, 0x65, 0x6d, 0x4b, 0x51, 0x73, 0x66, 0x54, 0x35, 0x4c, 0x70, 0x36, 0x59, 0x34, 0x67, 0x5a, + 0x53, 0x6c, 0x30, 0x79, 0x68, 0x72, 0x6a, 0x6d, 0x59, 0x6b, 0x31, 0x42, 0x34, 0x63, 0x71, 0x6e, 0x2b, 0x67, + 0x6c, 0x5a, 0x53, 0x63, 0x42, 0x63, 0x57, 0x73, 0x51, 0x57, 0x76, 0x39, 0x36, 0x4b, 0x68, 0x64, 0x45, 0x30, + 0x42, 0x54, 0x63, 0x6d, 0x73, 0x43, 0x70, 0x4c, 0x6e, 0x39, 0x63, 0x34, 0x35, 0x52, 0x75, 0x44, 0x57, 0x6c, + 0x64, 0x5c, 0x0a, + 0x09, 0x66, 0x68, 0x35, 0x63, 0x6b, 0x68, 0x73, 0x4b, 0x35, 0x77, 0x64, 0x53, 0x6f, 0x53, 0x56, 0x52, 0x52, + 0x31, 0x39, 0x48, 0x37, 0x53, 0x41, 0x6a, 0x31, 0x77, 0x30, 0x67, 0x46, 0x52, 0x4d, 0x56, 0x4c, 0x62, 0x7a, + 0x4d, 0x42, 0x68, 0x43, 0x72, 0x66, 0x38, 0x66, 0x71, 0x63, 0x73, 0x63, 0x57, 0x76, 0x44, 0x44, 0x6a, 0x31, + 0x4f, 0x32, 0x4a, 0x63, 0x38, 0x46, 0x6f, 0x56, 0x48, 0x38, 0x38, 0x43, 0x78, 0x44, 0x76, 0x42, 0x56, 0x4f, + 0x6b, 0x5c, 0x0a, + 0x09, 0x78, 0x35, 0x35, 0x6b, 0x46, 0x77, 0x59, 0x50, 0x33, 0x45, 0x38, 0x46, 0x2b, 0x50, 0x4a, 0x2b, 0x32, + 0x58, 0x6a, 0x6a, 0x64, 0x52, 0x4b, 0x6e, 0x54, 0x56, 0x6b, 0x4c, 0x4a, 0x7a, 0x4c, 0x47, 0x4a, 0x4d, 0x42, + 0x4d, 0x44, 0x34, 0x61, 0x4e, 0x4f, 0x59, 0x52, 0x79, 0x70, 0x36, 0x2b, 0x6a, 0x6c, 0x6c, 0x65, 0x69, 0x4a, + 0x32, 0x4d, 0x73, 0x59, 0x72, 0x6f, 0x45, 0x6f, 0x33, 0x2b, 0x6c, 0x6c, 0x31, 0x41, 0x32, 0x6d, 0x61, 0x61, + 0x4a, 0x5c, 0x0a, + 0x09, 0x4c, 0x7a, 0x44, 0x31, 0x78, 0x6a, 0x50, 0x50, 0x61, 0x41, 0x75, 0x68, 0x69, 0x36, 0x42, 0x4c, 0x4a, + 0x51, 0x50, 0x6e, 0x5a, 0x46, 0x6d, 0x48, 0x37, 0x56, 0x6f, 0x71, 0x36, 0x30, 0x45, 0x62, 0x41, 0x41, 0x41, + 0x30, 0x4b, 0x35, 0x53, 0x69, 0x6a, 0x5a, 0x69, 0x66, 0x74, 0x2b, 0x62, 0x6a, 0x34, 0x50, 0x57, 0x55, 0x73, + 0x65, 0x74, 0x79, 0x54, 0x63, 0x66, 0x63, 0x4f, 0x49, 0x51, 0x6a, 0x4e, 0x2f, 0x53, 0x6e, 0x76, 0x7a, 0x64, + 0x47, 0x5c, 0x0a, + 0x09, 0x43, 0x71, 0x4f, 0x65, 0x64, 0x67, 0x77, 0x65, 0x74, 0x55, 0x52, 0x6b, 0x59, 0x32, 0x58, 0x45, 0x4d, + 0x61, 0x75, 0x76, 0x73, 0x77, 0x38, 0x64, 0x42, 0x54, 0x6e, 0x41, 0x43, 0x58, 0x42, 0x6c, 0x52, 0x67, 0x6a, + 0x56, 0x6a, 0x67, 0x6c, 0x34, 0x51, 0x47, 0x4b, 0x34, 0x54, 0x62, 0x4b, 0x77, 0x31, 0x6a, 0x70, 0x45, 0x47, + 0x5a, 0x61, 0x5a, 0x6d, 0x46, 0x45, 0x64, 0x53, 0x70, 0x38, 0x61, 0x74, 0x48, 0x54, 0x37, 0x72, 0x4b, 0x34, + 0x46, 0x5c, 0x0a, + 0x09, 0x58, 0x73, 0x6c, 0x30, 0x69, 0x34, 0x31, 0x48, 0x41, 0x42, 0x70, 0x33, 0x57, 0x4d, 0x55, 0x7a, 0x7a, + 0x33, 0x70, 0x41, 0x69, 0x6c, 0x39, 0x4b, 0x65, 0x54, 0x66, 0x37, 0x55, 0x2f, 0x4a, 0x77, 0x71, 0x6e, 0x2b, + 0x6d, 0x74, 0x71, 0x72, 0x39, 0x48, 0x66, 0x62, 0x55, 0x62, 0x6d, 0x31, 0x70, 0x59, 0x2b, 0x34, 0x43, 0x56, + 0x43, 0x43, 0x66, 0x52, 0x69, 0x42, 0x75, 0x2f, 0x4c, 0x77, 0x61, 0x53, 0x59, 0x50, 0x51, 0x78, 0x69, 0x30, + 0x63, 0x5c, 0x0a, + 0x09, 0x77, 0x39, 0x56, 0x47, 0x77, 0x39, 0x4e, 0x46, 0x33, 0x56, 0x37, 0x67, 0x70, 0x39, 0x48, 0x4a, 0x6c, + 0x66, 0x45, 0x4b, 0x78, 0x70, 0x46, 0x65, 0x34, 0x38, 0x72, 0x56, 0x35, 0x2b, 0x50, 0x59, 0x47, 0x75, 0x70, + 0x47, 0x30, 0x5a, 0x41, 0x79, 0x46, 0x4d, 0x34, 0x54, 0x42, 0x79, 0x2b, 0x53, 0x4d, 0x74, 0x47, 0x67, 0x43, + 0x63, 0x56, 0x37, 0x37, 0x46, 0x62, 0x31, 0x36, 0x64, 0x68, 0x46, 0x34, 0x52, 0x68, 0x4b, 0x43, 0x5a, 0x61, + 0x4d, 0x5c, 0x0a, + 0x09, 0x64, 0x4e, 0x75, 0x79, 0x55, 0x61, 0x59, 0x44, 0x53, 0x46, 0x35, 0x35, 0x65, 0x39, 0x79, 0x35, 0x2b, + 0x54, 0x52, 0x45, 0x52, 0x32, 0x44, 0x6c, 0x78, 0x79, 0x5a, 0x6f, 0x4f, 0x39, 0x56, 0x75, 0x4d, 0x72, 0x33, + 0x51, 0x51, 0x44, 0x61, 0x43, 0x70, 0x38, 0x69, 0x62, 0x30, 0x61, 0x2b, 0x65, 0x56, 0x67, 0x56, 0x67, 0x62, + 0x6e, 0x4a, 0x65, 0x61, 0x2f, 0x71, 0x52, 0x54, 0x4d, 0x30, 0x41, 0x67, 0x48, 0x61, 0x73, 0x47, 0x46, 0x6a, + 0x57, 0x5c, 0x0a, + 0x09, 0x67, 0x44, 0x5a, 0x6d, 0x44, 0x51, 0x42, 0x49, 0x6a, 0x5a, 0x79, 0x66, 0x35, 0x38, 0x61, 0x65, 0x54, + 0x41, 0x2f, 0x59, 0x73, 0x61, 0x2f, 0x41, 0x4b, 0x30, 0x4d, 0x34, 0x42, 0x37, 0x48, 0x76, 0x47, 0x67, 0x78, + 0x30, 0x4e, 0x45, 0x31, 0x59, 0x56, 0x55, 0x59, 0x56, 0x69, 0x7a, 0x61, 0x42, 0x52, 0x35, 0x50, 0x6a, 0x57, + 0x71, 0x51, 0x41, 0x4c, 0x62, 0x52, 0x72, 0x31, 0x59, 0x30, 0x47, 0x62, 0x6b, 0x52, 0x52, 0x43, 0x30, 0x68, + 0x34, 0x5c, 0x0a, + 0x09, 0x48, 0x38, 0x5a, 0x68, 0x57, 0x70, 0x36, 0x44, 0x71, 0x4d, 0x6f, 0x55, 0x64, 0x48, 0x6c, 0x75, 0x75, + 0x4a, 0x77, 0x2f, 0x37, 0x58, 0x67, 0x63, 0x6a, 0x41, 0x52, 0x59, 0x75, 0x4c, 0x53, 0x4e, 0x42, 0x4d, 0x51, + 0x74, 0x5a, 0x2b, 0x4a, 0x39, 0x42, 0x52, 0x6d, 0x4d, 0x41, 0x43, 0x55, 0x4e, 0x47, 0x4c, 0x79, 0x2f, 0x42, + 0x49, 0x53, 0x4e, 0x64, 0x6f, 0x54, 0x39, 0x71, 0x43, 0x49, 0x61, 0x64, 0x42, 0x57, 0x4c, 0x63, 0x69, 0x78, + 0x41, 0x5c, 0x0a, + 0x09, 0x59, 0x67, 0x50, 0x4e, 0x31, 0x37, 0x62, 0x44, 0x72, 0x63, 0x39, 0x50, 0x67, 0x6e, 0x50, 0x61, 0x69, + 0x4a, 0x32, 0x41, 0x38, 0x2b, 0x4b, 0x72, 0x6d, 0x48, 0x74, 0x43, 0x47, 0x54, 0x73, 0x37, 0x46, 0x38, 0x73, + 0x71, 0x67, 0x7a, 0x49, 0x58, 0x74, 0x70, 0x41, 0x61, 0x65, 0x6b, 0x44, 0x70, 0x42, 0x48, 0x67, 0x61, 0x44, + 0x44, 0x36, 0x5a, 0x45, 0x75, 0x68, 0x50, 0x78, 0x71, 0x75, 0x49, 0x58, 0x69, 0x4d, 0x63, 0x71, 0x44, 0x46, + 0x4e, 0x5c, 0x0a, + 0x09, 0x68, 0x67, 0x51, 0x33, 0x71, 0x31, 0x35, 0x6a, 0x6d, 0x37, 0x77, 0x78, 0x4a, 0x2b, 0x58, 0x48, 0x54, + 0x73, 0x65, 0x79, 0x56, 0x76, 0x6f, 0x66, 0x49, 0x78, 0x75, 0x37, 0x5a, 0x67, 0x49, 0x4f, 0x6a, 0x4c, 0x61, + 0x56, 0x51, 0x2b, 0x74, 0x30, 0x6e, 0x59, 0x39, 0x4c, 0x4f, 0x4a, 0x55, 0x47, 0x62, 0x68, 0x68, 0x6a, 0x4e, + 0x50, 0x51, 0x62, 0x39, 0x4a, 0x2f, 0x49, 0x56, 0x59, 0x4f, 0x49, 0x34, 0x74, 0x2f, 0x53, 0x75, 0x38, 0x57, + 0x2f, 0x5c, 0x0a, + 0x09, 0x36, 0x45, 0x76, 0x4a, 0x6d, 0x64, 0x74, 0x71, 0x46, 0x42, 0x66, 0x50, 0x58, 0x6b, 0x4c, 0x42, 0x4a, + 0x6a, 0x32, 0x4d, 0x41, 0x47, 0x7a, 0x6e, 0x2b, 0x69, 0x42, 0x61, 0x39, 0x79, 0x63, 0x43, 0x31, 0x78, 0x63, + 0x41, 0x66, 0x4b, 0x51, 0x62, 0x78, 0x4f, 0x39, 0x61, 0x59, 0x53, 0x49, 0x71, 0x73, 0x50, 0x4f, 0x78, 0x76, + 0x69, 0x6f, 0x54, 0x46, 0x42, 0x44, 0x62, 0x63, 0x72, 0x61, 0x42, 0x36, 0x62, 0x6d, 0x69, 0x6a, 0x6b, 0x70, + 0x4a, 0x5c, 0x0a, + 0x09, 0x32, 0x2b, 0x70, 0x37, 0x34, 0x49, 0x55, 0x44, 0x6b, 0x49, 0x35, 0x79, 0x6f, 0x59, 0x77, 0x59, 0x72, + 0x48, 0x4a, 0x71, 0x66, 0x59, 0x33, 0x4c, 0x49, 0x59, 0x78, 0x46, 0x52, 0x35, 0x30, 0x6d, 0x6f, 0x34, 0x6c, + 0x70, 0x4a, 0x77, 0x63, 0x32, 0x4e, 0x65, 0x35, 0x45, 0x46, 0x73, 0x47, 0x41, 0x56, 0x65, 0x51, 0x6a, 0x56, + 0x55, 0x2b, 0x33, 0x77, 0x38, 0x76, 0x78, 0x39, 0x6e, 0x53, 0x47, 0x46, 0x76, 0x6c, 0x69, 0x30, 0x56, 0x57, + 0x6e, 0x5c, 0x0a, + 0x09, 0x78, 0x35, 0x5a, 0x7a, 0x57, 0x56, 0x6c, 0x47, 0x77, 0x6a, 0x4e, 0x6e, 0x54, 0x76, 0x48, 0x51, 0x5a, + 0x43, 0x4f, 0x69, 0x54, 0x64, 0x32, 0x75, 0x71, 0x38, 0x65, 0x64, 0x5a, 0x4a, 0x6b, 0x4b, 0x47, 0x49, 0x4f, + 0x63, 0x2b, 0x54, 0x6d, 0x77, 0x63, 0x35, 0x77, 0x34, 0x6b, 0x4f, 0x6f, 0x73, 0x30, 0x77, 0x52, 0x79, 0x59, + 0x66, 0x4e, 0x54, 0x61, 0x59, 0x4e, 0x72, 0x53, 0x2b, 0x75, 0x66, 0x41, 0x54, 0x68, 0x33, 0x52, 0x45, 0x62, + 0x39, 0x5c, 0x0a, + 0x09, 0x52, 0x41, 0x68, 0x41, 0x34, 0x68, 0x77, 0x73, 0x73, 0x6f, 0x6a, 0x55, 0x53, 0x30, 0x55, 0x44, 0x78, + 0x2b, 0x72, 0x71, 0x43, 0x4b, 0x47, 0x56, 0x6c, 0x6b, 0x51, 0x72, 0x31, 0x50, 0x55, 0x63, 0x71, 0x37, 0x66, + 0x79, 0x65, 0x47, 0x72, 0x2b, 0x59, 0x2f, 0x31, 0x67, 0x42, 0x4f, 0x46, 0x50, 0x52, 0x54, 0x4a, 0x68, 0x55, + 0x49, 0x78, 0x33, 0x41, 0x55, 0x70, 0x38, 0x7a, 0x4d, 0x6f, 0x4a, 0x74, 0x43, 0x4f, 0x69, 0x34, 0x54, 0x76, + 0x6e, 0x5c, 0x0a, + 0x09, 0x4c, 0x33, 0x5a, 0x43, 0x7a, 0x4c, 0x41, 0x4e, 0x51, 0x34, 0x34, 0x79, 0x55, 0x61, 0x43, 0x6a, 0x77, + 0x55, 0x54, 0x4c, 0x54, 0x71, 0x54, 0x67, 0x66, 0x47, 0x77, 0x47, 0x65, 0x49, 0x6d, 0x49, 0x61, 0x52, 0x43, + 0x66, 0x6a, 0x69, 0x52, 0x41, 0x51, 0x51, 0x33, 0x6a, 0x5a, 0x76, 0x78, 0x5a, 0x55, 0x37, 0x4f, 0x45, 0x4c, + 0x36, 0x34, 0x62, 0x59, 0x33, 0x7a, 0x63, 0x4a, 0x76, 0x55, 0x34, 0x72, 0x53, 0x44, 0x52, 0x6c, 0x4b, 0x48, + 0x70, 0x5c, 0x0a, + 0x09, 0x63, 0x33, 0x72, 0x36, 0x4a, 0x4f, 0x31, 0x67, 0x71, 0x79, 0x57, 0x4f, 0x74, 0x61, 0x54, 0x31, 0x42, + 0x77, 0x43, 0x69, 0x49, 0x6b, 0x33, 0x46, 0x74, 0x4f, 0x4d, 0x62, 0x54, 0x68, 0x6b, 0x6a, 0x53, 0x39, 0x4a, + 0x65, 0x72, 0x59, 0x7a, 0x6f, 0x61, 0x30, 0x59, 0x45, 0x69, 0x46, 0x2b, 0x64, 0x62, 0x61, 0x68, 0x4e, 0x63, + 0x7a, 0x37, 0x42, 0x46, 0x2b, 0x2f, 0x54, 0x55, 0x43, 0x4b, 0x2f, 0x6c, 0x6a, 0x69, 0x59, 0x59, 0x61, 0x41, + 0x36, 0x5c, 0x0a, + 0x09, 0x62, 0x62, 0x59, 0x69, 0x55, 0x65, 0x4b, 0x6b, 0x4b, 0x6e, 0x72, 0x7a, 0x38, 0x68, 0x47, 0x4d, 0x51, + 0x6a, 0x6b, 0x4e, 0x63, 0x47, 0x70, 0x38, 0x53, 0x63, 0x6f, 0x4c, 0x31, 0x71, 0x63, 0x46, 0x66, 0x69, 0x73, + 0x41, 0x59, 0x71, 0x7a, 0x72, 0x32, 0x4a, 0x43, 0x4a, 0x73, 0x61, 0x34, 0x69, 0x59, 0x57, 0x4e, 0x6d, 0x77, + 0x35, 0x31, 0x66, 0x79, 0x55, 0x37, 0x55, 0x59, 0x57, 0x50, 0x56, 0x6d, 0x52, 0x77, 0x72, 0x49, 0x6a, 0x36, + 0x62, 0x5c, 0x0a, + 0x09, 0x5a, 0x4a, 0x4a, 0x6b, 0x68, 0x4c, 0x79, 0x62, 0x45, 0x57, 0x6a, 0x46, 0x78, 0x38, 0x7a, 0x50, 0x78, + 0x58, 0x70, 0x4f, 0x6c, 0x72, 0x4d, 0x79, 0x6c, 0x2f, 0x72, 0x38, 0x74, 0x75, 0x61, 0x4f, 0x31, 0x6f, 0x62, + 0x57, 0x2b, 0x59, 0x31, 0x41, 0x42, 0x41, 0x43, 0x48, 0x45, 0x6b, 0x4e, 0x76, 0x69, 0x6b, 0x54, 0x68, 0x4d, + 0x7a, 0x71, 0x34, 0x5a, 0x59, 0x41, 0x4e, 0x55, 0x53, 0x46, 0x65, 0x43, 0x2f, 0x32, 0x53, 0x4b, 0x43, 0x37, + 0x36, 0x5c, 0x0a, + 0x09, 0x34, 0x46, 0x6d, 0x46, 0x6e, 0x6a, 0x4e, 0x79, 0x5a, 0x78, 0x67, 0x31, 0x44, 0x39, 0x62, 0x58, 0x74, + 0x4a, 0x47, 0x76, 0x5a, 0x45, 0x51, 0x6d, 0x61, 0x52, 0x43, 0x6f, 0x6d, 0x4e, 0x56, 0x74, 0x36, 0x55, 0x67, + 0x56, 0x4d, 0x67, 0x79, 0x72, 0x79, 0x77, 0x43, 0x69, 0x53, 0x62, 0x62, 0x56, 0x59, 0x4d, 0x44, 0x57, 0x57, + 0x4b, 0x76, 0x6d, 0x61, 0x38, 0x66, 0x54, 0x35, 0x58, 0x54, 0x32, 0x6f, 0x2f, 0x6a, 0x55, 0x57, 0x56, 0x4f, + 0x55, 0x5c, 0x0a, + 0x09, 0x76, 0x33, 0x49, 0x57, 0x69, 0x33, 0x38, 0x39, 0x56, 0x64, 0x48, 0x70, 0x74, 0x67, 0x6b, 0x75, 0x4b, + 0x6f, 0x43, 0x4d, 0x42, 0x42, 0x34, 0x32, 0x68, 0x4b, 0x5a, 0x72, 0x75, 0x6b, 0x43, 0x59, 0x35, 0x76, 0x42, + 0x41, 0x45, 0x2f, 0x58, 0x52, 0x6f, 0x41, 0x65, 0x37, 0x33, 0x66, 0x2f, 0x6f, 0x47, 0x59, 0x41, 0x44, 0x41, + 0x50, 0x57, 0x4c, 0x48, 0x70, 0x41, 0x4f, 0x6d, 0x4b, 0x52, 0x6b, 0x59, 0x45, 0x37, 0x4c, 0x49, 0x36, 0x57, + 0x46, 0x5c, 0x0a, + 0x09, 0x31, 0x46, 0x43, 0x52, 0x56, 0x42, 0x6d, 0x79, 0x52, 0x75, 0x41, 0x6d, 0x51, 0x33, 0x4f, 0x36, 0x4c, + 0x33, 0x55, 0x78, 0x4d, 0x52, 0x62, 0x56, 0x4a, 0x71, 0x63, 0x59, 0x6a, 0x64, 0x56, 0x6e, 0x59, 0x38, 0x52, + 0x69, 0x2f, 0x54, 0x5a, 0x46, 0x6f, 0x53, 0x52, 0x79, 0x4f, 0x2f, 0x61, 0x6e, 0x73, 0x78, 0x50, 0x49, 0x64, + 0x6b, 0x6a, 0x58, 0x35, 0x32, 0x55, 0x61, 0x67, 0x4d, 0x7a, 0x71, 0x4f, 0x7a, 0x69, 0x34, 0x54, 0x6d, 0x4d, + 0x31, 0x5c, 0x0a, + 0x09, 0x62, 0x79, 0x6f, 0x34, 0x31, 0x6d, 0x32, 0x51, 0x4c, 0x43, 0x50, 0x47, 0x61, 0x79, 0x68, 0x45, 0x70, + 0x2f, 0x56, 0x38, 0x71, 0x74, 0x4b, 0x49, 0x72, 0x59, 0x36, 0x31, 0x47, 0x2b, 0x53, 0x71, 0x78, 0x6d, 0x53, + 0x42, 0x61, 0x52, 0x79, 0x66, 0x64, 0x62, 0x37, 0x68, 0x6e, 0x43, 0x56, 0x72, 0x66, 0x63, 0x30, 0x71, 0x4c, + 0x77, 0x46, 0x72, 0x45, 0x36, 0x77, 0x42, 0x77, 0x42, 0x33, 0x78, 0x48, 0x30, 0x41, 0x30, 0x49, 0x42, 0x47, + 0x52, 0x5c, 0x0a, + 0x09, 0x64, 0x42, 0x62, 0x41, 0x42, 0x4b, 0x75, 0x64, 0x50, 0x52, 0x54, 0x58, 0x44, 0x73, 0x54, 0x2f, 0x41, + 0x42, 0x59, 0x68, 0x57, 0x55, 0x56, 0x7a, 0x48, 0x73, 0x6c, 0x5a, 0x4c, 0x54, 0x62, 0x5a, 0x31, 0x77, 0x41, + 0x41, 0x49, 0x41, 0x42, 0x4a, 0x52, 0x45, 0x46, 0x55, 0x73, 0x42, 0x54, 0x4f, 0x2b, 0x7a, 0x57, 0x4d, 0x53, + 0x47, 0x63, 0x57, 0x59, 0x70, 0x79, 0x38, 0x41, 0x49, 0x76, 0x59, 0x41, 0x6d, 0x53, 0x63, 0x35, 0x46, 0x48, + 0x7a, 0x5c, 0x0a, + 0x09, 0x5a, 0x34, 0x31, 0x4c, 0x70, 0x38, 0x6c, 0x57, 0x4e, 0x68, 0x4c, 0x61, 0x46, 0x71, 0x6b, 0x31, 0x34, + 0x35, 0x55, 0x55, 0x58, 0x78, 0x7a, 0x38, 0x72, 0x44, 0x55, 0x42, 0x4b, 0x7a, 0x4f, 0x49, 0x38, 0x6f, 0x58, + 0x73, 0x33, 0x77, 0x4c, 0x52, 0x70, 0x6d, 0x78, 0x49, 0x4f, 0x35, 0x45, 0x41, 0x2b, 0x69, 0x5a, 0x48, 0x56, + 0x63, 0x64, 0x69, 0x36, 0x73, 0x4d, 0x64, 0x54, 0x39, 0x6d, 0x58, 0x7a, 0x76, 0x52, 0x57, 0x36, 0x71, 0x38, + 0x4a, 0x5c, 0x0a, + 0x09, 0x73, 0x44, 0x56, 0x50, 0x54, 0x64, 0x6c, 0x63, 0x6f, 0x68, 0x66, 0x56, 0x6e, 0x71, 0x2b, 0x33, 0x37, + 0x68, 0x6e, 0x41, 0x75, 0x75, 0x34, 0x45, 0x2f, 0x4f, 0x67, 0x58, 0x76, 0x34, 0x35, 0x4c, 0x4c, 0x6a, 0x68, + 0x76, 0x6b, 0x46, 0x7a, 0x51, 0x55, 0x34, 0x4a, 0x77, 0x4c, 0x6a, 0x48, 0x41, 0x32, 0x73, 0x6a, 0x76, 0x66, + 0x4f, 0x41, 0x77, 0x48, 0x49, 0x43, 0x35, 0x68, 0x53, 0x55, 0x4d, 0x42, 0x6b, 0x4d, 0x4d, 0x69, 0x77, 0x4a, + 0x7a, 0x5c, 0x0a, + 0x09, 0x43, 0x2f, 0x37, 0x31, 0x30, 0x51, 0x65, 0x50, 0x7a, 0x4b, 0x4d, 0x73, 0x53, 0x79, 0x77, 0x4f, 0x6c, + 0x6a, 0x45, 0x6f, 0x53, 0x73, 0x41, 0x35, 0x7a, 0x43, 0x30, 0x75, 0x59, 0x54, 0x6a, 0x30, 0x79, 0x63, 0x66, + 0x43, 0x30, 0x67, 0x44, 0x4c, 0x52, 0x51, 0x45, 0x69, 0x77, 0x73, 0x4c, 0x69, 0x41, 0x4d, 0x76, 0x44, 0x6f, + 0x54, 0x38, 0x65, 0x4c, 0x47, 0x4e, 0x59, 0x2b, 0x4e, 0x2b, 0x63, 0x57, 0x31, 0x77, 0x75, 0x2f, 0x48, 0x6e, + 0x34, 0x5c, 0x0a, + 0x09, 0x39, 0x38, 0x30, 0x76, 0x4c, 0x41, 0x31, 0x51, 0x73, 0x4e, 0x2f, 0x30, 0x49, 0x79, 0x49, 0x4d, 0x6c, + 0x6f, 0x64, 0x59, 0x4c, 0x6f, 0x71, 0x4b, 0x52, 0x63, 0x39, 0x33, 0x55, 0x54, 0x67, 0x73, 0x4c, 0x43, 0x2f, + 0x4c, 0x78, 0x45, 0x55, 0x62, 0x6d, 0x61, 0x74, 0x2b, 0x30, 0x70, 0x4a, 0x46, 0x53, 0x77, 0x65, 0x67, 0x6b, + 0x32, 0x55, 0x59, 0x36, 0x33, 0x57, 0x71, 0x39, 0x76, 0x77, 0x76, 0x36, 0x50, 0x61, 0x36, 0x4f, 0x62, 0x71, + 0x35, 0x5c, 0x0a, + 0x09, 0x2f, 0x34, 0x6e, 0x73, 0x69, 0x62, 0x45, 0x2b, 0x38, 0x69, 0x7a, 0x48, 0x6c, 0x72, 0x45, 0x65, 0x4a, + 0x73, 0x66, 0x48, 0x4d, 0x44, 0x6e, 0x65, 0x77, 0x37, 0x59, 0x74, 0x6b, 0x39, 0x69, 0x7a, 0x66, 0x51, 0x70, + 0x37, 0x54, 0x39, 0x79, 0x4a, 0x2f, 0x53, 0x66, 0x74, 0x78, 0x72, 0x62, 0x4a, 0x76, 0x68, 0x49, 0x75, 0x63, + 0x2f, 0x41, 0x6f, 0x5a, 0x70, 0x56, 0x64, 0x61, 0x52, 0x37, 0x6a, 0x4e, 0x59, 0x63, 0x62, 0x37, 0x33, 0x6f, + 0x51, 0x5c, 0x0a, + 0x09, 0x63, 0x43, 0x58, 0x32, 0x6e, 0x37, 0x51, 0x4c, 0x41, 0x2b, 0x51, 0x34, 0x50, 0x4c, 0x75, 0x41, 0x65, + 0x2b, 0x38, 0x2f, 0x69, 0x41, 0x64, 0x6e, 0x5a, 0x72, 0x47, 0x77, 0x4f, 0x4d, 0x44, 0x69, 0x59, 0x49, 0x41, + 0x6a, 0x63, 0x77, 0x73, 0x6f, 0x69, 0x54, 0x41, 0x33, 0x76, 0x2b, 0x6a, 0x6c, 0x42, 0x32, 0x43, 0x35, 0x4b, + 0x4c, 0x43, 0x77, 0x4e, 0x49, 0x69, 0x79, 0x30, 0x6d, 0x2b, 0x66, 0x46, 0x75, 0x2f, 0x6f, 0x72, 0x36, 0x35, + 0x52, 0x5c, 0x0a, + 0x09, 0x42, 0x5a, 0x4b, 0x48, 0x35, 0x78, 0x59, 0x41, 0x35, 0x37, 0x42, 0x6c, 0x59, 0x68, 0x7a, 0x73, 0x42, + 0x35, 0x31, 0x5a, 0x58, 0x57, 0x43, 0x73, 0x32, 0x30, 0x4d, 0x6e, 0x39, 0x7a, 0x2f, 0x68, 0x54, 0x6c, 0x55, + 0x62, 0x2f, 0x72, 0x63, 0x42, 0x67, 0x47, 0x36, 0x65, 0x59, 0x33, 0x4b, 0x38, 0x4c, 0x38, 0x59, 0x30, 0x4f, + 0x64, 0x5a, 0x48, 0x48, 0x6e, 0x2b, 0x43, 0x50, 0x4d, 0x50, 0x30, 0x6c, 0x76, 0x70, 0x48, 0x55, 0x48, 0x75, + 0x64, 0x5c, 0x0a, + 0x09, 0x48, 0x4f, 0x50, 0x39, 0x58, 0x6d, 0x78, 0x37, 0x79, 0x2f, 0x67, 0x34, 0x75, 0x74, 0x30, 0x73, 0x36, + 0x6d, 0x6a, 0x58, 0x74, 0x71, 0x33, 0x6f, 0x5a, 0x70, 0x42, 0x5a, 0x6f, 0x78, 0x43, 0x78, 0x71, 0x32, 0x55, + 0x72, 0x67, 0x68, 0x6d, 0x37, 0x72, 0x76, 0x57, 0x68, 0x70, 0x30, 0x47, 0x2b, 0x34, 0x74, 0x51, 0x4e, 0x74, + 0x39, 0x2b, 0x4c, 0x4d, 0x38, 0x37, 0x43, 0x75, 0x74, 0x45, 0x36, 0x41, 0x38, 0x44, 0x56, 0x65, 0x50, 0x6b, + 0x66, 0x5c, 0x0a, + 0x09, 0x2f, 0x4f, 0x58, 0x55, 0x39, 0x35, 0x2f, 0x33, 0x79, 0x48, 0x4b, 0x38, 0x33, 0x38, 0x6b, 0x57, 0x6c, + 0x70, 0x5a, 0x52, 0x6c, 0x47, 0x56, 0x30, 0x72, 0x71, 0x58, 0x42, 0x4d, 0x70, 0x61, 0x4c, 0x41, 0x6f, 0x50, + 0x43, 0x2f, 0x30, 0x6a, 0x6b, 0x30, 0x76, 0x49, 0x51, 0x51, 0x31, 0x66, 0x36, 0x7a, 0x36, 0x4c, 0x41, 0x63, + 0x6c, 0x46, 0x69, 0x71, 0x53, 0x69, 0x67, 0x34, 0x43, 0x41, 0x35, 0x35, 0x74, 0x52, 0x55, 0x52, 0x73, 0x55, + 0x30, 0x5c, 0x0a, + 0x09, 0x73, 0x30, 0x31, 0x64, 0x50, 0x79, 0x33, 0x48, 0x76, 0x34, 0x58, 0x66, 0x71, 0x5a, 0x57, 0x2f, 0x67, + 0x47, 0x50, 0x31, 0x62, 0x37, 0x57, 0x58, 0x74, 0x70, 0x61, 0x4f, 0x49, 0x65, 0x56, 0x57, 0x6e, 0x53, 0x58, + 0x43, 0x33, 0x6c, 0x30, 0x37, 0x38, 0x66, 0x74, 0x76, 0x2b, 0x4b, 0x39, 0x34, 0x78, 0x43, 0x4d, 0x65, 0x42, + 0x71, 0x49, 0x4d, 0x6f, 0x41, 0x77, 0x67, 0x49, 0x4d, 0x74, 0x79, 0x6c, 0x41, 0x42, 0x75, 0x76, 0x66, 0x6c, + 0x57, 0x5c, 0x0a, + 0x09, 0x76, 0x4f, 0x76, 0x64, 0x37, 0x38, 0x55, 0x58, 0x76, 0x76, 0x77, 0x56, 0x4c, 0x41, 0x30, 0x47, 0x47, + 0x42, 0x5a, 0x44, 0x50, 0x4f, 0x2b, 0x48, 0x66, 0x67, 0x69, 0x76, 0x66, 0x4e, 0x57, 0x6c, 0x32, 0x44, 0x6f, + 0x39, 0x37, 0x64, 0x74, 0x32, 0x4a, 0x54, 0x71, 0x35, 0x4e, 0x34, 0x32, 0x33, 0x76, 0x65, 0x39, 0x58, 0x38, + 0x43, 0x2b, 0x66, 0x2b, 0x51, 0x79, 0x6d, 0x74, 0x30, 0x37, 0x68, 0x34, 0x4f, 0x77, 0x73, 0x6c, 0x71, 0x72, + 0x66, 0x5c, 0x0a, + 0x09, 0x34, 0x4c, 0x50, 0x47, 0x59, 0x6f, 0x33, 0x35, 0x61, 0x4d, 0x64, 0x59, 0x31, 0x30, 0x74, 0x6c, 0x71, + 0x66, 0x74, 0x71, 0x30, 0x71, 0x4d, 0x64, 0x65, 0x32, 0x55, 0x62, 0x54, 0x58, 0x61, 0x6a, 0x32, 0x37, 0x50, + 0x37, 0x4a, 0x47, 0x51, 0x45, 0x6a, 0x48, 0x55, 0x37, 0x73, 0x62, 0x39, 0x75, 0x70, 0x34, 0x4e, 0x75, 0x6e, + 0x73, 0x58, 0x79, 0x34, 0x37, 0x30, 0x65, 0x73, 0x73, 0x71, 0x70, 0x2b, 0x37, 0x30, 0x75, 0x63, 0x73, 0x70, + 0x41, 0x5c, 0x0a, + 0x09, 0x35, 0x44, 0x44, 0x52, 0x39, 0x38, 0x42, 0x4d, 0x52, 0x4e, 0x67, 0x79, 0x50, 0x68, 0x5a, 0x39, 0x66, + 0x32, 0x4b, 0x73, 0x44, 0x79, 0x4a, 0x67, 0x66, 0x6e, 0x47, 0x41, 0x38, 0x38, 0x2f, 0x59, 0x74, 0x33, 0x33, + 0x5a, 0x46, 0x54, 0x6a, 0x6a, 0x2b, 0x31, 0x39, 0x67, 0x6a, 0x6d, 0x51, 0x74, 0x61, 0x4e, 0x31, 0x2b, 0x46, + 0x2b, 0x44, 0x6b, 0x38, 0x78, 0x37, 0x6e, 0x4f, 0x77, 0x54, 0x65, 0x36, 0x59, 0x42, 0x58, 0x4e, 0x42, 0x6c, + 0x35, 0x5c, 0x0a, + 0x09, 0x30, 0x37, 0x6b, 0x6d, 0x78, 0x2b, 0x54, 0x58, 0x6d, 0x77, 0x78, 0x75, 0x70, 0x54, 0x4a, 0x57, 0x6e, + 0x53, 0x59, 0x48, 0x48, 0x4e, 0x58, 0x75, 0x4b, 0x42, 0x36, 0x61, 0x6a, 0x4c, 0x57, 0x70, 0x76, 0x74, 0x55, + 0x33, 0x70, 0x37, 0x71, 0x64, 0x32, 0x6d, 0x48, 0x4b, 0x73, 0x73, 0x54, 0x38, 0x2f, 0x42, 0x77, 0x65, 0x64, + 0x76, 0x4c, 0x4a, 0x2b, 0x50, 0x4b, 0x6e, 0x50, 0x32, 0x37, 0x57, 0x6d, 0x7a, 0x31, 0x79, 0x42, 0x49, 0x2b, + 0x35, 0x5c, 0x0a, + 0x09, 0x38, 0x43, 0x49, 0x63, 0x6d, 0x5a, 0x50, 0x37, 0x73, 0x58, 0x37, 0x72, 0x4e, 0x61, 0x2f, 0x42, 0x53, + 0x33, 0x2f, 0x32, 0x4a, 0x65, 0x4c, 0x63, 0x2f, 0x50, 0x77, 0x38, 0x54, 0x6a, 0x2f, 0x2f, 0x51, 0x69, 0x77, + 0x4d, 0x42, 0x68, 0x6a, 0x72, 0x39, 0x39, 0x48, 0x74, 0x39, 0x52, 0x67, 0x2f, 0x64, 0x62, 0x2f, 0x79, 0x7a, + 0x4d, 0x70, 0x41, 0x4e, 0x71, 0x70, 0x4f, 0x45, 0x39, 0x58, 0x6c, 0x36, 0x70, 0x4a, 0x32, 0x4f, 0x37, 0x4b, + 0x6c, 0x5c, 0x0a, + 0x09, 0x55, 0x53, 0x44, 0x42, 0x48, 0x56, 0x75, 0x44, 0x52, 0x4e, 0x32, 0x75, 0x48, 0x47, 0x63, 0x54, 0x47, + 0x45, 0x6b, 0x75, 0x5a, 0x42, 0x6e, 0x4a, 0x58, 0x38, 0x6f, 0x58, 0x61, 0x2b, 0x4d, 0x54, 0x70, 0x2b, 0x7a, + 0x61, 0x38, 0x5a, 0x39, 0x75, 0x76, 0x65, 0x39, 0x42, 0x33, 0x48, 0x37, 0x56, 0x6c, 0x37, 0x41, 0x65, 0x74, + 0x43, 0x35, 0x72, 0x41, 0x4b, 0x64, 0x55, 0x7a, 0x67, 0x2f, 0x67, 0x42, 0x77, 0x46, 0x36, 0x68, 0x54, 0x46, + 0x77, 0x5c, 0x0a, + 0x09, 0x51, 0x51, 0x54, 0x2b, 0x53, 0x37, 0x31, 0x55, 0x52, 0x59, 0x4b, 0x36, 0x54, 0x6d, 0x70, 0x59, 0x54, + 0x53, 0x33, 0x78, 0x4d, 0x76, 0x58, 0x2f, 0x31, 0x6a, 0x58, 0x65, 0x4e, 0x6a, 0x38, 0x76, 0x66, 0x7a, 0x5a, + 0x4d, 0x6b, 0x6a, 0x4d, 0x2b, 0x43, 0x64, 0x49, 0x45, 0x75, 0x57, 0x48, 0x57, 0x42, 0x70, 0x6f, 0x61, 0x4a, + 0x4b, 0x6e, 0x36, 0x6d, 0x6c, 0x50, 0x48, 0x2f, 0x69, 0x54, 0x66, 0x6c, 0x54, 0x4f, 0x55, 0x4a, 0x65, 0x59, + 0x58, 0x5c, 0x0a, + 0x09, 0x46, 0x75, 0x43, 0x63, 0x77, 0x2f, 0x57, 0x33, 0x33, 0x59, 0x59, 0x2f, 0x66, 0x76, 0x2b, 0x66, 0x6d, + 0x32, 0x50, 0x39, 0x71, 0x37, 0x2f, 0x36, 0x36, 0x2f, 0x69, 0x72, 0x4f, 0x35, 0x7a, 0x37, 0x4e, 0x37, 0x7a, + 0x35, 0x7a, 0x66, 0x6a, 0x73, 0x5a, 0x7a, 0x38, 0x6e, 0x79, 0x72, 0x37, 0x2b, 0x76, 0x2f, 0x30, 0x75, 0x46, + 0x67, 0x59, 0x2b, 0x6a, 0x56, 0x38, 0x61, 0x4c, 0x46, 0x55, 0x2f, 0x66, 0x53, 0x37, 0x64, 0x52, 0x50, 0x4e, + 0x66, 0x5c, 0x0a, + 0x09, 0x38, 0x30, 0x62, 0x73, 0x2f, 0x33, 0x72, 0x38, 0x41, 0x4e, 0x67, 0x35, 0x4c, 0x62, 0x75, 0x36, 0x4c, + 0x4b, 0x6c, 0x79, 0x6d, 0x6c, 0x2b, 0x74, 0x72, 0x7a, 0x52, 0x49, 0x70, 0x4b, 0x37, 0x5a, 0x44, 0x4b, 0x61, + 0x32, 0x38, 0x34, 0x64, 0x72, 0x4b, 0x6f, 0x46, 0x50, 0x39, 0x4f, 0x42, 0x47, 0x48, 0x73, 0x6d, 0x78, 0x57, + 0x2f, 0x56, 0x59, 0x65, 0x78, 0x66, 0x66, 0x65, 0x74, 0x2b, 0x44, 0x4c, 0x77, 0x62, 0x71, 0x67, 0x4c, 0x6e, + 0x57, 0x5c, 0x0a, + 0x09, 0x74, 0x4f, 0x59, 0x5a, 0x77, 0x43, 0x6e, 0x6e, 0x50, 0x53, 0x34, 0x6f, 0x35, 0x31, 0x51, 0x41, 0x56, + 0x7a, 0x72, 0x34, 0x78, 0x78, 0x35, 0x48, 0x49, 0x32, 0x4b, 0x4b, 0x34, 0x6a, 0x44, 0x4f, 0x63, 0x32, 0x71, + 0x4f, 0x33, 0x73, 0x30, 0x52, 0x6f, 0x53, 0x6c, 0x56, 0x58, 0x54, 0x6e, 0x71, 0x6a, 0x75, 0x72, 0x44, 0x6a, + 0x68, 0x6a, 0x63, 0x2b, 0x62, 0x55, 0x52, 0x57, 0x35, 0x45, 0x74, 0x35, 0x59, 0x48, 0x2f, 0x50, 0x70, 0x37, + 0x69, 0x5c, 0x0a, + 0x09, 0x71, 0x79, 0x77, 0x78, 0x74, 0x37, 0x44, 0x67, 0x66, 0x36, 0x4b, 0x63, 0x2f, 0x50, 0x57, 0x70, 0x69, + 0x55, 0x6c, 0x38, 0x36, 0x79, 0x75, 0x66, 0x52, 0x37, 0x66, 0x6e, 0x35, 0x37, 0x59, 0x42, 0x36, 0x5a, 0x2f, + 0x37, 0x76, 0x42, 0x2f, 0x42, 0x6c, 0x37, 0x37, 0x32, 0x56, 0x62, 0x50, 0x6e, 0x37, 0x56, 0x4e, 0x62, 0x38, + 0x61, 0x2b, 0x66, 0x2f, 0x77, 0x4b, 0x79, 0x4c, 0x45, 0x4f, 0x57, 0x45, 0x38, 0x34, 0x2b, 0x2f, 0x77, 0x49, + 0x63, 0x5c, 0x0a, + 0x09, 0x6e, 0x70, 0x2b, 0x50, 0x55, 0x39, 0x59, 0x38, 0x79, 0x7a, 0x41, 0x78, 0x4d, 0x5a, 0x6b, 0x77, 0x6f, + 0x4d, 0x66, 0x49, 0x2b, 0x57, 0x79, 0x4b, 0x6e, 0x4c, 0x79, 0x75, 0x70, 0x51, 0x75, 0x77, 0x74, 0x6c, 0x62, + 0x4b, 0x4a, 0x47, 0x79, 0x39, 0x72, 0x5a, 0x53, 0x50, 0x48, 0x46, 0x56, 0x45, 0x58, 0x73, 0x45, 0x65, 0x52, + 0x32, 0x56, 0x75, 0x54, 0x62, 0x2b, 0x47, 0x62, 0x50, 0x55, 0x76, 0x64, 0x4c, 0x38, 0x41, 0x34, 0x4c, 0x45, + 0x41, 0x5c, 0x0a, + 0x09, 0x72, 0x69, 0x55, 0x41, 0x74, 0x36, 0x31, 0x78, 0x4a, 0x72, 0x41, 0x75, 0x47, 0x51, 0x41, 0x42, 0x48, + 0x51, 0x66, 0x38, 0x4e, 0x55, 0x44, 0x62, 0x4f, 0x52, 0x4c, 0x7a, 0x4b, 0x41, 0x39, 0x77, 0x67, 0x61, 0x53, + 0x70, 0x5a, 0x58, 0x43, 0x72, 0x46, 0x44, 0x58, 0x54, 0x2b, 0x43, 0x41, 0x6a, 0x67, 0x78, 0x4f, 0x6f, 0x4c, + 0x65, 0x4e, 0x72, 0x58, 0x56, 0x64, 0x48, 0x49, 0x34, 0x6e, 0x59, 0x5a, 0x4b, 0x69, 0x79, 0x6d, 0x66, 0x4f, + 0x6d, 0x5c, 0x0a, + 0x09, 0x62, 0x4d, 0x4c, 0x46, 0x66, 0x35, 0x62, 0x42, 0x70, 0x61, 0x44, 0x41, 0x2b, 0x32, 0x33, 0x36, 0x5a, + 0x64, 0x33, 0x53, 0x75, 0x64, 0x72, 0x35, 0x51, 0x31, 0x30, 0x48, 0x7a, 0x4d, 0x7a, 0x4e, 0x34, 0x68, 0x64, + 0x65, 0x2f, 0x65, 0x76, 0x34, 0x78, 0x72, 0x30, 0x7a, 0x2b, 0x4d, 0x61, 0x39, 0x4d, 0x37, 0x6a, 0x6d, 0x6e, + 0x6f, 0x4f, 0x34, 0x35, 0x74, 0x34, 0x5a, 0x44, 0x4d, 0x6f, 0x51, 0x78, 0x56, 0x50, 0x54, 0x6e, 0x6c, 0x74, + 0x63, 0x5c, 0x0a, + 0x09, 0x77, 0x70, 0x32, 0x7a, 0x53, 0x37, 0x68, 0x74, 0x5a, 0x67, 0x36, 0x2f, 0x2f, 0x65, 0x59, 0x2f, 0x77, + 0x4f, 0x48, 0x35, 0x65, 0x64, 0x2b, 0x7a, 0x41, 0x34, 0x68, 0x51, 0x72, 0x64, 0x63, 0x73, 0x43, 0x75, 0x6e, + 0x70, 0x6a, 0x4d, 0x62, 0x4f, 0x41, 0x35, 0x72, 0x6b, 0x78, 0x6b, 0x76, 0x4c, 0x48, 0x45, 0x33, 0x4c, 0x70, + 0x4f, 0x35, 0x50, 0x79, 0x71, 0x55, 0x5a, 0x74, 0x45, 0x4e, 0x64, 0x78, 0x34, 0x36, 0x6b, 0x62, 0x70, 0x75, + 0x6a, 0x5c, 0x0a, + 0x09, 0x76, 0x6b, 0x56, 0x53, 0x30, 0x36, 0x6b, 0x46, 0x36, 0x63, 0x78, 0x47, 0x74, 0x74, 0x49, 0x55, 0x56, + 0x44, 0x69, 0x50, 0x56, 0x64, 0x76, 0x6a, 0x42, 0x50, 0x77, 0x4e, 0x41, 0x52, 0x4e, 0x72, 0x47, 0x35, 0x6f, + 0x39, 0x72, 0x53, 0x6b, 0x41, 0x68, 0x4f, 0x67, 0x50, 0x34, 0x50, 0x55, 0x41, 0x4c, 0x74, 0x41, 0x4b, 0x72, + 0x5a, 0x55, 0x69, 0x55, 0x7a, 0x43, 0x4e, 0x71, 0x76, 0x77, 0x63, 0x49, 0x4a, 0x56, 0x67, 0x4f, 0x5a, 0x77, + 0x56, 0x5c, 0x0a, + 0x09, 0x4c, 0x57, 0x6f, 0x46, 0x2b, 0x4e, 0x5a, 0x53, 0x35, 0x37, 0x53, 0x6a, 0x62, 0x75, 0x69, 0x44, 0x67, + 0x35, 0x5a, 0x74, 0x4d, 0x44, 0x55, 0x63, 0x68, 0x66, 0x5a, 0x30, 0x32, 0x6d, 0x63, 0x5a, 0x7a, 0x69, 0x6a, + 0x44, 0x43, 0x48, 0x78, 0x61, 0x55, 0x63, 0x6c, 0x56, 0x42, 0x2f, 0x50, 0x4d, 0x2b, 0x51, 0x47, 0x77, 0x4f, + 0x36, 0x65, 0x45, 0x76, 0x2f, 0x2f, 0x59, 0x78, 0x33, 0x44, 0x77, 0x2f, 0x76, 0x74, 0x5a, 0x78, 0x52, 0x4c, + 0x50, 0x5c, 0x0a, + 0x09, 0x2b, 0x62, 0x45, 0x66, 0x4e, 0x33, 0x6a, 0x33, 0x64, 0x4d, 0x61, 0x42, 0x41, 0x35, 0x34, 0x6e, 0x79, + 0x76, 0x43, 0x68, 0x44, 0x2f, 0x38, 0x76, 0x77, 0x57, 0x46, 0x6f, 0x74, 0x78, 0x67, 0x75, 0x49, 0x36, 0x78, + 0x71, 0x42, 0x39, 0x31, 0x4a, 0x66, 0x66, 0x43, 0x32, 0x74, 0x62, 0x37, 0x54, 0x47, 0x46, 0x33, 0x4c, 0x4a, + 0x4d, 0x31, 0x2b, 0x4c, 0x4c, 0x32, 0x47, 0x55, 0x70, 0x61, 0x75, 0x6f, 0x4d, 0x70, 0x70, 0x76, 0x72, 0x6a, + 0x4d, 0x5c, 0x0a, + 0x09, 0x30, 0x34, 0x69, 0x64, 0x39, 0x70, 0x66, 0x32, 0x54, 0x4d, 0x6d, 0x31, 0x70, 0x67, 0x77, 0x6e, 0x4c, + 0x5a, 0x6e, 0x61, 0x68, 0x58, 0x57, 0x39, 0x71, 0x6e, 0x2b, 0x57, 0x41, 0x2f, 0x34, 0x48, 0x49, 0x4b, 0x62, + 0x50, 0x61, 0x30, 0x4a, 0x72, 0x42, 0x67, 0x41, 0x6e, 0x31, 0x36, 0x6e, 0x2f, 0x45, 0x78, 0x7a, 0x77, 0x47, + 0x71, 0x30, 0x77, 0x79, 0x79, 0x6b, 0x41, 0x62, 0x53, 0x4a, 0x70, 0x75, 0x73, 0x58, 0x4c, 0x42, 0x45, 0x46, + 0x62, 0x5c, 0x0a, + 0x09, 0x4b, 0x61, 0x47, 0x75, 0x7a, 0x36, 0x4d, 0x64, 0x4e, 0x79, 0x51, 0x4c, 0x63, 0x4f, 0x6f, 0x32, 0x6e, + 0x4c, 0x69, 0x6d, 0x77, 0x53, 0x41, 0x6c, 0x65, 0x36, 0x32, 0x43, 0x31, 0x48, 0x58, 0x62, 0x45, 0x48, 0x67, + 0x38, 0x74, 0x59, 0x33, 0x55, 0x36, 0x41, 0x35, 0x5a, 0x6c, 0x71, 0x6d, 0x37, 0x54, 0x6e, 0x57, 0x74, 0x35, + 0x65, 0x55, 0x68, 0x2f, 0x76, 0x75, 0x62, 0x33, 0x67, 0x6a, 0x6e, 0x79, 0x75, 0x71, 0x4f, 0x41, 0x4f, 0x47, + 0x43, 0x5c, 0x0a, + 0x09, 0x4a, 0x7a, 0x38, 0x4e, 0x35, 0x7a, 0x2f, 0x36, 0x66, 0x4c, 0x4f, 0x48, 0x43, 0x37, 0x2f, 0x76, 0x4b, + 0x58, 0x41, 0x41, 0x4c, 0x76, 0x2f, 0x6f, 0x52, 0x2f, 0x46, 0x41, 0x2f, 0x42, 0x56, 0x65, 0x56, 0x73, 0x59, + 0x42, 0x45, 0x2b, 0x4d, 0x54, 0x63, 0x43, 0x53, 0x6a, 0x4e, 0x65, 0x39, 0x5a, 0x36, 0x31, 0x4f, 0x4f, 0x33, + 0x35, 0x6d, 0x79, 0x56, 0x6b, 0x4e, 0x4b, 0x64, 0x47, 0x49, 0x42, 0x4f, 0x6a, 0x2f, 0x6d, 0x75, 0x76, 0x4c, + 0x66, 0x5c, 0x0a, + 0x09, 0x4e, 0x58, 0x2b, 0x6b, 0x64, 0x43, 0x46, 0x72, 0x4e, 0x6a, 0x6b, 0x6f, 0x6e, 0x33, 0x35, 0x49, 0x59, + 0x4a, 0x4d, 0x52, 0x58, 0x6f, 0x4e, 0x39, 0x34, 0x47, 0x65, 0x6c, 0x37, 0x49, 0x66, 0x58, 0x54, 0x38, 0x76, + 0x51, 0x7a, 0x78, 0x48, 0x77, 0x77, 0x77, 0x35, 0x72, 0x75, 0x78, 0x36, 0x77, 0x31, 0x6c, 0x4f, 0x41, 0x4b, + 0x51, 0x41, 0x66, 0x6f, 0x4b, 0x71, 0x66, 0x5a, 0x6f, 0x4d, 0x6d, 0x59, 0x53, 0x6a, 0x38, 0x30, 0x34, 0x71, + 0x61, 0x5c, 0x0a, + 0x09, 0x4f, 0x73, 0x72, 0x6f, 0x44, 0x4d, 0x47, 0x69, 0x4f, 0x6c, 0x4b, 0x6c, 0x61, 0x57, 0x6e, 0x54, 0x63, + 0x52, 0x4d, 0x77, 0x70, 0x47, 0x6c, 0x67, 0x62, 0x59, 0x49, 0x36, 0x45, 0x6b, 0x71, 0x65, 0x6e, 0x46, 0x6d, + 0x2f, 0x6a, 0x71, 0x51, 0x75, 0x4d, 0x61, 0x54, 0x41, 0x73, 0x32, 0x34, 0x76, 0x39, 0x44, 0x6b, 0x78, 0x4e, + 0x6f, 0x59, 0x38, 0x34, 0x33, 0x64, 0x7a, 0x4b, 0x58, 0x34, 0x51, 0x41, 0x5a, 0x2f, 0x37, 0x30, 0x70, 0x64, + 0x77, 0x5c, 0x0a, + 0x09, 0x32, 0x38, 0x32, 0x33, 0x69, 0x47, 0x75, 0x2f, 0x2b, 0x47, 0x75, 0x76, 0x78, 0x65, 0x54, 0x45, 0x42, + 0x44, 0x68, 0x4e, 0x54, 0x6b, 0x7a, 0x67, 0x36, 0x63, 0x39, 0x35, 0x48, 0x67, 0x6a, 0x41, 0x6e, 0x2f, 0x37, + 0x5a, 0x6e, 0x38, 0x69, 0x6f, 0x58, 0x54, 0x55, 0x35, 0x31, 0x75, 0x38, 0x6a, 0x7a, 0x33, 0x4d, 0x68, 0x48, + 0x7a, 0x33, 0x47, 0x6c, 0x45, 0x2b, 0x62, 0x39, 0x4f, 0x4b, 0x71, 0x42, 0x4f, 0x62, 0x36, 0x76, 0x4f, 0x56, + 0x45, 0x5c, 0x0a, + 0x09, 0x64, 0x67, 0x59, 0x6d, 0x75, 0x65, 0x41, 0x36, 0x73, 0x4f, 0x39, 0x56, 0x49, 0x4a, 0x46, 0x33, 0x57, + 0x71, 0x4c, 0x2b, 0x7a, 0x75, 0x4f, 0x39, 0x74, 0x73, 0x6e, 0x36, 0x75, 0x77, 0x77, 0x79, 0x4b, 0x62, 0x2b, + 0x6b, 0x76, 0x71, 0x63, 0x5a, 0x44, 0x79, 0x2f, 0x6c, 0x67, 0x50, 0x63, 0x44, 0x32, 0x49, 0x55, 0x31, 0x70, + 0x44, 0x55, 0x42, 0x41, 0x4a, 0x61, 0x32, 0x2f, 0x43, 0x36, 0x41, 0x76, 0x65, 0x47, 0x4c, 0x54, 0x6f, 0x74, + 0x71, 0x5c, 0x0a, + 0x09, 0x70, 0x63, 0x74, 0x55, 0x6b, 0x58, 0x38, 0x47, 0x6b, 0x56, 0x74, 0x52, 0x67, 0x4b, 0x41, 0x56, 0x55, + 0x46, 0x4e, 0x54, 0x31, 0x4e, 0x44, 0x6d, 0x6b, 0x46, 0x4c, 0x4b, 0x59, 0x35, 0x4d, 0x52, 0x61, 0x77, 0x50, + 0x54, 0x64, 0x79, 0x4d, 0x34, 0x2f, 0x32, 0x6b, 0x64, 0x75, 0x32, 0x63, 0x72, 0x55, 0x74, 0x6d, 0x4c, 0x66, + 0x2f, 0x55, 0x34, 0x4a, 0x73, 0x62, 0x48, 0x68, 0x57, 0x4f, 0x47, 0x6a, 0x70, 0x30, 0x44, 0x43, 0x6c, 0x66, + 0x69, 0x5c, 0x0a, + 0x09, 0x37, 0x57, 0x2f, 0x35, 0x50, 0x5a, 0x38, 0x46, 0x41, 0x48, 0x43, 0x75, 0x78, 0x41, 0x6d, 0x6e, 0x37, + 0x73, 0x56, 0x50, 0x76, 0x4f, 0x53, 0x6c, 0x6f, 0x73, 0x58, 0x48, 0x58, 0x2f, 0x51, 0x45, 0x62, 0x4a, 0x6d, + 0x61, 0x78, 0x72, 0x56, 0x66, 0x2b, 0x78, 0x70, 0x75, 0x76, 0x66, 0x4f, 0x75, 0x68, 0x4d, 0x46, 0x75, 0x74, + 0x34, 0x74, 0x65, 0x74, 0x61, 0x43, 0x34, 0x6b, 0x71, 0x79, 0x74, 0x72, 0x49, 0x31, 0x48, 0x35, 0x2f, 0x53, + 0x63, 0x5c, 0x0a, + 0x09, 0x2f, 0x63, 0x66, 0x62, 0x74, 0x7a, 0x49, 0x71, 0x4c, 0x6e, 0x57, 0x39, 0x57, 0x4a, 0x68, 0x47, 0x5a, + 0x4e, 0x75, 0x4a, 0x39, 0x56, 0x69, 0x61, 0x2b, 0x4e, 0x64, 0x6a, 0x6c, 0x59, 0x42, 0x56, 0x63, 0x79, 0x53, + 0x64, 0x6d, 0x43, 0x42, 0x44, 0x54, 0x6e, 0x71, 0x33, 0x77, 0x51, 0x62, 0x4b, 0x43, 0x43, 0x63, 0x37, 0x43, + 0x58, 0x67, 0x58, 0x41, 0x4a, 0x78, 0x79, 0x33, 0x76, 0x64, 0x69, 0x4c, 0x57, 0x6a, 0x56, 0x41, 0x59, 0x43, + 0x6c, 0x5c, 0x0a, + 0x09, 0x2f, 0x6b, 0x38, 0x42, 0x38, 0x44, 0x4b, 0x41, 0x43, 0x31, 0x45, 0x65, 0x61, 0x55, 0x63, 0x4f, 0x33, + 0x37, 0x54, 0x67, 0x72, 0x62, 0x54, 0x62, 0x64, 0x6d, 0x49, 0x79, 0x6a, 0x6d, 0x77, 0x44, 0x30, 0x6d, 0x6c, + 0x62, 0x66, 0x54, 0x35, 0x64, 0x48, 0x34, 0x43, 0x71, 0x59, 0x77, 0x47, 0x43, 0x42, 0x6a, 0x49, 0x35, 0x70, + 0x68, 0x52, 0x30, 0x67, 0x6f, 0x6f, 0x74, 0x41, 0x36, 0x76, 0x37, 0x63, 0x67, 0x6d, 0x6f, 0x63, 0x46, 0x35, + 0x43, 0x5c, 0x0a, + 0x09, 0x65, 0x5a, 0x44, 0x50, 0x42, 0x43, 0x6a, 0x4c, 0x5a, 0x43, 0x45, 0x34, 0x4f, 0x4f, 0x66, 0x77, 0x70, + 0x53, 0x75, 0x76, 0x78, 0x41, 0x33, 0x66, 0x2b, 0x45, 0x5a, 0x39, 0x69, 0x54, 0x4a, 0x73, 0x6e, 0x64, 0x6f, + 0x71, 0x57, 0x68, 0x34, 0x4d, 0x2f, 0x43, 0x37, 0x4b, 0x39, 0x37, 0x33, 0x37, 0x58, 0x53, 0x6a, 0x4b, 0x38, + 0x4c, 0x69, 0x47, 0x37, 0x36, 0x57, 0x54, 0x35, 0x52, 0x6a, 0x76, 0x6a, 0x37, 0x45, 0x7a, 0x64, 0x6d, 0x59, + 0x47, 0x5c, 0x0a, + 0x09, 0x34, 0x33, 0x74, 0x36, 0x47, 0x7a, 0x58, 0x49, 0x6c, 0x7a, 0x74, 0x73, 0x43, 0x67, 0x70, 0x4e, 0x49, + 0x4a, 0x33, 0x61, 0x51, 0x56, 0x70, 0x53, 0x36, 0x30, 0x69, 0x57, 0x53, 0x4f, 0x57, 0x5a, 0x42, 0x70, 0x7a, + 0x6d, 0x30, 0x6a, 0x71, 0x44, 0x43, 0x36, 0x76, 0x39, 0x54, 0x70, 0x7a, 0x6e, 0x77, 0x4d, 0x33, 0x7a, 0x75, + 0x39, 0x48, 0x32, 0x77, 0x38, 0x64, 0x55, 0x31, 0x38, 0x4c, 0x7a, 0x43, 0x66, 0x52, 0x63, 0x42, 0x37, 0x63, + 0x6d, 0x5c, 0x0a, + 0x09, 0x55, 0x34, 0x47, 0x31, 0x6d, 0x67, 0x4c, 0x30, 0x41, 0x50, 0x77, 0x52, 0x59, 0x4b, 0x63, 0x34, 0x51, + 0x42, 0x6f, 0x4a, 0x72, 0x47, 0x67, 0x71, 0x68, 0x52, 0x7a, 0x71, 0x4e, 0x54, 0x76, 0x78, 0x61, 0x46, 0x57, + 0x6e, 0x62, 0x71, 0x33, 0x76, 0x4e, 0x2f, 0x4e, 0x53, 0x6f, 0x77, 0x78, 0x51, 0x47, 0x34, 0x72, 0x64, 0x68, + 0x70, 0x30, 0x33, 0x61, 0x47, 0x43, 0x77, 0x44, 0x4e, 0x55, 0x78, 0x33, 0x6b, 0x49, 0x5a, 0x57, 0x34, 0x62, + 0x73, 0x5c, 0x0a, + 0x09, 0x58, 0x4a, 0x5a, 0x68, 0x63, 0x6e, 0x77, 0x63, 0x47, 0x54, 0x39, 0x5a, 0x37, 0x59, 0x45, 0x76, 0x48, + 0x66, 0x44, 0x4f, 0x74, 0x37, 0x37, 0x56, 0x31, 0x36, 0x45, 0x4d, 0x7a, 0x70, 0x58, 0x34, 0x36, 0x68, 0x65, + 0x2f, 0x4b, 0x4f, 0x44, 0x34, 0x47, 0x39, 0x64, 0x65, 0x69, 0x37, 0x74, 0x75, 0x76, 0x77, 0x31, 0x58, 0x66, + 0x65, 0x4d, 0x62, 0x64, 0x63, 0x74, 0x45, 0x79, 0x49, 0x67, 0x77, 0x50, 0x6a, 0x59, 0x47, 0x30, 0x4d, 0x72, + 0x47, 0x5c, 0x0a, + 0x09, 0x79, 0x78, 0x32, 0x36, 0x50, 0x75, 0x2f, 0x4d, 0x73, 0x76, 0x55, 0x34, 0x77, 0x78, 0x68, 0x72, 0x71, + 0x59, 0x32, 0x4f, 0x2b, 0x46, 0x4c, 0x2b, 0x6c, 0x73, 0x78, 0x31, 0x41, 0x4a, 0x48, 0x31, 0x6e, 0x61, 0x45, + 0x2f, 0x32, 0x31, 0x4b, 0x73, 0x49, 0x4d, 0x48, 0x62, 0x31, 0x2b, 0x4d, 0x6a, 0x79, 0x44, 0x37, 0x34, 0x4f, + 0x4d, 0x4e, 0x31, 0x76, 0x59, 0x69, 0x73, 0x78, 0x77, 0x46, 0x52, 0x4e, 0x73, 0x72, 0x6e, 0x6e, 0x56, 0x69, + 0x6a, 0x5c, 0x0a, + 0x09, 0x35, 0x77, 0x52, 0x57, 0x46, 0x51, 0x42, 0x4f, 0x71, 0x58, 0x66, 0x37, 0x58, 0x51, 0x70, 0x67, 0x76, + 0x7a, 0x5a, 0x63, 0x4f, 0x55, 0x69, 0x6e, 0x6c, 0x4b, 0x63, 0x46, 0x7a, 0x38, 0x30, 0x7a, 0x7a, 0x52, 0x78, + 0x53, 0x51, 0x4c, 0x41, 0x53, 0x4f, 0x6d, 0x35, 0x49, 0x55, 0x75, 0x7a, 0x63, 0x52, 0x45, 0x4d, 0x45, 0x34, + 0x69, 0x6c, 0x64, 0x65, 0x6e, 0x74, 0x4c, 0x4c, 0x74, 0x44, 0x70, 0x73, 0x61, 0x56, 0x4b, 0x74, 0x61, 0x63, + 0x61, 0x5c, 0x0a, + 0x09, 0x61, 0x5a, 0x54, 0x68, 0x57, 0x32, 0x5a, 0x34, 0x4f, 0x62, 0x76, 0x2b, 0x79, 0x47, 0x69, 0x62, 0x5a, + 0x52, 0x67, 0x62, 0x47, 0x36, 0x39, 0x37, 0x69, 0x51, 0x30, 0x34, 0x66, 0x4f, 0x33, 0x61, 0x61, 0x2f, 0x43, + 0x64, 0x36, 0x37, 0x38, 0x46, 0x35, 0x2f, 0x77, 0x64, 0x67, 0x32, 0x39, 0x2b, 0x34, 0x31, 0x72, 0x77, 0x38, + 0x64, 0x39, 0x37, 0x2f, 0x33, 0x31, 0x34, 0x31, 0x39, 0x76, 0x65, 0x69, 0x6d, 0x47, 0x31, 0x31, 0x54, 0x65, + 0x30, 0x5c, 0x0a, + 0x09, 0x50, 0x54, 0x59, 0x2b, 0x44, 0x6d, 0x53, 0x5a, 0x45, 0x5a, 0x6d, 0x62, 0x62, 0x34, 0x31, 0x79, 0x47, + 0x4c, 0x41, 0x63, 0x4d, 0x5a, 0x53, 0x51, 0x33, 0x31, 0x31, 0x53, 0x54, 0x67, 0x4f, 0x39, 0x76, 0x65, 0x47, + 0x4c, 0x75, 0x55, 0x6c, 0x44, 0x41, 0x4c, 0x44, 0x41, 0x51, 0x6b, 0x74, 0x62, 0x66, 0x37, 0x4e, 0x73, 0x31, + 0x78, 0x71, 0x50, 0x46, 0x5a, 0x6a, 0x30, 0x64, 0x54, 0x31, 0x4f, 0x69, 0x77, 0x39, 0x65, 0x54, 0x67, 0x63, + 0x51, 0x5c, 0x0a, + 0x09, 0x42, 0x35, 0x78, 0x41, 0x77, 0x47, 0x75, 0x42, 0x31, 0x56, 0x38, 0x51, 0x58, 0x46, 0x55, 0x41, 0x71, + 0x41, 0x61, 0x78, 0x78, 0x77, 0x47, 0x2f, 0x72, 0x71, 0x39, 0x5a, 0x77, 0x74, 0x4c, 0x58, 0x77, 0x2b, 0x63, + 0x6f, 0x51, 0x30, 0x6c, 0x54, 0x77, 0x50, 0x44, 0x70, 0x7a, 0x59, 0x51, 0x4c, 0x7a, 0x7a, 0x49, 0x2b, 0x4f, + 0x34, 0x4a, 0x70, 0x46, 0x4c, 0x66, 0x63, 0x72, 0x38, 0x62, 0x37, 0x4e, 0x50, 0x4d, 0x59, 0x48, 0x61, 0x45, + 0x31, 0x5c, 0x0a, + 0x09, 0x57, 0x59, 0x62, 0x50, 0x46, 0x78, 0x41, 0x44, 0x49, 0x4e, 0x69, 0x5a, 0x68, 0x46, 0x77, 0x77, 0x6c, + 0x65, 0x6b, 0x6f, 0x30, 0x4f, 0x6c, 0x30, 0x4b, 0x78, 0x44, 0x77, 0x49, 0x77, 0x6b, 0x50, 0x32, 0x4a, 0x51, + 0x4f, 0x2b, 0x4a, 0x50, 0x33, 0x76, 0x41, 0x64, 0x45, 0x47, 0x51, 0x37, 0x64, 0x66, 0x7a, 0x2f, 0x75, 0x76, + 0x50, 0x4e, 0x4f, 0x61, 0x4d, 0x6c, 0x2b, 0x34, 0x53, 0x76, 0x2f, 0x35, 0x6f, 0x2b, 0x71, 0x30, 0x2f, 0x33, + 0x2b, 0x5c, 0x0a, + 0x09, 0x47, 0x44, 0x70, 0x35, 0x62, 0x68, 0x70, 0x31, 0x55, 0x2b, 0x6f, 0x4e, 0x53, 0x50, 0x6c, 0x77, 0x4a, + 0x7a, 0x67, 0x61, 0x4d, 0x4c, 0x43, 0x69, 0x65, 0x39, 0x32, 0x4f, 0x64, 0x63, 0x73, 0x33, 0x35, 0x57, 0x5a, + 0x55, 0x50, 0x79, 0x6b, 0x41, 0x31, 0x2b, 0x57, 0x34, 0x6a, 0x56, 0x68, 0x6a, 0x67, 0x43, 0x71, 0x6a, 0x36, + 0x7a, 0x58, 0x33, 0x54, 0x36, 0x59, 0x63, 0x41, 0x6b, 0x77, 0x47, 0x63, 0x4e, 0x4d, 0x77, 0x70, 0x4f, 0x7a, + 0x73, 0x5c, 0x0a, + 0x09, 0x55, 0x67, 0x43, 0x6e, 0x47, 0x36, 0x7a, 0x2f, 0x75, 0x32, 0x6a, 0x56, 0x41, 0x43, 0x41, 0x73, 0x55, + 0x6a, 0x6a, 0x67, 0x31, 0x51, 0x43, 0x32, 0x36, 0x6b, 0x48, 0x57, 0x2f, 0x2f, 0x75, 0x6a, 0x4a, 0x73, 0x4f, + 0x6f, 0x53, 0x36, 0x52, 0x4f, 0x78, 0x6f, 0x2b, 0x62, 0x6f, 0x72, 0x45, 0x76, 0x55, 0x78, 0x73, 0x4b, 0x78, + 0x48, 0x6c, 0x74, 0x42, 0x4a, 0x4b, 0x76, 0x2b, 0x6c, 0x4f, 0x36, 0x6e, 0x2b, 0x58, 0x73, 0x54, 0x57, 0x33, + 0x7a, 0x5c, 0x0a, + 0x09, 0x53, 0x47, 0x47, 0x68, 0x75, 0x6a, 0x51, 0x75, 0x53, 0x73, 0x37, 0x72, 0x4d, 0x65, 0x68, 0x65, 0x6d, + 0x32, 0x35, 0x4e, 0x31, 0x52, 0x48, 0x5a, 0x6f, 0x64, 0x76, 0x74, 0x6f, 0x74, 0x2f, 0x72, 0x2b, 0x58, 0x4f, + 0x73, 0x30, 0x47, 0x65, 0x75, 0x75, 0x41, 0x4c, 0x33, 0x33, 0x33, 0x4d, 0x33, 0x72, 0x76, 0x7a, 0x79, 0x46, + 0x78, 0x56, 0x55, 0x41, 0x75, 0x6a, 0x31, 0x73, 0x54, 0x52, 0x59, 0x38, 0x6a, 0x30, 0x37, 0x76, 0x2b, 0x6a, + 0x58, 0x5c, 0x0a, + 0x09, 0x37, 0x58, 0x5a, 0x5a, 0x36, 0x7a, 0x4c, 0x62, 0x30, 0x6d, 0x44, 0x56, 0x6c, 0x4d, 0x6f, 0x32, 0x36, + 0x64, 0x69, 0x4a, 0x36, 0x7a, 0x6f, 0x66, 0x30, 0x32, 0x4f, 0x79, 0x49, 0x71, 0x6b, 0x64, 0x50, 0x54, 0x6d, + 0x2f, 0x2b, 0x6c, 0x6f, 0x54, 0x49, 0x4d, 0x73, 0x65, 0x6d, 0x36, 0x36, 0x6b, 0x5a, 0x41, 0x55, 0x78, 0x4b, + 0x33, 0x74, 0x49, 0x4e, 0x63, 0x55, 0x42, 0x58, 0x6d, 0x65, 0x6a, 0x30, 0x6a, 0x59, 0x59, 0x37, 0x33, 0x30, + 0x43, 0x5c, 0x0a, + 0x09, 0x66, 0x68, 0x56, 0x59, 0x33, 0x53, 0x78, 0x67, 0x46, 0x54, 0x4d, 0x41, 0x42, 0x77, 0x4b, 0x4e, 0x41, + 0x2f, 0x69, 0x5a, 0x31, 0x41, 0x68, 0x30, 0x76, 0x48, 0x42, 0x4b, 0x4d, 0x62, 0x55, 0x49, 0x56, 0x6b, 0x4c, + 0x6e, 0x75, 0x67, 0x57, 0x72, 0x6c, 0x47, 0x30, 0x4d, 0x2b, 0x6a, 0x78, 0x50, 0x72, 0x6e, 0x51, 0x30, 0x64, + 0x38, 0x6e, 0x5a, 0x74, 0x4c, 0x36, 0x4d, 0x44, 0x6d, 0x6c, 0x76, 0x4b, 0x57, 0x43, 0x52, 0x4d, 0x41, 0x51, + 0x65, 0x5c, 0x0a, + 0x09, 0x76, 0x52, 0x79, 0x6b, 0x66, 0x4a, 0x6f, 0x64, 0x4b, 0x5a, 0x56, 0x69, 0x4c, 0x5a, 0x64, 0x30, 0x79, + 0x32, 0x79, 0x2f, 0x33, 0x30, 0x65, 0x6e, 0x4b, 0x31, 0x38, 0x79, 0x57, 0x35, 0x51, 0x46, 0x2f, 0x75, 0x4c, + 0x39, 0x66, 0x34, 0x79, 0x62, 0x76, 0x76, 0x55, 0x74, 0x31, 0x71, 0x71, 0x6e, 0x5a, 0x63, 0x71, 0x72, 0x78, + 0x33, 0x49, 0x4a, 0x57, 0x5a, 0x35, 0x6a, 0x72, 0x46, 0x72, 0x30, 0x34, 0x2b, 0x4f, 0x74, 0x5a, 0x5a, 0x43, + 0x36, 0x5c, 0x0a, + 0x09, 0x73, 0x77, 0x53, 0x49, 0x4e, 0x4a, 0x70, 0x61, 0x33, 0x37, 0x58, 0x4a, 0x38, 0x33, 0x46, 0x4c, 0x65, + 0x55, 0x6e, 0x64, 0x4e, 0x6f, 0x48, 0x4b, 0x53, 0x73, 0x2b, 0x45, 0x4e, 0x47, 0x56, 0x72, 0x4b, 0x39, 0x30, + 0x4f, 0x64, 0x4f, 0x70, 0x59, 0x36, 0x31, 0x64, 0x71, 0x31, 0x63, 0x35, 0x41, 0x72, 0x44, 0x48, 0x72, 0x67, + 0x47, 0x51, 0x46, 0x4d, 0x57, 0x57, 0x62, 0x50, 0x34, 0x46, 0x56, 0x66, 0x6d, 0x6e, 0x49, 0x71, 0x67, 0x46, + 0x41, 0x5c, 0x0a, + 0x09, 0x70, 0x62, 0x41, 0x6e, 0x41, 0x70, 0x6a, 0x53, 0x5a, 0x71, 0x4c, 0x78, 0x4e, 0x58, 0x57, 0x6d, 0x2b, + 0x73, 0x78, 0x6f, 0x46, 0x65, 0x6f, 0x4e, 0x48, 0x53, 0x6b, 0x50, 0x56, 0x73, 0x53, 0x32, 0x44, 0x4a, 0x42, + 0x7a, 0x4a, 0x46, 0x50, 0x4e, 0x35, 0x70, 0x6b, 0x6d, 0x4c, 0x38, 0x2f, 0x56, 0x62, 0x51, 0x47, 0x55, 0x6a, + 0x49, 0x36, 0x70, 0x71, 0x57, 0x73, 0x6e, 0x53, 0x64, 0x73, 0x64, 0x76, 0x63, 0x48, 0x4a, 0x63, 0x68, 0x52, + 0x64, 0x5c, 0x0a, + 0x09, 0x62, 0x72, 0x78, 0x4b, 0x34, 0x51, 0x48, 0x45, 0x71, 0x63, 0x44, 0x48, 0x4c, 0x37, 0x73, 0x63, 0x68, + 0x77, 0x34, 0x64, 0x42, 0x49, 0x2b, 0x39, 0x57, 0x62, 0x65, 0x48, 0x59, 0x74, 0x6e, 0x50, 0x2f, 0x58, 0x4d, + 0x69, 0x6a, 0x49, 0x2b, 0x50, 0x78, 0x30, 0x5a, 0x47, 0x79, 0x56, 0x71, 0x36, 0x37, 0x61, 0x68, 0x4e, 0x54, + 0x6e, 0x55, 0x70, 0x72, 0x52, 0x4d, 0x39, 0x52, 0x6e, 0x34, 0x74, 0x63, 0x47, 0x67, 0x39, 0x57, 0x38, 0x44, + 0x72, 0x5c, 0x0a, + 0x09, 0x57, 0x7a, 0x71, 0x31, 0x2b, 0x67, 0x2f, 0x58, 0x65, 0x48, 0x39, 0x36, 0x66, 0x44, 0x6f, 0x6f, 0x38, + 0x66, 0x5a, 0x30, 0x42, 0x68, 0x4b, 0x75, 0x42, 0x61, 0x75, 0x32, 0x67, 0x6f, 0x54, 0x57, 0x69, 0x64, 0x57, + 0x58, 0x78, 0x57, 0x46, 0x44, 0x2b, 0x58, 0x45, 0x43, 0x6e, 0x6d, 0x52, 0x57, 0x65, 0x34, 0x69, 0x30, 0x32, + 0x6d, 0x73, 0x41, 0x31, 0x61, 0x73, 0x37, 0x70, 0x47, 0x6d, 0x6b, 0x79, 0x55, 0x33, 0x39, 0x72, 0x56, 0x5a, + 0x67, 0x5c, 0x0a, + 0x09, 0x45, 0x31, 0x78, 0x77, 0x51, 0x63, 0x72, 0x36, 0x70, 0x4b, 0x37, 0x70, 0x43, 0x47, 0x52, 0x46, 0x43, + 0x32, 0x31, 0x34, 0x64, 0x56, 0x38, 0x38, 0x4c, 0x76, 0x73, 0x7a, 0x4e, 0x54, 0x4c, 0x72, 0x2b, 0x56, 0x6c, + 0x74, 0x38, 0x50, 0x70, 0x73, 0x79, 0x72, 0x63, 0x45, 0x43, 0x49, 0x73, 0x58, 0x51, 0x42, 0x70, 0x73, 0x44, + 0x59, 0x70, 0x57, 0x32, 0x33, 0x61, 0x32, 0x6c, 0x42, 0x6f, 0x54, 0x65, 0x59, 0x73, 0x5a, 0x47, 0x30, 0x4f, + 0x57, 0x5c, 0x0a, + 0x09, 0x5a, 0x58, 0x45, 0x71, 0x63, 0x47, 0x52, 0x2b, 0x44, 0x72, 0x66, 0x66, 0x63, 0x58, 0x65, 0x73, 0x34, + 0x51, 0x41, 0x73, 0x35, 0x31, 0x30, 0x55, 0x7a, 0x69, 0x45, 0x6a, 0x51, 0x6e, 0x39, 0x38, 0x48, 0x44, 0x6d, + 0x6c, 0x4f, 0x72, 0x43, 0x4f, 0x72, 0x5a, 0x6a, 0x58, 0x35, 0x48, 0x68, 0x63, 0x6c, 0x72, 0x4a, 0x31, 0x69, + 0x33, 0x50, 0x65, 0x73, 0x6f, 0x50, 0x6d, 0x52, 0x74, 0x65, 0x6f, 0x64, 0x53, 0x79, 0x42, 0x45, 0x4a, 0x44, + 0x79, 0x5c, 0x0a, + 0x09, 0x31, 0x6e, 0x7a, 0x77, 0x36, 0x39, 0x62, 0x74, 0x79, 0x71, 0x4d, 0x42, 0x46, 0x61, 0x33, 0x4c, 0x4a, + 0x6b, 0x43, 0x70, 0x79, 0x2b, 0x6f, 0x46, 0x5a, 0x36, 0x6c, 0x54, 0x6f, 0x4a, 0x36, 0x63, 0x57, 0x54, 0x6f, + 0x48, 0x61, 0x48, 0x5a, 0x30, 0x6b, 0x50, 0x7a, 0x75, 0x61, 0x4c, 0x56, 0x76, 0x41, 0x31, 0x37, 0x6d, 0x67, + 0x42, 0x75, 0x31, 0x73, 0x56, 0x74, 0x71, 0x74, 0x6c, 0x49, 0x75, 0x66, 0x6f, 0x61, 0x6e, 0x52, 0x53, 0x74, + 0x46, 0x5c, 0x0a, + 0x09, 0x43, 0x6b, 0x37, 0x61, 0x52, 0x49, 0x37, 0x6d, 0x63, 0x56, 0x35, 0x2f, 0x72, 0x47, 0x2f, 0x4a, 0x63, + 0x62, 0x44, 0x52, 0x47, 0x7a, 0x68, 0x6b, 0x53, 0x32, 0x6b, 0x30, 0x6c, 0x45, 0x63, 0x36, 0x31, 0x62, 0x50, + 0x71, 0x4e, 0x6b, 0x58, 0x37, 0x4e, 0x4b, 0x72, 0x71, 0x36, 0x5a, 0x4d, 0x73, 0x70, 0x2f, 0x6c, 0x48, 0x6c, + 0x6d, 0x46, 0x69, 0x66, 0x4a, 0x79, 0x39, 0x72, 0x59, 0x72, 0x38, 0x52, 0x70, 0x39, 0x51, 0x76, 0x39, 0x50, + 0x44, 0x5c, 0x0a, + 0x09, 0x59, 0x46, 0x67, 0x41, 0x42, 0x50, 0x52, 0x59, 0x78, 0x67, 0x43, 0x6b, 0x68, 0x74, 0x79, 0x73, 0x73, + 0x78, 0x54, 0x6f, 0x4f, 0x49, 0x56, 0x4d, 0x53, 0x50, 0x44, 0x46, 0x57, 0x6b, 0x71, 0x7a, 0x41, 0x52, 0x6b, + 0x4f, 0x36, 0x72, 0x48, 0x5a, 0x6d, 0x33, 0x31, 0x30, 0x58, 0x37, 0x78, 0x65, 0x55, 0x38, 0x61, 0x67, 0x2b, + 0x2b, 0x59, 0x61, 0x74, 0x32, 0x53, 0x62, 0x6a, 0x71, 0x63, 0x70, 0x6d, 0x30, 0x68, 0x42, 0x4b, 0x72, 0x57, + 0x57, 0x5c, 0x0a, + 0x09, 0x56, 0x46, 0x63, 0x79, 0x6b, 0x36, 0x6e, 0x68, 0x6a, 0x41, 0x63, 0x52, 0x41, 0x46, 0x63, 0x44, 0x37, + 0x74, 0x50, 0x47, 0x73, 0x42, 0x38, 0x79, 0x72, 0x64, 0x6f, 0x62, 0x67, 0x53, 0x35, 0x39, 0x33, 0x73, 0x56, + 0x59, 0x47, 0x67, 0x79, 0x48, 0x64, 0x39, 0x78, 0x39, 0x36, 0x46, 0x38, 0x2b, 0x38, 0x75, 0x55, 0x72, 0x58, + 0x2b, 0x62, 0x50, 0x31, 0x67, 0x50, 0x52, 0x71, 0x54, 0x42, 0x2f, 0x31, 0x4c, 0x4d, 0x75, 0x6d, 0x54, 0x70, + 0x41, 0x5c, 0x0a, + 0x09, 0x2b, 0x4d, 0x62, 0x56, 0x6f, 0x77, 0x57, 0x57, 0x66, 0x6d, 0x72, 0x58, 0x58, 0x67, 0x6d, 0x64, 0x30, + 0x34, 0x63, 0x33, 0x7a, 0x59, 0x69, 0x71, 0x32, 0x72, 0x58, 0x53, 0x4e, 0x4a, 0x33, 0x39, 0x38, 0x46, 0x71, + 0x32, 0x63, 0x30, 0x67, 0x5a, 0x79, 0x64, 0x55, 0x43, 0x44, 0x6d, 0x68, 0x70, 0x56, 0x73, 0x57, 0x58, 0x44, + 0x71, 0x30, 0x4d, 0x49, 0x35, 0x37, 0x4c, 0x4d, 0x6f, 0x79, 0x50, 0x54, 0x32, 0x42, 0x68, 0x59, 0x52, 0x34, + 0x67, 0x5c, 0x0a, + 0x09, 0x34, 0x4e, 0x35, 0x44, 0x42, 0x39, 0x47, 0x76, 0x49, 0x6e, 0x37, 0x5a, 0x37, 0x61, 0x4e, 0x63, 0x58, + 0x45, 0x53, 0x48, 0x4c, 0x66, 0x6f, 0x31, 0x5a, 0x53, 0x61, 0x57, 0x4a, 0x4a, 0x6f, 0x79, 0x6d, 0x69, 0x5a, + 0x67, 0x53, 0x74, 0x74, 0x30, 0x6b, 0x42, 0x4f, 0x37, 0x31, 0x4d, 0x6c, 0x31, 0x57, 0x78, 0x70, 0x59, 0x59, + 0x5a, 0x51, 0x66, 0x31, 0x61, 0x2f, 0x46, 0x76, 0x38, 0x77, 0x35, 0x35, 0x46, 0x68, 0x54, 0x6e, 0x76, 0x30, + 0x56, 0x5c, 0x0a, + 0x09, 0x76, 0x55, 0x4e, 0x54, 0x51, 0x6b, 0x70, 0x71, 0x32, 0x32, 0x6d, 0x77, 0x73, 0x74, 0x39, 0x57, 0x46, + 0x44, 0x61, 0x41, 0x61, 0x5a, 0x74, 0x38, 0x78, 0x54, 0x4f, 0x66, 0x66, 0x45, 0x57, 0x33, 0x6e, 0x7a, 0x76, + 0x4b, 0x64, 0x45, 0x73, 0x50, 0x6e, 0x56, 0x62, 0x74, 0x66, 0x51, 0x44, 0x6c, 0x74, 0x5a, 0x38, 0x45, 0x67, + 0x4a, 0x30, 0x67, 0x75, 0x76, 0x6c, 0x35, 0x72, 0x33, 0x33, 0x48, 0x35, 0x4a, 0x64, 0x76, 0x75, 0x6b, 0x31, + 0x32, 0x5c, 0x0a, + 0x09, 0x68, 0x43, 0x5a, 0x6e, 0x6c, 0x57, 0x52, 0x46, 0x51, 0x46, 0x31, 0x66, 0x6c, 0x78, 0x31, 0x56, 0x58, + 0x76, 0x65, 0x76, 0x79, 0x2b, 0x70, 0x6e, 0x2b, 0x64, 0x4d, 0x34, 0x59, 0x44, 0x6d, 0x6b, 0x62, 0x5a, 0x69, + 0x6a, 0x65, 0x45, 0x72, 0x35, 0x72, 0x2f, 0x75, 0x31, 0x78, 0x6a, 0x6a, 0x4b, 0x38, 0x54, 0x51, 0x6f, 0x6a, + 0x41, 0x49, 0x75, 0x33, 0x76, 0x5a, 0x77, 0x4f, 0x4d, 0x54, 0x38, 0x77, 0x67, 0x4b, 0x49, 0x67, 0x4a, 0x34, + 0x72, 0x5c, 0x0a, + 0x09, 0x30, 0x4d, 0x30, 0x79, 0x7a, 0x46, 0x4d, 0x48, 0x47, 0x59, 0x43, 0x4a, 0x73, 0x59, 0x6d, 0x59, 0x44, + 0x7a, 0x62, 0x70, 0x36, 0x57, 0x67, 0x79, 0x46, 0x58, 0x73, 0x38, 0x6f, 0x31, 0x37, 0x74, 0x5a, 0x58, 0x50, + 0x63, 0x4a, 0x41, 0x66, 0x4c, 0x39, 0x4a, 0x76, 0x73, 0x61, 0x5a, 0x51, 0x74, 0x57, 0x66, 0x58, 0x74, 0x74, + 0x6c, 0x49, 0x75, 0x64, 0x45, 0x42, 0x72, 0x41, 0x72, 0x76, 0x56, 0x73, 0x4e, 0x31, 0x77, 0x2f, 0x4e, 0x52, + 0x48, 0x5c, 0x0a, + 0x09, 0x50, 0x68, 0x78, 0x2f, 0x39, 0x6c, 0x39, 0x66, 0x73, 0x67, 0x79, 0x34, 0x41, 0x77, 0x42, 0x75, 0x7a, + 0x63, 0x35, 0x36, 0x43, 0x6c, 0x61, 0x44, 0x56, 0x6e, 0x63, 0x4b, 0x51, 0x50, 0x52, 0x7a, 0x41, 0x43, 0x5a, + 0x2f, 0x37, 0x32, 0x55, 0x2f, 0x69, 0x75, 0x33, 0x6a, 0x31, 0x54, 0x76, 0x51, 0x77, 0x4a, 0x32, 0x70, 0x4a, + 0x71, 0x31, 0x59, 0x50, 0x6d, 0x42, 0x39, 0x57, 0x30, 0x6b, 0x72, 0x52, 0x46, 0x38, 0x4c, 0x39, 0x58, 0x57, + 0x45, 0x5c, 0x0a, + 0x09, 0x34, 0x4d, 0x64, 0x61, 0x37, 0x58, 0x58, 0x45, 0x6b, 0x45, 0x74, 0x30, 0x64, 0x52, 0x33, 0x65, 0x6f, + 0x68, 0x31, 0x31, 0x6d, 0x76, 0x6d, 0x33, 0x2b, 0x70, 0x48, 0x31, 0x30, 0x30, 0x7a, 0x42, 0x33, 0x6c, 0x68, + 0x6a, 0x52, 0x5a, 0x48, 0x67, 0x49, 0x71, 0x4d, 0x7a, 0x6c, 0x6c, 0x51, 0x65, 0x6e, 0x55, 0x34, 0x48, 0x2f, + 0x58, 0x37, 0x66, 0x50, 0x79, 0x4f, 0x51, 0x64, 0x56, 0x43, 0x51, 0x66, 0x2b, 0x50, 0x6d, 0x32, 0x50, 0x67, + 0x34, 0x5c, 0x0a, + 0x09, 0x58, 0x4a, 0x5a, 0x47, 0x56, 0x42, 0x32, 0x4a, 0x39, 0x54, 0x6a, 0x35, 0x65, 0x4b, 0x7a, 0x4d, 0x53, + 0x73, 0x76, 0x56, 0x6b, 0x70, 0x33, 0x65, 0x4c, 0x73, 0x76, 0x37, 0x44, 0x6d, 0x31, 0x5a, 0x57, 0x59, 0x58, + 0x6d, 0x42, 0x38, 0x5a, 0x33, 0x61, 0x34, 0x65, 0x66, 0x4e, 0x53, 0x62, 0x4f, 0x6d, 0x77, 0x58, 0x43, 0x44, + 0x72, 0x4c, 0x50, 0x45, 0x44, 0x52, 0x73, 0x51, 0x4c, 0x50, 0x35, 0x61, 0x67, 0x4b, 0x7a, 0x35, 0x73, 0x42, + 0x55, 0x5c, 0x0a, + 0x09, 0x57, 0x39, 0x37, 0x75, 0x4c, 0x5a, 0x50, 0x34, 0x37, 0x5a, 0x2f, 0x2f, 0x45, 0x51, 0x43, 0x75, 0x43, + 0x39, 0x44, 0x50, 0x6d, 0x59, 0x62, 0x79, 0x45, 0x47, 0x6e, 0x31, 0x41, 0x4d, 0x42, 0x7a, 0x2b, 0x30, 0x77, + 0x34, 0x68, 0x77, 0x4f, 0x6e, 0x37, 0x4d, 0x61, 0x76, 0x76, 0x4f, 0x41, 0x53, 0x4a, 0x6c, 0x67, 0x5a, 0x61, + 0x37, 0x56, 0x52, 0x70, 0x77, 0x4b, 0x33, 0x49, 0x78, 0x73, 0x2f, 0x4b, 0x78, 0x58, 0x53, 0x6e, 0x4b, 0x70, + 0x70, 0x5c, 0x0a, + 0x09, 0x49, 0x2b, 0x54, 0x74, 0x4e, 0x53, 0x56, 0x53, 0x55, 0x75, 0x45, 0x72, 0x37, 0x38, 0x6a, 0x54, 0x69, + 0x71, 0x39, 0x48, 0x4f, 0x37, 0x6f, 0x65, 0x2f, 0x7a, 0x5a, 0x71, 0x46, 0x39, 0x73, 0x6f, 0x35, 0x77, 0x35, + 0x6c, 0x6e, 0x62, 0x72, 0x47, 0x5a, 0x63, 0x71, 0x76, 0x39, 0x58, 0x73, 0x39, 0x64, 0x4c, 0x70, 0x64, 0x6c, + 0x4d, 0x35, 0x68, 0x32, 0x66, 0x6c, 0x46, 0x51, 0x71, 0x4b, 0x6d, 0x4a, 0x79, 0x51, 0x6c, 0x2b, 0x44, 0x56, + 0x46, 0x5c, 0x0a, + 0x09, 0x74, 0x79, 0x62, 0x6e, 0x74, 0x67, 0x79, 0x63, 0x39, 0x79, 0x54, 0x31, 0x62, 0x67, 0x63, 0x4a, 0x32, + 0x7a, 0x6e, 0x53, 0x5a, 0x7a, 0x71, 0x31, 0x30, 0x77, 0x53, 0x37, 0x53, 0x2b, 0x33, 0x43, 0x47, 0x6b, 0x31, + 0x39, 0x4a, 0x72, 0x55, 0x35, 0x61, 0x35, 0x71, 0x61, 0x4c, 0x6c, 0x6c, 0x62, 0x34, 0x44, 0x51, 0x4b, 0x49, + 0x43, 0x7a, 0x62, 0x74, 0x32, 0x77, 0x33, 0x4a, 0x2b, 0x43, 0x33, 0x58, 0x76, 0x51, 0x63, 0x6e, 0x4c, 0x68, + 0x7a, 0x5c, 0x0a, + 0x09, 0x79, 0x70, 0x64, 0x30, 0x37, 0x76, 0x73, 0x54, 0x78, 0x76, 0x38, 0x64, 0x74, 0x48, 0x6f, 0x41, 0x34, + 0x41, 0x44, 0x41, 0x6e, 0x65, 0x32, 0x50, 0x48, 0x56, 0x37, 0x34, 0x39, 0x41, 0x76, 0x77, 0x2f, 0x4d, 0x63, + 0x2f, 0x52, 0x71, 0x6b, 0x62, 0x36, 0x73, 0x69, 0x54, 0x68, 0x59, 0x35, 0x4e, 0x35, 0x32, 0x73, 0x44, 0x53, + 0x41, 0x56, 0x6e, 0x4f, 0x58, 0x56, 0x7a, 0x65, 0x6a, 0x58, 0x36, 0x4c, 0x54, 0x2b, 0x36, 0x48, 0x59, 0x6e, + 0x2b, 0x5c, 0x0a, + 0x09, 0x2f, 0x46, 0x79, 0x54, 0x6b, 0x39, 0x67, 0x50, 0x41, 0x45, 0x6e, 0x6a, 0x73, 0x48, 0x59, 0x63, 0x6a, + 0x42, 0x34, 0x50, 0x6b, 0x6e, 0x4f, 0x32, 0x49, 0x65, 0x73, 0x49, 0x79, 0x6b, 0x48, 0x4e, 0x50, 0x7a, 0x69, + 0x55, 0x49, 0x79, 0x4e, 0x2f, 0x7a, 0x7a, 0x2f, 0x64, 0x39, 0x6d, 0x79, 0x50, 0x77, 0x4d, 0x6f, 0x34, 0x4c, + 0x47, 0x4f, 0x33, 0x53, 0x4d, 0x62, 0x35, 0x64, 0x41, 0x32, 0x48, 0x5a, 0x77, 0x6b, 0x32, 0x4c, 0x39, 0x78, + 0x5a, 0x5c, 0x0a, + 0x09, 0x58, 0x4e, 0x4b, 0x4f, 0x35, 0x44, 0x47, 0x31, 0x74, 0x5a, 0x72, 0x66, 0x65, 0x73, 0x32, 0x68, 0x53, + 0x62, 0x5a, 0x36, 0x62, 0x4b, 0x4e, 0x41, 0x6d, 0x4e, 0x64, 0x4d, 0x67, 0x61, 0x36, 0x32, 0x6a, 0x6d, 0x5a, + 0x37, 0x6b, 0x70, 0x2f, 0x68, 0x4f, 0x46, 0x7a, 0x2f, 0x6d, 0x52, 0x39, 0x34, 0x45, 0x69, 0x36, 0x35, 0x36, + 0x4e, 0x79, 0x71, 0x6b, 0x67, 0x4d, 0x49, 0x71, 0x2f, 0x72, 0x53, 0x38, 0x4e, 0x57, 0x64, 0x41, 0x6a, 0x68, + 0x4d, 0x5c, 0x0a, + 0x09, 0x38, 0x66, 0x66, 0x35, 0x76, 0x2b, 0x6e, 0x6e, 0x6e, 0x34, 0x39, 0x7a, 0x54, 0x7a, 0x30, 0x70, 0x4b, + 0x57, 0x5a, 0x46, 0x4e, 0x32, 0x30, 0x51, 0x56, 0x6e, 0x53, 0x72, 0x42, 0x57, 0x75, 0x62, 0x6e, 0x58, 0x61, + 0x6d, 0x4a, 0x75, 0x50, 0x55, 0x66, 0x66, 0x4b, 0x36, 0x32, 0x67, 0x41, 0x35, 0x50, 0x31, 0x59, 0x45, 0x31, + 0x50, 0x66, 0x34, 0x72, 0x66, 0x54, 0x53, 0x47, 0x69, 0x38, 0x33, 0x36, 0x4b, 0x5a, 0x73, 0x77, 0x68, 0x70, + 0x48, 0x5c, 0x0a, + 0x09, 0x6b, 0x35, 0x4d, 0x32, 0x52, 0x2b, 0x49, 0x55, 0x4c, 0x68, 0x79, 0x41, 0x79, 0x66, 0x45, 0x4a, 0x55, + 0x42, 0x37, 0x57, 0x67, 0x4f, 0x31, 0x62, 0x58, 0x71, 0x6e, 0x63, 0x4b, 0x4f, 0x45, 0x31, 0x33, 0x51, 0x56, + 0x6f, 0x50, 0x2b, 0x53, 0x6c, 0x59, 0x37, 0x59, 0x65, 0x55, 0x35, 0x4d, 0x38, 0x5a, 0x46, 0x2b, 0x68, 0x4a, + 0x56, 0x6b, 0x33, 0x6b, 0x49, 0x37, 0x79, 0x54, 0x55, 0x47, 0x69, 0x43, 0x64, 0x68, 0x57, 0x30, 0x68, 0x33, + 0x59, 0x5c, 0x0a, + 0x09, 0x39, 0x7a, 0x54, 0x69, 0x36, 0x79, 0x63, 0x33, 0x55, 0x38, 0x36, 0x30, 0x62, 0x69, 0x7a, 0x65, 0x2b, + 0x4c, 0x55, 0x6e, 0x6e, 0x72, 0x6b, 0x66, 0x76, 0x2f, 0x4c, 0x43, 0x5a, 0x37, 0x43, 0x54, 0x42, 0x49, 0x41, + 0x6d, 0x56, 0x6b, 0x54, 0x62, 0x37, 0x34, 0x4a, 0x57, 0x65, 0x77, 0x32, 0x67, 0x65, 0x6a, 0x65, 0x56, 0x41, + 0x77, 0x67, 0x59, 0x36, 0x32, 0x5a, 0x34, 0x37, 0x36, 0x2b, 0x38, 0x43, 0x4b, 0x64, 0x73, 0x6e, 0x7a, 0x59, + 0x46, 0x5c, 0x0a, + 0x09, 0x4f, 0x47, 0x72, 0x6e, 0x56, 0x6c, 0x4d, 0x45, 0x6b, 0x44, 0x75, 0x6b, 0x48, 0x45, 0x67, 0x5a, 0x42, + 0x43, 0x39, 0x76, 0x6f, 0x57, 0x34, 0x64, 0x2f, 0x65, 0x73, 0x53, 0x2b, 0x74, 0x61, 0x4e, 0x4e, 0x67, 0x44, + 0x70, 0x32, 0x50, 0x62, 0x72, 0x78, 0x44, 0x51, 0x31, 0x4f, 0x62, 0x34, 0x75, 0x4d, 0x79, 0x71, 0x43, 0x63, + 0x71, 0x66, 0x67, 0x66, 0x49, 0x30, 0x61, 0x57, 0x78, 0x72, 0x78, 0x39, 0x66, 0x37, 0x35, 0x53, 0x6d, 0x49, + 0x45, 0x5c, 0x0a, + 0x09, 0x63, 0x35, 0x2b, 0x2f, 0x64, 0x6e, 0x34, 0x5a, 0x6c, 0x56, 0x50, 0x48, 0x30, 0x66, 0x4b, 0x77, 0x70, + 0x47, 0x48, 0x6c, 0x46, 0x39, 0x59, 0x36, 0x6a, 0x33, 0x54, 0x62, 0x5a, 0x73, 0x44, 0x56, 0x63, 0x74, 0x44, + 0x79, 0x71, 0x48, 0x6d, 0x79, 0x34, 0x36, 0x38, 0x46, 0x6c, 0x45, 0x30, 0x41, 0x62, 0x31, 0x33, 0x54, 0x34, + 0x77, 0x6a, 0x6c, 0x62, 0x66, 0x6d, 0x73, 0x33, 0x49, 0x66, 0x56, 0x39, 0x73, 0x4e, 0x50, 0x32, 0x49, 0x4e, + 0x33, 0x5c, 0x0a, + 0x09, 0x76, 0x50, 0x4b, 0x6e, 0x30, 0x45, 0x31, 0x58, 0x2f, 0x41, 0x76, 0x54, 0x34, 0x42, 0x34, 0x69, 0x72, + 0x66, 0x59, 0x2b, 0x67, 0x48, 0x74, 0x30, 0x7a, 0x44, 0x78, 0x78, 0x35, 0x7a, 0x54, 0x65, 0x2f, 0x56, 0x39, + 0x65, 0x68, 0x47, 0x31, 0x6a, 0x66, 0x53, 0x50, 0x4b, 0x36, 0x70, 0x46, 0x49, 0x56, 0x31, 0x77, 0x4a, 0x4e, + 0x46, 0x4a, 0x41, 0x47, 0x49, 0x58, 0x51, 0x2f, 0x4a, 0x77, 0x54, 0x6e, 0x79, 0x45, 0x64, 0x64, 0x45, 0x62, + 0x37, 0x5c, 0x0a, + 0x09, 0x76, 0x4a, 0x35, 0x31, 0x58, 0x6b, 0x65, 0x4e, 0x65, 0x68, 0x53, 0x70, 0x57, 0x70, 0x73, 0x69, 0x71, + 0x34, 0x34, 0x56, 0x45, 0x68, 0x6a, 0x30, 0x61, 0x38, 0x62, 0x73, 0x64, 0x4e, 0x4c, 0x4b, 0x63, 0x71, 0x7a, + 0x4d, 0x68, 0x62, 0x74, 0x51, 0x65, 0x4c, 0x57, 0x58, 0x72, 0x70, 0x39, 0x47, 0x5a, 0x58, 0x73, 0x35, 0x7a, + 0x58, 0x61, 0x59, 0x5a, 0x41, 0x39, 0x37, 0x76, 0x4f, 0x35, 0x45, 0x43, 0x53, 0x66, 0x71, 0x63, 0x56, 0x43, + 0x33, 0x5c, 0x0a, + 0x09, 0x31, 0x6f, 0x41, 0x34, 0x6e, 0x30, 0x30, 0x4f, 0x72, 0x55, 0x47, 0x58, 0x62, 0x37, 0x57, 0x57, 0x54, + 0x6b, 0x2b, 0x69, 0x6e, 0x69, 0x5a, 0x43, 0x73, 0x32, 0x35, 0x72, 0x2f, 0x71, 0x57, 0x56, 0x6a, 0x67, 0x49, + 0x50, 0x4f, 0x62, 0x36, 0x56, 0x6e, 0x35, 0x73, 0x34, 0x66, 0x6e, 0x6f, 0x72, 0x2f, 0x75, 0x68, 0x58, 0x58, + 0x6f, 0x77, 0x64, 0x57, 0x2f, 0x71, 0x71, 0x59, 0x51, 0x63, 0x34, 0x64, 0x36, 0x66, 0x42, 0x38, 0x6b, 0x4f, + 0x6d, 0x5c, 0x0a, + 0x09, 0x56, 0x5a, 0x34, 0x43, 0x75, 0x43, 0x73, 0x73, 0x77, 0x7a, 0x2f, 0x6e, 0x74, 0x42, 0x50, 0x78, 0x33, + 0x6c, 0x64, 0x36, 0x45, 0x4c, 0x43, 0x69, 0x47, 0x56, 0x65, 0x2b, 0x2f, 0x7a, 0x38, 0x56, 0x61, 0x71, 0x31, + 0x41, 0x6e, 0x65, 0x6a, 0x56, 0x52, 0x74, 0x47, 0x73, 0x73, 0x4f, 0x2f, 0x6d, 0x76, 0x45, 0x75, 0x75, 0x4e, + 0x52, 0x6c, 0x4a, 0x33, 0x62, 0x65, 0x6b, 0x65, 0x6f, 0x59, 0x71, 0x65, 0x65, 0x63, 0x39, 0x63, 0x43, 0x4f, + 0x53, 0x5c, 0x0a, + 0x09, 0x34, 0x39, 0x54, 0x52, 0x7a, 0x34, 0x6e, 0x7a, 0x54, 0x6b, 0x6d, 0x6e, 0x61, 0x57, 0x78, 0x61, 0x53, + 0x6b, 0x31, 0x52, 0x6b, 0x33, 0x39, 0x61, 0x45, 0x63, 0x74, 0x71, 0x33, 0x53, 0x6c, 0x4e, 0x38, 0x46, 0x7a, + 0x4b, 0x6c, 0x71, 0x5a, 0x73, 0x54, 0x30, 0x39, 0x62, 0x39, 0x4c, 0x46, 0x46, 0x36, 0x57, 0x34, 0x35, 0x2b, + 0x57, 0x42, 0x56, 0x6d, 0x6a, 0x4e, 0x59, 0x6f, 0x46, 0x68, 0x7a, 0x6f, 0x47, 0x58, 0x4f, 0x78, 0x39, 0x38, + 0x55, 0x5c, 0x0a, + 0x09, 0x54, 0x50, 0x69, 0x6f, 0x4e, 0x4a, 0x6a, 0x77, 0x50, 0x71, 0x30, 0x67, 0x78, 0x6d, 0x74, 0x61, 0x6a, + 0x68, 0x2b, 0x64, 0x66, 0x32, 0x6f, 0x72, 0x2f, 0x75, 0x4b, 0x31, 0x50, 0x34, 0x75, 0x39, 0x4a, 0x32, 0x79, + 0x48, 0x2f, 0x45, 0x33, 0x44, 0x32, 0x4d, 0x48, 0x6e, 0x73, 0x49, 0x71, 0x30, 0x32, 0x6c, 0x4f, 0x41, 0x39, + 0x34, 0x72, 0x76, 0x37, 0x49, 0x63, 0x50, 0x4c, 0x7a, 0x78, 0x6e, 0x50, 0x39, 0x35, 0x39, 0x36, 0x59, 0x73, + 0x77, 0x5c, 0x0a, + 0x09, 0x50, 0x65, 0x34, 0x66, 0x4d, 0x74, 0x48, 0x52, 0x53, 0x55, 0x63, 0x39, 0x6f, 0x42, 0x61, 0x77, 0x6c, + 0x53, 0x70, 0x71, 0x68, 0x4c, 0x59, 0x45, 0x43, 0x33, 0x5a, 0x64, 0x47, 0x35, 0x6f, 0x32, 0x48, 0x76, 0x6b, + 0x35, 0x2b, 0x6b, 0x63, 0x73, 0x62, 0x49, 0x64, 0x6d, 0x59, 0x6a, 0x69, 0x4b, 0x2f, 0x71, 0x55, 0x52, 0x38, + 0x62, 0x4a, 0x70, 0x39, 0x4e, 0x4f, 0x6d, 0x70, 0x4a, 0x38, 0x64, 0x48, 0x44, 0x55, 0x6d, 0x36, 0x7a, 0x6b, + 0x45, 0x5c, 0x0a, + 0x09, 0x7a, 0x5a, 0x63, 0x56, 0x50, 0x53, 0x33, 0x6a, 0x74, 0x79, 0x4b, 0x6d, 0x4e, 0x4e, 0x48, 0x6d, 0x68, + 0x35, 0x71, 0x73, 0x42, 0x33, 0x71, 0x61, 0x51, 0x4d, 0x73, 0x43, 0x68, 0x58, 0x53, 0x74, 0x52, 0x55, 0x35, + 0x74, 0x6d, 0x76, 0x76, 0x6c, 0x31, 0x31, 0x4d, 0x62, 0x30, 0x52, 0x76, 0x4c, 0x30, 0x67, 0x56, 0x52, 0x43, + 0x59, 0x4d, 0x70, 0x51, 0x4b, 0x53, 0x4c, 0x6c, 0x39, 0x6f, 0x65, 0x74, 0x53, 0x34, 0x31, 0x63, 0x49, 0x5a, + 0x79, 0x5c, 0x0a, + 0x09, 0x4a, 0x30, 0x35, 0x50, 0x34, 0x58, 0x33, 0x2f, 0x35, 0x61, 0x66, 0x78, 0x38, 0x46, 0x50, 0x33, 0x31, + 0x42, 0x57, 0x53, 0x33, 0x32, 0x76, 0x45, 0x32, 0x37, 0x47, 0x4b, 0x74, 0x49, 0x71, 0x33, 0x41, 0x51, 0x6c, + 0x77, 0x37, 0x6d, 0x4e, 0x77, 0x37, 0x70, 0x33, 0x4a, 0x2b, 0x59, 0x6f, 0x75, 0x4f, 0x6e, 0x63, 0x2f, 0x50, + 0x76, 0x44, 0x61, 0x6e, 0x38, 0x4d, 0x70, 0x32, 0x36, 0x62, 0x4d, 0x69, 0x42, 0x4f, 0x6f, 0x56, 0x6f, 0x6a, + 0x39, 0x5c, 0x0a, + 0x09, 0x49, 0x4d, 0x30, 0x6f, 0x4a, 0x56, 0x74, 0x6c, 0x64, 0x48, 0x61, 0x67, 0x6e, 0x56, 0x76, 0x58, 0x30, + 0x61, 0x76, 0x4c, 0x73, 0x6f, 0x35, 0x38, 0x36, 0x49, 0x58, 0x7a, 0x78, 0x71, 0x4d, 0x53, 0x50, 0x34, 0x5a, + 0x71, 0x78, 0x2b, 0x6f, 0x2f, 0x64, 0x61, 0x77, 0x30, 0x67, 0x6e, 0x42, 0x4a, 0x36, 0x49, 0x69, 0x56, 0x41, + 0x6f, 0x59, 0x4e, 0x68, 0x35, 0x5a, 0x7a, 0x61, 0x65, 0x65, 0x30, 0x2b, 0x4e, 0x62, 0x58, 0x72, 0x57, 0x74, + 0x70, 0x5c, 0x0a, + 0x09, 0x2b, 0x33, 0x57, 0x37, 0x2b, 0x6f, 0x47, 0x65, 0x65, 0x6c, 0x6f, 0x68, 0x6f, 0x55, 0x62, 0x6d, 0x4f, + 0x32, 0x6e, 0x62, 0x7a, 0x56, 0x48, 0x5a, 0x72, 0x71, 0x33, 0x35, 0x53, 0x6b, 0x74, 0x72, 0x77, 0x45, 0x30, + 0x74, 0x30, 0x67, 0x49, 0x39, 0x66, 0x6c, 0x34, 0x43, 0x4a, 0x70, 0x38, 0x43, 0x70, 0x55, 0x38, 0x2b, 0x57, + 0x4f, 0x30, 0x41, 0x77, 0x46, 0x6b, 0x6e, 0x37, 0x4d, 0x45, 0x48, 0x58, 0x2f, 0x63, 0x4b, 0x6e, 0x48, 0x66, + 0x67, 0x5c, 0x0a, + 0x09, 0x70, 0x4e, 0x72, 0x70, 0x6b, 0x35, 0x2b, 0x62, 0x70, 0x31, 0x38, 0x46, 0x38, 0x41, 0x56, 0x6a, 0x4b, + 0x41, 0x2b, 0x5a, 0x56, 0x67, 0x30, 0x41, 0x73, 0x72, 0x4f, 0x65, 0x48, 0x41, 0x35, 0x2f, 0x45, 0x58, 0x41, + 0x76, 0x42, 0x50, 0x42, 0x31, 0x2f, 0x35, 0x55, 0x4e, 0x42, 0x72, 0x6a, 0x2b, 0x33, 0x50, 0x30, 0x6e, 0x76, + 0x75, 0x57, 0x56, 0x50, 0x2f, 0x4b, 0x4d, 0x52, 0x78, 0x50, 0x6f, 0x58, 0x51, 0x44, 0x6d, 0x41, 0x52, 0x77, + 0x42, 0x5c, 0x0a, + 0x09, 0x55, 0x46, 0x67, 0x6d, 0x30, 0x5a, 0x78, 0x6b, 0x70, 0x59, 0x72, 0x56, 0x78, 0x6d, 0x6b, 0x39, 0x55, + 0x47, 0x49, 0x5a, 0x6a, 0x32, 0x56, 0x63, 0x2f, 0x4c, 0x79, 0x4f, 0x37, 0x74, 0x78, 0x67, 0x55, 0x71, 0x50, + 0x69, 0x45, 0x56, 0x41, 0x76, 0x76, 0x75, 0x6d, 0x53, 0x4b, 0x78, 0x6d, 0x6e, 0x45, 0x34, 0x62, 0x45, 0x2b, + 0x78, 0x73, 0x56, 0x4b, 0x53, 0x6d, 0x70, 0x54, 0x36, 0x49, 0x4d, 0x7a, 0x36, 0x70, 0x34, 0x74, 0x4a, 0x4a, + 0x31, 0x5c, 0x0a, + 0x09, 0x6a, 0x34, 0x34, 0x73, 0x6d, 0x63, 0x6d, 0x36, 0x64, 0x6b, 0x74, 0x53, 0x67, 0x79, 0x6d, 0x63, 0x36, + 0x6d, 0x6c, 0x4f, 0x63, 0x2f, 0x38, 0x53, 0x75, 0x45, 0x49, 0x4e, 0x65, 0x2f, 0x72, 0x56, 0x70, 0x41, 0x6e, + 0x37, 0x43, 0x75, 0x63, 0x6f, 0x72, 0x5a, 0x57, 0x75, 0x63, 0x77, 0x52, 0x51, 0x6b, 0x78, 0x6d, 0x63, 0x4c, + 0x52, 0x45, 0x72, 0x75, 0x4e, 0x77, 0x39, 0x63, 0x2f, 0x69, 0x36, 0x76, 0x53, 0x64, 0x73, 0x2f, 0x79, 0x55, + 0x41, 0x5c, 0x0a, + 0x09, 0x6c, 0x34, 0x4e, 0x6f, 0x68, 0x74, 0x57, 0x59, 0x41, 0x66, 0x41, 0x78, 0x41, 0x45, 0x38, 0x44, 0x38, + 0x47, 0x59, 0x51, 0x49, 0x58, 0x76, 0x6b, 0x55, 0x38, 0x78, 0x78, 0x50, 0x42, 0x52, 0x61, 0x39, 0x5a, 0x38, + 0x47, 0x4b, 0x36, 0x2f, 0x37, 0x70, 0x44, 0x39, 0x77, 0x41, 0x49, 0x69, 0x6d, 0x41, 0x4f, 0x77, 0x44, 0x55, + 0x4d, 0x4b, 0x35, 0x57, 0x77, 0x41, 0x63, 0x75, 0x66, 0x33, 0x65, 0x67, 0x2f, 0x6a, 0x6f, 0x46, 0x56, 0x66, + 0x6a, 0x5c, 0x0a, + 0x09, 0x6f, 0x31, 0x2f, 0x38, 0x4f, 0x71, 0x36, 0x73, 0x74, 0x67, 0x73, 0x54, 0x38, 0x4c, 0x38, 0x42, 0x2f, + 0x47, 0x43, 0x6f, 0x56, 0x70, 0x32, 0x72, 0x6d, 0x32, 0x48, 0x74, 0x70, 0x34, 0x71, 0x56, 0x35, 0x58, 0x55, + 0x64, 0x4b, 0x31, 0x72, 0x7a, 0x74, 0x4d, 0x39, 0x71, 0x67, 0x39, 0x66, 0x52, 0x5a, 0x58, 0x6a, 0x5a, 0x55, + 0x55, 0x36, 0x70, 0x32, 0x32, 0x6a, 0x69, 0x53, 0x34, 0x39, 0x4c, 0x74, 0x39, 0x45, 0x30, 0x50, 0x73, 0x36, + 0x44, 0x5c, 0x0a, + 0x09, 0x35, 0x6f, 0x74, 0x66, 0x61, 0x5a, 0x49, 0x46, 0x67, 0x54, 0x41, 0x73, 0x68, 0x76, 0x46, 0x74, 0x77, + 0x6b, 0x63, 0x37, 0x33, 0x6c, 0x48, 0x6e, 0x6d, 0x73, 0x59, 0x4a, 0x53, 0x4f, 0x64, 0x6f, 0x49, 0x6f, 0x75, + 0x48, 0x70, 0x6e, 0x4f, 0x61, 0x52, 0x75, 0x6c, 0x73, 0x56, 0x46, 0x33, 0x75, 0x75, 0x4e, 0x71, 0x52, 0x6d, + 0x2b, 0x71, 0x74, 0x70, 0x45, 0x64, 0x62, 0x66, 0x33, 0x58, 0x72, 0x31, 0x6a, 0x6f, 0x57, 0x67, 0x50, 0x2f, + 0x2f, 0x5c, 0x0a, + 0x09, 0x4a, 0x79, 0x36, 0x2b, 0x34, 0x44, 0x6c, 0x76, 0x66, 0x50, 0x46, 0x7a, 0x71, 0x67, 0x73, 0x30, 0x58, + 0x51, 0x58, 0x4e, 0x47, 0x56, 0x2f, 0x49, 0x6c, 0x32, 0x53, 0x42, 0x64, 0x6c, 0x56, 0x6f, 0x7a, 0x58, 0x34, + 0x62, 0x73, 0x4c, 0x7a, 0x75, 0x55, 0x2f, 0x55, 0x58, 0x31, 0x6f, 0x64, 0x47, 0x72, 0x2b, 0x6f, 0x39, 0x67, + 0x6a, 0x2f, 0x75, 0x67, 0x41, 0x2b, 0x6b, 0x53, 0x58, 0x4f, 0x7a, 0x41, 0x73, 0x44, 0x4f, 0x61, 0x36, 0x58, + 0x78, 0x5c, 0x0a, + 0x09, 0x63, 0x6e, 0x72, 0x50, 0x64, 0x6a, 0x67, 0x48, 0x32, 0x4f, 0x61, 0x6f, 0x6e, 0x58, 0x59, 0x6c, 0x58, + 0x71, 0x44, 0x61, 0x49, 0x6e, 0x55, 0x2b, 0x50, 0x5a, 0x59, 0x38, 0x36, 0x50, 0x48, 0x77, 0x32, 0x6b, 0x31, + 0x39, 0x48, 0x38, 0x31, 0x78, 0x33, 0x55, 0x39, 0x7a, 0x2f, 0x61, 0x49, 0x6f, 0x6b, 0x4c, 0x4e, 0x62, 0x67, + 0x64, 0x2b, 0x4e, 0x4a, 0x54, 0x53, 0x50, 0x54, 0x73, 0x71, 0x33, 0x4f, 0x59, 0x62, 0x7a, 0x58, 0x43, 0x57, + 0x74, 0x5c, 0x0a, + 0x09, 0x4d, 0x30, 0x6f, 0x48, 0x7a, 0x61, 0x42, 0x67, 0x41, 0x31, 0x38, 0x6f, 0x4d, 0x57, 0x71, 0x64, 0x53, + 0x4c, 0x5a, 0x76, 0x77, 0x2b, 0x41, 0x6f, 0x50, 0x64, 0x6c, 0x41, 0x30, 0x74, 0x77, 0x76, 0x42, 0x38, 0x5a, + 0x71, 0x33, 0x47, 0x38, 0x42, 0x38, 0x4f, 0x72, 0x62, 0x72, 0x2f, 0x71, 0x53, 0x39, 0x35, 0x30, 0x52, 0x50, + 0x72, 0x4f, 0x61, 0x74, 0x47, 0x70, 0x50, 0x41, 0x32, 0x72, 0x36, 0x37, 0x70, 0x43, 0x4b, 0x50, 0x6b, 0x78, + 0x77, 0x5c, 0x0a, + 0x09, 0x4d, 0x77, 0x35, 0x75, 0x47, 0x6d, 0x69, 0x4b, 0x4c, 0x50, 0x62, 0x44, 0x46, 0x39, 0x4b, 0x74, 0x30, + 0x69, 0x68, 0x6e, 0x50, 0x57, 0x31, 0x6c, 0x47, 0x61, 0x64, 0x6c, 0x57, 0x4a, 0x59, 0x6a, 0x70, 0x51, 0x59, + 0x6b, 0x6a, 0x56, 0x61, 0x32, 0x6d, 0x50, 0x4a, 0x57, 0x74, 0x39, 0x48, 0x38, 0x31, 0x42, 0x6b, 0x48, 0x6b, + 0x5a, 0x58, 0x53, 0x38, 0x7a, 0x42, 0x47, 0x7a, 0x59, 0x4d, 0x65, 0x76, 0x39, 0x56, 0x2b, 0x52, 0x76, 0x5a, + 0x4f, 0x5c, 0x0a, + 0x09, 0x6a, 0x4b, 0x4f, 0x52, 0x41, 0x34, 0x7a, 0x6a, 0x55, 0x63, 0x36, 0x6a, 0x78, 0x77, 0x4d, 0x34, 0x79, + 0x4f, 0x63, 0x66, 0x4e, 0x45, 0x67, 0x33, 0x6a, 0x58, 0x63, 0x55, 0x4f, 0x49, 0x51, 0x32, 0x72, 0x48, 0x78, + 0x44, 0x77, 0x68, 0x56, 0x33, 0x30, 0x44, 0x52, 0x50, 0x73, 0x53, 0x4b, 0x30, 0x66, 0x46, 0x4c, 0x54, 0x44, + 0x6b, 0x68, 0x57, 0x76, 0x73, 0x50, 0x72, 0x57, 0x50, 0x71, 0x4d, 0x33, 0x37, 0x38, 0x65, 0x61, 0x71, 0x39, + 0x32, 0x5c, 0x0a, + 0x09, 0x6c, 0x42, 0x39, 0x46, 0x36, 0x2f, 0x4c, 0x6a, 0x6f, 0x4b, 0x4f, 0x4a, 0x41, 0x4c, 0x67, 0x46, 0x41, + 0x42, 0x2b, 0x51, 0x5a, 0x2f, 0x56, 0x43, 0x6b, 0x42, 0x53, 0x63, 0x4c, 0x68, 0x75, 0x75, 0x53, 0x55, 0x64, + 0x4e, 0x30, 0x33, 0x7a, 0x52, 0x4b, 0x32, 0x43, 0x32, 0x36, 0x70, 0x4b, 0x53, 0x36, 0x54, 0x57, 0x58, 0x6c, + 0x4c, 0x4f, 0x4e, 0x6f, 0x6a, 0x6d, 0x71, 0x45, 0x76, 0x76, 0x66, 0x67, 0x6f, 0x76, 0x67, 0x76, 0x43, 0x54, + 0x4f, 0x5c, 0x0a, + 0x09, 0x38, 0x54, 0x48, 0x79, 0x36, 0x4d, 0x4a, 0x62, 0x71, 0x35, 0x31, 0x58, 0x6d, 0x6d, 0x5a, 0x69, 0x75, + 0x45, 0x35, 0x7a, 0x6e, 0x58, 0x4b, 0x6e, 0x2b, 0x64, 0x50, 0x6a, 0x54, 0x72, 0x4f, 0x78, 0x4e, 0x42, 0x75, + 0x71, 0x36, 0x37, 0x71, 0x6b, 0x72, 0x41, 0x62, 0x7a, 0x55, 0x66, 0x4b, 0x56, 0x59, 0x36, 0x76, 0x62, 0x61, + 0x51, 0x4c, 0x6c, 0x64, 0x45, 0x7a, 0x61, 0x41, 0x58, 0x55, 0x57, 0x74, 0x6a, 0x4c, 0x76, 0x46, 0x74, 0x69, + 0x54, 0x5c, 0x0a, + 0x09, 0x4f, 0x75, 0x4b, 0x41, 0x4c, 0x4b, 0x2f, 0x4c, 0x57, 0x6b, 0x71, 0x4f, 0x56, 0x78, 0x6b, 0x73, 0x72, + 0x7a, 0x6c, 0x74, 0x4f, 0x41, 0x44, 0x63, 0x64, 0x74, 0x55, 0x56, 0x34, 0x66, 0x43, 0x74, 0x41, 0x41, 0x71, + 0x4e, 0x6a, 0x50, 0x34, 0x34, 0x4b, 0x4e, 0x70, 0x36, 0x6d, 0x30, 0x6f, 0x74, 0x38, 0x42, 0x53, 0x33, 0x6d, + 0x31, 0x66, 0x73, 0x51, 0x79, 0x6c, 0x74, 0x69, 0x4c, 0x79, 0x46, 0x46, 0x4d, 0x47, 0x74, 0x43, 0x43, 0x6a, + 0x76, 0x5c, 0x0a, + 0x09, 0x52, 0x33, 0x4e, 0x48, 0x73, 0x7a, 0x4d, 0x44, 0x7a, 0x59, 0x55, 0x38, 0x55, 0x2f, 0x65, 0x52, 0x76, + 0x6a, 0x34, 0x36, 0x6a, 0x55, 0x7a, 0x61, 0x58, 0x4f, 0x30, 0x78, 0x51, 0x68, 0x31, 0x48, 0x57, 0x52, 0x46, + 0x59, 0x71, 0x2f, 0x4c, 0x35, 0x69, 0x6e, 0x43, 0x6c, 0x48, 0x6b, 0x2b, 0x36, 0x4d, 0x6c, 0x39, 0x48, 0x2f, + 0x46, 0x51, 0x6e, 0x6e, 0x45, 0x69, 0x56, 0x35, 0x58, 0x64, 0x53, 0x6f, 0x44, 0x34, 0x74, 0x66, 0x75, 0x31, + 0x4d, 0x5c, 0x0a, + 0x09, 0x59, 0x7a, 0x53, 0x77, 0x32, 0x32, 0x33, 0x71, 0x67, 0x43, 0x44, 0x74, 0x70, 0x73, 0x6c, 0x47, 0x6d, + 0x6e, 0x6a, 0x56, 0x2f, 0x56, 0x74, 0x54, 0x30, 0x4a, 0x6f, 0x76, 0x45, 0x6e, 0x4b, 0x55, 0x65, 0x79, 0x48, + 0x6f, 0x4d, 0x41, 0x48, 0x58, 0x47, 0x63, 0x4e, 0x5a, 0x63, 0x39, 0x70, 0x77, 0x41, 0x41, 0x6a, 0x6b, 0x2f, + 0x4a, 0x75, 0x45, 0x2f, 0x6b, 0x5a, 0x48, 0x5a, 0x47, 0x36, 0x55, 0x58, 0x4d, 0x42, 0x79, 0x42, 0x56, 0x67, + 0x2f, 0x5c, 0x0a, + 0x09, 0x48, 0x44, 0x51, 0x71, 0x2f, 0x6b, 0x6f, 0x38, 0x62, 0x6a, 0x49, 0x6d, 0x33, 0x6f, 0x4a, 0x73, 0x57, + 0x2f, 0x65, 0x76, 0x55, 0x33, 0x6e, 0x4a, 0x75, 0x78, 0x30, 0x70, 0x5a, 0x44, 0x38, 0x45, 0x62, 0x71, 0x67, + 0x6b, 0x2b, 0x70, 0x45, 0x77, 0x70, 0x45, 0x64, 0x56, 0x47, 0x31, 0x4e, 0x61, 0x4b, 0x6f, 0x32, 0x55, 0x75, + 0x6f, 0x53, 0x56, 0x59, 0x65, 0x6b, 0x78, 0x31, 0x4f, 0x56, 0x53, 0x57, 0x65, 0x72, 0x7a, 0x2b, 0x74, 0x5a, + 0x6e, 0x5c, 0x0a, + 0x09, 0x71, 0x67, 0x55, 0x58, 0x2b, 0x65, 0x56, 0x6a, 0x31, 0x65, 0x50, 0x53, 0x51, 0x43, 0x52, 0x35, 0x6c, + 0x52, 0x5a, 0x67, 0x5a, 0x51, 0x37, 0x61, 0x53, 0x58, 0x55, 0x66, 0x56, 0x74, 0x38, 0x61, 0x5a, 0x4e, 0x4b, + 0x6f, 0x62, 0x67, 0x57, 0x59, 0x5a, 0x71, 0x44, 0x56, 0x59, 0x4d, 0x5a, 0x33, 0x6e, 0x36, 0x62, 0x42, 0x78, + 0x48, 0x30, 0x47, 0x4c, 0x50, 0x69, 0x74, 0x4a, 0x78, 0x30, 0x54, 0x41, 0x48, 0x44, 0x62, 0x56, 0x56, 0x38, + 0x43, 0x5c, 0x0a, + 0x09, 0x41, 0x44, 0x6a, 0x67, 0x74, 0x51, 0x51, 0x73, 0x63, 0x6e, 0x4e, 0x4f, 0x6f, 0x33, 0x30, 0x67, 0x2f, + 0x68, 0x77, 0x41, 0x56, 0x37, 0x73, 0x38, 0x73, 0x6a, 0x66, 0x4f, 0x31, 0x75, 0x55, 0x30, 0x77, 0x6b, 0x4d, + 0x64, 0x38, 0x37, 0x4d, 0x57, 0x79, 0x48, 0x42, 0x46, 0x63, 0x6d, 0x54, 0x6e, 0x34, 0x43, 0x4a, 0x62, 0x61, + 0x62, 0x34, 0x57, 0x61, 0x6b, 0x6f, 0x48, 0x73, 0x4a, 0x39, 0x61, 0x35, 0x41, 0x36, 0x76, 0x6a, 0x59, 0x33, + 0x33, 0x5c, 0x0a, + 0x09, 0x6f, 0x31, 0x31, 0x5a, 0x52, 0x37, 0x4a, 0x52, 0x32, 0x55, 0x6e, 0x49, 0x75, 0x6b, 0x49, 0x4e, 0x69, + 0x32, 0x66, 0x65, 0x72, 0x6a, 0x56, 0x4e, 0x6b, 0x34, 0x43, 0x70, 0x39, 0x32, 0x50, 0x59, 0x50, 0x33, 0x32, + 0x6d, 0x78, 0x38, 0x47, 0x50, 0x35, 0x59, 0x33, 0x57, 0x70, 0x6a, 0x4a, 0x32, 0x66, 0x51, 0x37, 0x32, 0x54, + 0x57, 0x73, 0x6a, 0x71, 0x52, 0x31, 0x59, 0x62, 0x33, 0x37, 0x69, 0x4f, 0x56, 0x50, 0x61, 0x31, 0x30, 0x71, + 0x67, 0x5c, 0x0a, + 0x09, 0x78, 0x44, 0x50, 0x5a, 0x36, 0x73, 0x6f, 0x2f, 0x4f, 0x4e, 0x52, 0x2b, 0x73, 0x4a, 0x35, 0x30, 0x54, + 0x41, 0x41, 0x41, 0x6f, 0x35, 0x73, 0x42, 0x2f, 0x49, 0x35, 0x47, 0x30, 0x4b, 0x62, 0x49, 0x36, 0x55, 0x78, + 0x7a, 0x6b, 0x4b, 0x57, 0x61, 0x31, 0x77, 0x35, 0x30, 0x70, 0x45, 0x30, 0x6a, 0x46, 0x74, 0x2b, 0x5a, 0x6f, + 0x4f, 0x65, 0x41, 0x54, 0x61, 0x6b, 0x65, 0x32, 0x48, 0x57, 0x64, 0x72, 0x59, 0x42, 0x39, 0x74, 0x2f, 0x69, + 0x52, 0x5c, 0x0a, + 0x09, 0x6e, 0x47, 0x75, 0x44, 0x6c, 0x30, 0x35, 0x4e, 0x72, 0x49, 0x37, 0x56, 0x76, 0x78, 0x32, 0x35, 0x37, + 0x4e, 0x7a, 0x49, 0x79, 0x6e, 0x44, 0x71, 0x75, 0x6d, 0x6c, 0x32, 0x6b, 0x59, 0x4b, 0x48, 0x4c, 0x65, 0x4e, + 0x61, 0x44, 0x6d, 0x46, 0x70, 0x7a, 0x53, 0x72, 0x6e, 0x7a, 0x47, 0x39, 0x4e, 0x6d, 0x5a, 0x6c, 0x32, 0x57, + 0x4e, 0x32, 0x58, 0x35, 0x42, 0x32, 0x6f, 0x6f, 0x59, 0x65, 0x45, 0x50, 0x76, 0x52, 0x47, 0x71, 0x32, 0x5a, + 0x41, 0x5c, 0x0a, + 0x09, 0x35, 0x4d, 0x43, 0x58, 0x51, 0x72, 0x5a, 0x6c, 0x6d, 0x31, 0x5a, 0x2f, 0x6e, 0x43, 0x39, 0x65, 0x7a, + 0x38, 0x45, 0x56, 0x44, 0x76, 0x68, 0x37, 0x6f, 0x35, 0x6c, 0x31, 0x6f, 0x57, 0x4d, 0x47, 0x41, 0x47, 0x36, + 0x76, 0x73, 0x34, 0x44, 0x66, 0x64, 0x6d, 0x71, 0x33, 0x6b, 0x35, 0x57, 0x4f, 0x6a, 0x34, 0x35, 0x34, 0x61, + 0x54, 0x61, 0x51, 0x70, 0x76, 0x6a, 0x4e, 0x76, 0x37, 0x6e, 0x48, 0x79, 0x33, 0x44, 0x6a, 0x64, 0x36, 0x71, + 0x38, 0x5c, 0x0a, + 0x09, 0x5a, 0x54, 0x77, 0x36, 0x4c, 0x65, 0x56, 0x4f, 0x56, 0x4a, 0x74, 0x2f, 0x32, 0x70, 0x36, 0x56, 0x54, + 0x4b, 0x5a, 0x67, 0x45, 0x39, 0x61, 0x33, 0x36, 0x33, 0x5a, 0x30, 0x6e, 0x38, 0x79, 0x77, 0x6b, 0x72, 0x71, + 0x36, 0x50, 0x57, 0x73, 0x73, 0x6d, 0x6d, 0x51, 0x32, 0x6b, 0x6c, 0x37, 0x54, 0x33, 0x47, 0x74, 0x51, 0x61, + 0x67, 0x4b, 0x50, 0x4d, 0x42, 0x70, 0x2b, 0x74, 0x63, 0x6d, 0x5a, 0x65, 0x42, 0x38, 0x79, 0x6f, 0x78, 0x69, + 0x74, 0x5c, 0x0a, + 0x09, 0x6a, 0x79, 0x43, 0x68, 0x4f, 0x76, 0x6e, 0x6d, 0x2f, 0x4e, 0x6b, 0x62, 0x74, 0x64, 0x49, 0x78, 0x38, + 0x58, 0x55, 0x44, 0x43, 0x61, 0x41, 0x36, 0x30, 0x76, 0x4f, 0x78, 0x38, 0x4a, 0x57, 0x56, 0x74, 0x43, 0x2b, + 0x52, 0x31, 0x58, 0x30, 0x59, 0x77, 0x46, 0x33, 0x59, 0x49, 0x44, 0x70, 0x6d, 0x41, 0x49, 0x44, 0x52, 0x45, + 0x4d, 0x42, 0x7a, 0x41, 0x64, 0x79, 0x34, 0x55, 0x6b, 0x47, 0x5a, 0x6f, 0x71, 0x62, 0x4f, 0x31, 0x42, 0x54, + 0x6c, 0x5c, 0x0a, + 0x09, 0x6d, 0x6f, 0x79, 0x61, 0x52, 0x79, 0x7a, 0x5a, 0x33, 0x74, 0x45, 0x35, 0x53, 0x37, 0x68, 0x75, 0x67, + 0x5a, 0x4e, 0x75, 0x54, 0x33, 0x4b, 0x71, 0x6f, 0x36, 0x6c, 0x63, 0x37, 0x5a, 0x66, 0x58, 0x74, 0x44, 0x6d, + 0x6e, 0x6a, 0x71, 0x30, 0x4e, 0x73, 0x6b, 0x35, 0x6c, 0x4a, 0x53, 0x65, 0x6c, 0x53, 0x2b, 0x56, 0x6e, 0x38, + 0x63, 0x6a, 0x35, 0x30, 0x55, 0x44, 0x44, 0x36, 0x2b, 0x71, 0x73, 0x62, 0x47, 0x56, 0x79, 0x4a, 0x71, 0x38, + 0x63, 0x5c, 0x0a, + 0x09, 0x79, 0x4a, 0x73, 0x79, 0x46, 0x6a, 0x34, 0x42, 0x63, 0x4f, 0x4a, 0x38, 0x7a, 0x62, 0x48, 0x64, 0x74, + 0x75, 0x64, 0x53, 0x32, 0x67, 0x44, 0x46, 0x64, 0x75, 0x78, 0x41, 0x6b, 0x50, 0x49, 0x58, 0x61, 0x6a, 0x57, + 0x56, 0x30, 0x32, 0x65, 0x6c, 0x76, 0x63, 0x58, 0x2b, 0x53, 0x77, 0x4c, 0x65, 0x42, 0x4e, 0x51, 0x42, 0x63, + 0x4c, 0x33, 0x70, 0x6d, 0x41, 0x49, 0x41, 0x4a, 0x6f, 0x53, 0x37, 0x48, 0x58, 0x41, 0x78, 0x67, 0x4b, 0x73, + 0x74, 0x5c, 0x0a, + 0x09, 0x42, 0x35, 0x63, 0x6f, 0x72, 0x4f, 0x38, 0x41, 0x2b, 0x4a, 0x4a, 0x53, 0x57, 0x55, 0x31, 0x6d, 0x7a, + 0x59, 0x2f, 0x54, 0x65, 0x39, 0x49, 0x61, 0x37, 0x62, 0x55, 0x6a, 0x38, 0x32, 0x6a, 0x4d, 0x4d, 0x35, 0x4f, + 0x6d, 0x74, 0x4e, 0x4b, 0x4b, 0x68, 0x6d, 0x6c, 0x61, 0x6e, 0x34, 0x37, 0x4a, 0x63, 0x6d, 0x34, 0x4c, 0x37, + 0x4e, 0x49, 0x73, 0x52, 0x34, 0x37, 0x55, 0x6e, 0x67, 0x44, 0x59, 0x6d, 0x55, 0x4b, 0x41, 0x49, 0x53, 0x66, + 0x71, 0x5c, 0x0a, + 0x09, 0x70, 0x57, 0x50, 0x55, 0x6a, 0x71, 0x6e, 0x35, 0x74, 0x63, 0x64, 0x58, 0x66, 0x32, 0x71, 0x51, 0x6c, + 0x58, 0x70, 0x4c, 0x64, 0x2b, 0x4f, 0x6c, 0x59, 0x4b, 0x71, 0x31, 0x4a, 0x72, 0x2f, 0x70, 0x6a, 0x46, 0x48, + 0x66, 0x53, 0x41, 0x57, 0x43, 0x76, 0x43, 0x31, 0x48, 0x72, 0x65, 0x58, 0x51, 0x42, 0x4b, 0x34, 0x31, 0x4c, + 0x35, 0x53, 0x4d, 0x52, 0x5a, 0x4d, 0x4f, 0x49, 0x67, 0x35, 0x34, 0x73, 0x77, 0x4f, 0x75, 0x73, 0x71, 0x31, + 0x7a, 0x5c, 0x0a, + 0x09, 0x66, 0x65, 0x69, 0x59, 0x41, 0x67, 0x42, 0x41, 0x67, 0x4d, 0x44, 0x4e, 0x44, 0x72, 0x67, 0x51, 0x63, + 0x47, 0x38, 0x44, 0x4d, 0x4d, 0x66, 0x4c, 0x6a, 0x42, 0x49, 0x59, 0x4e, 0x31, 0x69, 0x74, 0x4c, 0x47, 0x31, + 0x77, 0x32, 0x6d, 0x41, 0x73, 0x42, 0x65, 0x6f, 0x37, 0x44, 0x47, 0x6c, 0x76, 0x69, 0x44, 0x30, 0x32, 0x70, + 0x63, 0x6e, 0x61, 0x43, 0x47, 0x58, 0x4e, 0x39, 0x4e, 0x77, 0x6f, 0x67, 0x39, 0x4f, 0x52, 0x57, 0x50, 0x63, + 0x42, 0x5c, 0x0a, + 0x09, 0x39, 0x53, 0x6d, 0x6a, 0x70, 0x61, 0x71, 0x54, 0x43, 0x57, 0x4d, 0x55, 0x73, 0x75, 0x50, 0x72, 0x2b, + 0x52, 0x59, 0x76, 0x2b, 0x6c, 0x62, 0x65, 0x53, 0x6d, 0x4f, 0x71, 0x51, 0x53, 0x67, 0x46, 0x67, 0x39, 0x52, + 0x42, 0x65, 0x56, 0x30, 0x37, 0x47, 0x39, 0x4c, 0x6a, 0x35, 0x35, 0x39, 0x4e, 0x35, 0x51, 0x44, 0x75, 0x37, + 0x48, 0x57, 0x57, 0x74, 0x37, 0x49, 0x44, 0x36, 0x6c, 0x47, 0x6b, 0x41, 0x43, 0x64, 0x7a, 0x45, 0x6e, 0x6d, + 0x37, 0x5c, 0x0a, + 0x09, 0x32, 0x67, 0x42, 0x76, 0x52, 0x38, 0x41, 0x37, 0x55, 0x50, 0x32, 0x49, 0x37, 0x6b, 0x59, 0x73, 0x2f, + 0x67, 0x55, 0x36, 0x35, 0x67, 0x41, 0x41, 0x45, 0x43, 0x41, 0x77, 0x35, 0x2f, 0x79, 0x76, 0x6f, 0x68, 0x35, + 0x50, 0x66, 0x6c, 0x72, 0x77, 0x4a, 0x77, 0x43, 0x2b, 0x44, 0x61, 0x53, 0x47, 0x45, 0x38, 0x34, 0x46, 0x6b, + 0x74, 0x64, 0x47, 0x4a, 0x36, 0x56, 0x70, 0x6a, 0x75, 0x47, 0x50, 0x72, 0x61, 0x69, 0x72, 0x67, 0x55, 0x41, + 0x36, 0x5c, 0x0a, + 0x09, 0x6d, 0x34, 0x34, 0x73, 0x4e, 0x67, 0x69, 0x46, 0x38, 0x74, 0x71, 0x68, 0x69, 0x56, 0x32, 0x78, 0x30, + 0x74, 0x6f, 0x6d, 0x33, 0x76, 0x51, 0x66, 0x72, 0x79, 0x65, 0x6a, 0x62, 0x66, 0x50, 0x4f, 0x76, 0x78, 0x54, + 0x38, 0x30, 0x74, 0x32, 0x46, 0x65, 0x6e, 0x53, 0x57, 0x37, 0x44, 0x56, 0x66, 0x64, 0x64, 0x74, 0x4e, 0x4f, + 0x79, 0x5a, 0x72, 0x52, 0x39, 0x66, 0x5a, 0x42, 0x6c, 0x69, 0x39, 0x6c, 0x4f, 0x50, 0x52, 0x36, 0x58, 0x67, + 0x4b, 0x5c, 0x0a, + 0x09, 0x67, 0x69, 0x6b, 0x51, 0x41, 0x44, 0x59, 0x76, 0x74, 0x73, 0x78, 0x6c, 0x32, 0x37, 0x71, 0x63, 0x6c, + 0x48, 0x73, 0x4b, 0x47, 0x42, 0x55, 0x64, 0x64, 0x4d, 0x41, 0x66, 0x41, 0x58, 0x69, 0x55, 0x41, 0x33, 0x34, + 0x4a, 0x51, 0x44, 0x6d, 0x69, 0x6d, 0x33, 0x57, 0x68, 0x4e, 0x58, 0x73, 0x57, 0x59, 0x4c, 0x57, 0x49, 0x2f, + 0x78, 0x49, 0x71, 0x45, 0x2f, 0x67, 0x4f, 0x41, 0x68, 0x34, 0x33, 0x6e, 0x44, 0x76, 0x79, 0x63, 0x33, 0x44, + 0x6c, 0x5c, 0x0a, + 0x09, 0x73, 0x36, 0x6e, 0x62, 0x52, 0x39, 0x37, 0x74, 0x77, 0x57, 0x57, 0x5a, 0x4b, 0x4e, 0x66, 0x6b, 0x72, + 0x45, 0x44, 0x74, 0x45, 0x50, 0x37, 0x59, 0x6d, 0x66, 0x56, 0x30, 0x6c, 0x41, 0x72, 0x48, 0x69, 0x70, 0x63, + 0x59, 0x4c, 0x61, 0x32, 0x36, 0x73, 0x69, 0x2f, 0x37, 0x31, 0x70, 0x55, 0x33, 0x66, 0x76, 0x30, 0x54, 0x57, + 0x4f, 0x6c, 0x57, 0x59, 0x63, 0x76, 0x4a, 0x36, 0x76, 0x34, 0x34, 0x44, 0x38, 0x30, 0x6d, 0x48, 0x4b, 0x34, + 0x37, 0x5c, 0x0a, + 0x09, 0x4f, 0x46, 0x44, 0x56, 0x67, 0x4f, 0x62, 0x62, 0x48, 0x71, 0x4e, 0x64, 0x4c, 0x76, 0x33, 0x6b, 0x4d, + 0x56, 0x48, 0x79, 0x72, 0x33, 0x6e, 0x57, 0x37, 0x58, 0x49, 0x65, 0x56, 0x78, 0x70, 0x7a, 0x55, 0x2f, 0x76, + 0x68, 0x57, 0x39, 0x4f, 0x6d, 0x6e, 0x46, 0x46, 0x39, 0x57, 0x37, 0x70, 0x70, 0x47, 0x69, 0x75, 0x48, 0x4e, + 0x55, 0x74, 0x76, 0x31, 0x62, 0x6b, 0x35, 0x41, 0x46, 0x38, 0x45, 0x38, 0x43, 0x6b, 0x48, 0x66, 0x49, 0x71, + 0x41, 0x5c, 0x0a, + 0x09, 0x4b, 0x78, 0x79, 0x77, 0x48, 0x45, 0x70, 0x75, 0x5a, 0x4f, 0x51, 0x50, 0x64, 0x4d, 0x77, 0x44, 0x67, + 0x4b, 0x59, 0x41, 0x43, 0x4c, 0x50, 0x33, 0x33, 0x59, 0x32, 0x5a, 0x75, 0x32, 0x35, 0x37, 0x50, 0x59, 0x44, + 0x58, 0x68, 0x57, 0x75, 0x39, 0x73, 0x54, 0x47, 0x4d, 0x54, 0x55, 0x77, 0x69, 0x37, 0x2f, 0x61, 0x51, 0x64, + 0x2f, 0x76, 0x49, 0x75, 0x6c, 0x33, 0x6b, 0x6e, 0x51, 0x36, 0x51, 0x64, 0x5a, 0x48, 0x2f, 0x6e, 0x2f, 0x62, + 0x75, 0x5c, 0x0a, + 0x09, 0x33, 0x73, 0x65, 0x4e, 0x49, 0x67, 0x37, 0x6a, 0x2b, 0x48, 0x66, 0x73, 0x6e, 0x4f, 0x39, 0x38, 0x75, + 0x75, 0x53, 0x4d, 0x6c, 0x45, 0x52, 0x45, 0x53, 0x68, 0x6f, 0x4b, 0x6f, 0x45, 0x45, 0x52, 0x46, 0x4e, 0x42, + 0x52, 0x30, 0x46, 0x4d, 0x68, 0x55, 0x64, 0x4e, 0x52, 0x49, 0x53, 0x45, 0x71, 0x61, 0x76, 0x34, 0x41, 0x30, + 0x69, 0x48, 0x45, 0x50, 0x34, 0x41, 0x6f, 0x45, 0x4a, 0x52, 0x49, 0x55, 0x59, 0x51, 0x69, 0x51, 0x55, 0x53, + 0x56, 0x5c, 0x0a, + 0x09, 0x41, 0x71, 0x56, 0x42, 0x52, 0x4a, 0x45, 0x53, 0x68, 0x55, 0x4d, 0x6f, 0x51, 0x46, 0x37, 0x4f, 0x54, + 0x6f, 0x7a, 0x74, 0x33, 0x52, 0x2f, 0x46, 0x37, 0x4a, 0x35, 0x6e, 0x33, 0x32, 0x78, 0x66, 0x58, 0x70, 0x52, + 0x62, 0x7a, 0x2f, 0x4e, 0x70, 0x37, 0x72, 0x7a, 0x65, 0x6c, 0x31, 0x6e, 0x76, 0x7a, 0x4c, 0x4f, 0x7a, 0x34, + 0x37, 0x57, 0x39, 0x63, 0x51, 0x7a, 0x72, 0x46, 0x44, 0x2f, 0x35, 0x6c, 0x76, 0x38, 0x50, 0x70, 0x59, 0x5a, + 0x52, 0x5c, 0x0a, + 0x09, 0x6d, 0x46, 0x61, 0x65, 0x74, 0x33, 0x4b, 0x51, 0x61, 0x79, 0x70, 0x55, 0x33, 0x58, 0x72, 0x71, 0x7a, + 0x2b, 0x79, 0x4c, 0x7a, 0x6a, 0x5a, 0x4e, 0x35, 0x61, 0x78, 0x62, 0x76, 0x72, 0x6b, 0x42, 0x46, 0x43, 0x74, + 0x71, 0x57, 0x42, 0x5a, 0x6e, 0x76, 0x69, 0x39, 0x61, 0x33, 0x6c, 0x64, 0x58, 0x57, 0x63, 0x66, 0x63, 0x6f, + 0x70, 0x41, 0x4c, 0x79, 0x31, 0x33, 0x65, 0x69, 0x2b, 0x5a, 0x39, 0x4c, 0x41, 0x5a, 0x47, 0x58, 0x57, 0x67, + 0x76, 0x5c, 0x0a, + 0x09, 0x4f, 0x78, 0x75, 0x48, 0x32, 0x31, 0x2f, 0x55, 0x36, 0x4a, 0x76, 0x4b, 0x32, 0x37, 0x53, 0x74, 0x70, + 0x6c, 0x43, 0x63, 0x6c, 0x2f, 0x58, 0x67, 0x37, 0x65, 0x46, 0x39, 0x2f, 0x49, 0x31, 0x73, 0x31, 0x2f, 0x46, + 0x33, 0x39, 0x50, 0x31, 0x71, 0x2f, 0x74, 0x62, 0x65, 0x47, 0x35, 0x54, 0x4f, 0x38, 0x6b, 0x65, 0x6c, 0x34, + 0x65, 0x65, 0x65, 0x32, 0x59, 0x65, 0x42, 0x6e, 0x70, 0x58, 0x38, 0x38, 0x73, 0x44, 0x35, 0x4c, 0x30, 0x72, + 0x6f, 0x5c, 0x0a, + 0x09, 0x75, 0x50, 0x78, 0x37, 0x37, 0x63, 0x79, 0x59, 0x6a, 0x4d, 0x64, 0x4d, 0x78, 0x75, 0x50, 0x47, 0x5a, + 0x54, 0x76, 0x64, 0x4c, 0x72, 0x32, 0x74, 0x50, 0x68, 0x75, 0x39, 0x6e, 0x67, 0x2b, 0x4a, 0x54, 0x68, 0x65, + 0x36, 0x48, 0x54, 0x59, 0x32, 0x74, 0x33, 0x34, 0x2f, 0x74, 0x6a, 0x4f, 0x34, 0x41, 0x6e, 0x62, 0x61, 0x77, + 0x55, 0x6d, 0x44, 0x30, 0x38, 0x42, 0x70, 0x68, 0x2b, 0x74, 0x58, 0x42, 0x34, 0x65, 0x73, 0x55, 0x6d, 0x6c, + 0x7a, 0x5c, 0x0a, + 0x09, 0x38, 0x38, 0x70, 0x69, 0x6c, 0x55, 0x59, 0x55, 0x76, 0x69, 0x31, 0x58, 0x37, 0x6f, 0x36, 0x47, 0x5a, + 0x35, 0x43, 0x6d, 0x77, 0x61, 0x6a, 0x79, 0x76, 0x50, 0x57, 0x39, 0x6a, 0x4f, 0x4a, 0x38, 0x52, 0x74, 0x36, + 0x78, 0x72, 0x6a, 0x4a, 0x38, 0x34, 0x38, 0x2f, 0x4c, 0x57, 0x52, 0x77, 0x32, 0x7a, 0x51, 0x4b, 0x69, 0x73, + 0x5a, 0x7a, 0x56, 0x62, 0x54, 0x61, 0x46, 0x52, 0x2f, 0x48, 0x75, 0x7a, 0x65, 0x72, 0x79, 0x35, 0x53, 0x61, + 0x32, 0x5c, 0x0a, + 0x09, 0x72, 0x41, 0x48, 0x6d, 0x70, 0x51, 0x31, 0x44, 0x5a, 0x58, 0x46, 0x33, 0x6e, 0x4e, 0x4a, 0x38, 0x78, + 0x58, 0x31, 0x72, 0x4f, 0x74, 0x76, 0x50, 0x4a, 0x36, 0x5a, 0x59, 0x6b, 0x70, 0x44, 0x4f, 0x45, 0x69, 0x79, + 0x5a, 0x6b, 0x73, 0x36, 0x6d, 0x70, 0x4e, 0x4d, 0x4a, 0x53, 0x54, 0x49, 0x6a, 0x6e, 0x55, 0x34, 0x5a, 0x50, + 0x78, 0x7a, 0x65, 0x33, 0x6a, 0x35, 0x31, 0x35, 0x74, 0x7a, 0x32, 0x43, 0x79, 0x63, 0x62, 0x41, 0x2f, 0x31, + 0x35, 0x5c, 0x0a, + 0x09, 0x6a, 0x66, 0x43, 0x76, 0x6f, 0x6e, 0x55, 0x42, 0x55, 0x44, 0x49, 0x4b, 0x65, 0x7a, 0x44, 0x4f, 0x4f, + 0x52, 0x62, 0x31, 0x61, 0x4e, 0x49, 0x6b, 0x59, 0x54, 0x77, 0x61, 0x4d, 0x68, 0x35, 0x56, 0x6e, 0x76, 0x70, + 0x79, 0x63, 0x4f, 0x62, 0x73, 0x35, 0x7a, 0x75, 0x6e, 0x7a, 0x70, 0x51, 0x61, 0x74, 0x50, 0x57, 0x41, 0x58, + 0x57, 0x41, 0x41, 0x37, 0x4c, 0x72, 0x73, 0x4c, 0x39, 0x6a, 0x41, 0x5a, 0x64, 0x4d, 0x64, 0x62, 0x68, 0x64, + 0x73, 0x5c, 0x0a, + 0x09, 0x31, 0x32, 0x44, 0x67, 0x59, 0x47, 0x43, 0x77, 0x34, 0x32, 0x41, 0x4c, 0x32, 0x41, 0x45, 0x37, 0x37, + 0x71, 0x41, 0x50, 0x72, 0x6c, 0x39, 0x2f, 0x39, 0x69, 0x2f, 0x33, 0x43, 0x70, 0x6f, 0x61, 0x58, 0x66, 0x33, + 0x33, 0x46, 0x31, 0x44, 0x7a, 0x4f, 0x43, 0x74, 0x33, 0x46, 0x6a, 0x5a, 0x4e, 0x50, 0x36, 0x30, 0x64, 0x72, + 0x69, 0x73, 0x73, 0x67, 0x77, 0x58, 0x50, 0x7a, 0x78, 0x74, 0x4b, 0x65, 0x56, 0x76, 0x4c, 0x4c, 0x67, 0x76, + 0x43, 0x5c, 0x0a, + 0x09, 0x55, 0x71, 0x31, 0x32, 0x52, 0x6d, 0x34, 0x65, 0x62, 0x36, 0x6a, 0x66, 0x52, 0x76, 0x30, 0x50, 0x66, + 0x72, 0x6a, 0x53, 0x65, 0x6f, 0x4a, 0x74, 0x4a, 0x4d, 0x44, 0x51, 0x34, 0x44, 0x37, 0x59, 0x45, 0x4e, 0x77, + 0x6f, 0x6e, 0x55, 0x78, 0x4f, 0x70, 0x4e, 0x4e, 0x48, 0x72, 0x36, 0x52, 0x70, 0x69, 0x69, 0x56, 0x54, 0x62, + 0x4a, 0x61, 0x51, 0x70, 0x41, 0x6c, 0x70, 0x4f, 0x73, 0x4e, 0x6d, 0x43, 0x62, 0x50, 0x70, 0x68, 0x50, 0x38, + 0x65, 0x5c, 0x0a, + 0x09, 0x50, 0x53, 0x4b, 0x5a, 0x7a, 0x56, 0x68, 0x69, 0x50, 0x50, 0x33, 0x6a, 0x4a, 0x76, 0x2f, 0x65, 0x75, + 0x72, 0x46, 0x73, 0x76, 0x69, 0x4f, 0x70, 0x37, 0x51, 0x46, 0x77, 0x4b, 0x33, 0x79, 0x77, 0x79, 0x75, 0x56, + 0x4d, 0x54, 0x55, 0x69, 0x4d, 0x67, 0x61, 0x2f, 0x76, 0x2f, 0x58, 0x6d, 0x62, 0x75, 0x33, 0x76, 0x7a, 0x33, + 0x7a, 0x50, 0x4d, 0x4c, 0x6a, 0x55, 0x6d, 0x77, 0x42, 0x33, 0x67, 0x54, 0x72, 0x57, 0x62, 0x66, 0x62, 0x44, + 0x56, 0x5c, 0x0a, + 0x09, 0x53, 0x73, 0x4f, 0x6f, 0x6e, 0x6c, 0x6b, 0x4d, 0x68, 0x7a, 0x74, 0x68, 0x57, 0x4e, 0x38, 0x48, 0x41, + 0x67, 0x4f, 0x67, 0x62, 0x39, 0x69, 0x57, 0x38, 0x38, 0x47, 0x79, 0x62, 0x64, 0x44, 0x44, 0x68, 0x38, 0x55, + 0x6d, 0x50, 0x6e, 0x69, 0x32, 0x67, 0x61, 0x37, 0x42, 0x38, 0x53, 0x77, 0x59, 0x42, 0x74, 0x6c, 0x36, 0x6a, + 0x77, 0x4e, 0x64, 0x35, 0x73, 0x76, 0x30, 0x73, 0x75, 0x58, 0x7a, 0x37, 0x66, 0x65, 0x79, 0x35, 0x38, 0x67, + 0x61, 0x5c, 0x0a, + 0x09, 0x63, 0x4d, 0x39, 0x67, 0x32, 0x34, 0x48, 0x72, 0x4f, 0x74, 0x63, 0x46, 0x4e, 0x6d, 0x5a, 0x6d, 0x50, + 0x53, 0x75, 0x55, 0x4c, 0x6e, 0x74, 0x74, 0x43, 0x76, 0x32, 0x47, 0x34, 0x6d, 0x74, 0x5a, 0x50, 0x6f, 0x75, + 0x48, 0x44, 0x61, 0x7a, 0x75, 0x74, 0x51, 0x6b, 0x65, 0x54, 0x38, 0x45, 0x39, 0x44, 0x4f, 0x4d, 0x6d, 0x2b, + 0x33, 0x74, 0x76, 0x58, 0x67, 0x49, 0x53, 0x59, 0x44, 0x2f, 0x62, 0x34, 0x6e, 0x32, 0x48, 0x4d, 0x38, 0x4f, + 0x47, 0x5c, 0x0a, + 0x09, 0x2b, 0x48, 0x74, 0x43, 0x78, 0x73, 0x34, 0x66, 0x6f, 0x79, 0x6e, 0x2b, 0x6d, 0x74, 0x71, 0x41, 0x2b, + 0x39, 0x6b, 0x36, 0x48, 0x68, 0x68, 0x4d, 0x48, 0x65, 0x79, 0x62, 0x2f, 0x2b, 0x61, 0x63, 0x6b, 0x59, 0x4d, + 0x68, 0x75, 0x42, 0x48, 0x2b, 0x38, 0x58, 0x36, 0x32, 0x7a, 0x44, 0x67, 0x38, 0x4e, 0x71, 0x4f, 0x2f, 0x2f, + 0x2b, 0x4c, 0x65, 0x33, 0x73, 0x32, 0x50, 0x38, 0x52, 0x39, 0x41, 0x4f, 0x37, 0x52, 0x53, 0x48, 0x64, 0x70, + 0x4c, 0x5c, 0x0a, + 0x09, 0x30, 0x2b, 0x63, 0x2b, 0x6c, 0x76, 0x66, 0x59, 0x57, 0x68, 0x30, 0x41, 0x7a, 0x72, 0x6c, 0x66, 0x38, + 0x67, 0x4d, 0x52, 0x58, 0x67, 0x6f, 0x30, 0x7a, 0x49, 0x75, 0x5a, 0x31, 0x54, 0x31, 0x2f, 0x67, 0x5a, 0x6f, + 0x37, 0x73, 0x5a, 0x35, 0x6d, 0x74, 0x2b, 0x33, 0x63, 0x2b, 0x62, 0x63, 0x77, 0x37, 0x41, 0x47, 0x2b, 0x77, + 0x68, 0x61, 0x55, 0x4c, 0x79, 0x47, 0x61, 0x4c, 0x69, 0x33, 0x43, 0x2f, 0x38, 0x73, 0x39, 0x67, 0x55, 0x57, + 0x78, 0x5c, 0x0a, + 0x09, 0x46, 0x7a, 0x5a, 0x4f, 0x73, 0x2b, 0x71, 0x5a, 0x74, 0x74, 0x54, 0x6a, 0x77, 0x63, 0x47, 0x75, 0x48, + 0x59, 0x77, 0x4d, 0x65, 0x50, 0x58, 0x42, 0x56, 0x37, 0x75, 0x64, 0x45, 0x64, 0x6b, 0x67, 0x56, 0x32, 0x47, + 0x37, 0x77, 0x56, 0x5a, 0x57, 0x75, 0x52, 0x59, 0x76, 0x68, 0x30, 0x2f, 0x64, 0x76, 0x69, 0x35, 0x36, 0x66, + 0x61, 0x6a, 0x5a, 0x58, 0x6e, 0x67, 0x38, 0x73, 0x37, 0x70, 0x79, 0x74, 0x33, 0x35, 0x50, 0x4b, 0x4d, 0x78, + 0x58, 0x5c, 0x0a, + 0x09, 0x56, 0x35, 0x39, 0x4b, 0x30, 0x79, 0x34, 0x76, 0x57, 0x38, 0x39, 0x52, 0x31, 0x72, 0x70, 0x42, 0x77, + 0x46, 0x79, 0x6e, 0x30, 0x38, 0x6b, 0x50, 0x78, 0x47, 0x58, 0x67, 0x37, 0x57, 0x58, 0x7a, 0x4e, 0x78, 0x7a, + 0x4d, 0x48, 0x34, 0x42, 0x33, 0x67, 0x56, 0x6c, 0x62, 0x58, 0x34, 0x65, 0x6e, 0x36, 0x64, 0x7a, 0x35, 0x4e, + 0x78, 0x65, 0x47, 0x79, 0x53, 0x71, 0x4f, 0x32, 0x69, 0x42, 0x58, 0x6e, 0x53, 0x77, 0x41, 0x33, 0x67, 0x45, + 0x75, 0x5c, 0x0a, + 0x09, 0x72, 0x54, 0x70, 0x2f, 0x51, 0x2f, 0x31, 0x49, 0x67, 0x46, 0x65, 0x42, 0x36, 0x32, 0x32, 0x74, 0x50, + 0x36, 0x30, 0x4e, 0x41, 0x44, 0x67, 0x34, 0x6b, 0x47, 0x2f, 0x67, 0x50, 0x7a, 0x76, 0x51, 0x4f, 0x2b, 0x54, + 0x69, 0x58, 0x77, 0x45, 0x66, 0x34, 0x62, 0x76, 0x35, 0x4b, 0x31, 0x30, 0x2b, 0x79, 0x48, 0x72, 0x49, 0x36, + 0x73, 0x30, 0x4f, 0x38, 0x41, 0x38, 0x4c, 0x36, 0x6b, 0x31, 0x54, 0x77, 0x77, 0x2b, 0x6d, 0x58, 0x77, 0x41, + 0x2b, 0x5c, 0x0a, + 0x09, 0x67, 0x66, 0x62, 0x57, 0x6e, 0x79, 0x4e, 0x35, 0x49, 0x39, 0x41, 0x68, 0x58, 0x63, 0x58, 0x66, 0x4a, + 0x48, 0x54, 0x77, 0x54, 0x61, 0x72, 0x4f, 0x4c, 0x65, 0x79, 0x30, 0x2f, 0x6f, 0x7a, 0x2f, 0x68, 0x74, 0x55, + 0x50, 0x55, 0x65, 0x4f, 0x50, 0x32, 0x52, 0x44, 0x34, 0x42, 0x6e, 0x78, 0x39, 0x71, 0x61, 0x73, 0x7a, 0x54, + 0x66, 0x55, 0x69, 0x6d, 0x33, 0x34, 0x52, 0x2b, 0x48, 0x54, 0x52, 0x66, 0x47, 0x33, 0x51, 0x36, 0x68, 0x34, + 0x41, 0x5c, 0x0a, + 0x09, 0x46, 0x42, 0x72, 0x37, 0x69, 0x2f, 0x69, 0x37, 0x71, 0x39, 0x34, 0x44, 0x58, 0x67, 0x35, 0x6d, 0x47, + 0x54, 0x6e, 0x6e, 0x72, 0x70, 0x6e, 0x6f, 0x56, 0x57, 0x38, 0x39, 0x41, 0x41, 0x41, 0x42, 0x58, 0x6b, 0x6c, + 0x45, 0x51, 0x56, 0x54, 0x5a, 0x4a, 0x65, 0x42, 0x62, 0x66, 0x47, 0x41, 0x41, 0x37, 0x54, 0x35, 0x77, 0x38, + 0x6d, 0x53, 0x79, 0x65, 0x6e, 0x50, 0x57, 0x4f, 0x58, 0x66, 0x56, 0x7a, 0x45, 0x36, 0x56, 0x70, 0x69, 0x2b, + 0x72, 0x5c, 0x0a, + 0x09, 0x47, 0x31, 0x2f, 0x67, 0x37, 0x31, 0x42, 0x74, 0x2f, 0x51, 0x6d, 0x6b, 0x39, 0x51, 0x45, 0x41, 0x74, + 0x57, 0x66, 0x38, 0x54, 0x66, 0x78, 0x6f, 0x4f, 0x2f, 0x69, 0x65, 0x51, 0x66, 0x47, 0x74, 0x33, 0x54, 0x58, + 0x59, 0x5a, 0x33, 0x6b, 0x79, 0x65, 0x5a, 0x31, 0x78, 0x7a, 0x72, 0x31, 0x6d, 0x5a, 0x74, 0x38, 0x44, 0x4c, + 0x79, 0x32, 0x62, 0x33, 0x38, 0x77, 0x75, 0x41, 0x70, 0x38, 0x42, 0x50, 0x2b, 0x58, 0x54, 0x32, 0x31, 0x36, + 0x58, 0x5c, 0x0a, + 0x09, 0x31, 0x69, 0x49, 0x41, 0x51, 0x6b, 0x33, 0x64, 0x2f, 0x33, 0x58, 0x62, 0x54, 0x33, 0x6c, 0x79, 0x77, + 0x55, 0x42, 0x79, 0x48, 0x2f, 0x6a, 0x41, 0x4f, 0x66, 0x63, 0x2b, 0x38, 0x4c, 0x71, 0x5a, 0x2f, 0x33, 0x5a, + 0x71, 0x59, 0x41, 0x2b, 0x34, 0x42, 0x76, 0x77, 0x49, 0x66, 0x41, 0x66, 0x38, 0x6c, 0x69, 0x2b, 0x37, 0x4c, + 0x76, 0x56, 0x70, 0x37, 0x51, 0x4a, 0x41, 0x35, 0x44, 0x43, 0x57, 0x6a, 0x42, 0x64, 0x56, 0x72, 0x46, 0x74, + 0x37, 0x5c, 0x0a, + 0x09, 0x55, 0x51, 0x43, 0x49, 0x52, 0x47, 0x77, 0x64, 0x33, 0x67, 0x55, 0x51, 0x6b, 0x63, 0x65, 0x6b, 0x41, + 0x42, 0x43, 0x4a, 0x6d, 0x41, 0x4a, 0x41, 0x4a, 0x47, 0x49, 0x4b, 0x41, 0x4a, 0x47, 0x49, 0x4b, 0x51, 0x42, + 0x45, 0x49, 0x71, 0x59, 0x41, 0x45, 0x49, 0x6d, 0x59, 0x41, 0x6b, 0x41, 0x6b, 0x59, 0x67, 0x6f, 0x41, 0x6b, + 0x59, 0x67, 0x70, 0x41, 0x45, 0x51, 0x69, 0x70, 0x67, 0x41, 0x51, 0x69, 0x5a, 0x67, 0x43, 0x51, 0x43, 0x52, + 0x69, 0x5c, 0x0a, + 0x09, 0x43, 0x67, 0x43, 0x52, 0x69, 0x43, 0x6b, 0x41, 0x52, 0x43, 0x4b, 0x6d, 0x41, 0x42, 0x43, 0x4a, 0x6d, + 0x41, 0x4a, 0x41, 0x4a, 0x47, 0x49, 0x4b, 0x41, 0x4a, 0x47, 0x49, 0x4b, 0x51, 0x42, 0x45, 0x49, 0x71, 0x59, + 0x41, 0x45, 0x49, 0x6d, 0x59, 0x41, 0x6b, 0x41, 0x6b, 0x59, 0x67, 0x6f, 0x41, 0x6b, 0x59, 0x67, 0x70, 0x41, + 0x45, 0x51, 0x69, 0x70, 0x67, 0x41, 0x51, 0x69, 0x5a, 0x67, 0x43, 0x51, 0x43, 0x52, 0x69, 0x43, 0x67, 0x43, + 0x52, 0x5c, 0x0a, + 0x09, 0x69, 0x43, 0x6b, 0x41, 0x52, 0x43, 0x4b, 0x6d, 0x41, 0x42, 0x43, 0x4a, 0x6d, 0x41, 0x4a, 0x41, 0x4a, + 0x47, 0x49, 0x4b, 0x41, 0x4a, 0x47, 0x49, 0x4b, 0x51, 0x42, 0x45, 0x49, 0x71, 0x59, 0x41, 0x45, 0x49, 0x6d, + 0x59, 0x41, 0x6b, 0x41, 0x6b, 0x59, 0x67, 0x6f, 0x41, 0x6b, 0x59, 0x67, 0x70, 0x41, 0x45, 0x51, 0x69, 0x70, + 0x67, 0x41, 0x51, 0x69, 0x5a, 0x67, 0x43, 0x51, 0x43, 0x52, 0x69, 0x43, 0x67, 0x43, 0x52, 0x69, 0x43, 0x6b, + 0x41, 0x5c, 0x0a, + 0x09, 0x52, 0x43, 0x4b, 0x6d, 0x41, 0x42, 0x43, 0x4a, 0x6d, 0x41, 0x4a, 0x41, 0x4a, 0x47, 0x49, 0x4b, 0x41, + 0x4a, 0x47, 0x49, 0x4b, 0x51, 0x42, 0x45, 0x49, 0x71, 0x59, 0x41, 0x45, 0x49, 0x6d, 0x59, 0x41, 0x6b, 0x41, + 0x6b, 0x59, 0x67, 0x6f, 0x41, 0x6b, 0x59, 0x67, 0x70, 0x41, 0x45, 0x51, 0x69, 0x70, 0x67, 0x41, 0x51, 0x69, + 0x5a, 0x67, 0x43, 0x51, 0x43, 0x52, 0x69, 0x43, 0x67, 0x43, 0x52, 0x69, 0x50, 0x30, 0x50, 0x38, 0x66, 0x52, + 0x4d, 0x5c, 0x0a, + 0x09, 0x43, 0x50, 0x61, 0x46, 0x72, 0x73, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x53, 0x55, 0x56, 0x4f, 0x52, + 0x4b, 0x35, 0x43, 0x59, 0x49, 0x49, 0x3d, 0x5c, 0x0a, + 0x09, 0x22, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x0a, + 0x09, 0x22, 0x69, 0x56, 0x42, 0x4f, 0x52, 0x77, 0x30, 0x4b, 0x47, 0x67, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x4e, + 0x53, 0x55, 0x68, 0x45, 0x55, 0x67, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x43, 0x41, + 0x59, 0x41, 0x41, 0x41, 0x44, 0x53, 0x31, 0x6e, 0x39, 0x2f, 0x41, 0x41, 0x41, 0x48, 0x6c, 0x45, 0x6c, 0x45, + 0x51, 0x56, 0x52, 0x34, 0x6e, 0x4f, 0x32, 0x62, 0x65, 0x34, 0x78, 0x64, 0x56, 0x52, 0x58, 0x47, 0x66, 0x7a, + 0x4f, 0x64, 0x5c, 0x0a, + 0x09, 0x61, 0x57, 0x6c, 0x4c, 0x69, 0x7a, 0x43, 0x30, 0x59, 0x68, 0x38, 0x38, 0x4f, 0x79, 0x6b, 0x57, 0x78, + 0x51, 0x6f, 0x74, 0x64, 0x41, 0x6f, 0x71, 0x31, 0x42, 0x52, 0x45, 0x53, 0x56, 0x56, 0x53, 0x59, 0x77, 0x31, + 0x70, 0x51, 0x67, 0x69, 0x52, 0x67, 0x42, 0x41, 0x44, 0x78, 0x6f, 0x51, 0x59, 0x69, 0x64, 0x68, 0x45, 0x78, + 0x47, 0x42, 0x4a, 0x4e, 0x43, 0x67, 0x59, 0x45, 0x74, 0x4e, 0x71, 0x55, 0x6a, 0x48, 0x57, 0x38, 0x45, 0x61, + 0x6b, 0x5c, 0x0a, + 0x09, 0x74, 0x63, 0x58, 0x36, 0x41, 0x4d, 0x61, 0x71, 0x69, 0x50, 0x61, 0x68, 0x56, 0x69, 0x69, 0x56, 0x55, + 0x74, 0x73, 0x69, 0x46, 0x4b, 0x61, 0x4d, 0x4c, 0x5a, 0x33, 0x32, 0x38, 0x34, 0x2b, 0x31, 0x54, 0x75, 0x36, + 0x2b, 0x5a, 0x38, 0x34, 0x35, 0x64, 0x31, 0x36, 0x33, 0x63, 0x34, 0x65, 0x7a, 0x76, 0x2b, 0x52, 0x6b, 0x33, + 0x37, 0x50, 0x58, 0x32, 0x6e, 0x75, 0x74, 0x73, 0x2f, 0x64, 0x33, 0x39, 0x6c, 0x6e, 0x37, 0x63, 0x5a, 0x73, + 0x6b, 0x5c, 0x0a, + 0x09, 0x45, 0x56, 0x46, 0x65, 0x4e, 0x41, 0x2b, 0x33, 0x41, 0x78, 0x48, 0x44, 0x69, 0x30, 0x69, 0x41, 0x6b, + 0x69, 0x4d, 0x53, 0x6f, 0x4c, 0x48, 0x52, 0x42, 0x49, 0x77, 0x48, 0x52, 0x74, 0x58, 0x4c, 0x51, 0x43, 0x52, + 0x41, 0x59, 0x2b, 0x4d, 0x6d, 0x59, 0x44, 0x2f, 0x77, 0x6c, 0x58, 0x6f, 0x5a, 0x69, 0x41, 0x52, 0x6f, 0x62, + 0x45, 0x7a, 0x77, 0x39, 0x48, 0x33, 0x31, 0x4d, 0x68, 0x41, 0x4a, 0x30, 0x4e, 0x68, 0x34, 0x77, 0x39, 0x4d, + 0x70, 0x5c, 0x0a, + 0x09, 0x39, 0x54, 0x49, 0x51, 0x43, 0x64, 0x44, 0x59, 0x36, 0x50, 0x4c, 0x30, 0x68, 0x48, 0x6f, 0x5a, 0x69, + 0x41, 0x52, 0x6f, 0x62, 0x4f, 0x7a, 0x32, 0x39, 0x4d, 0x52, 0x36, 0x47, 0x57, 0x69, 0x70, 0x56, 0x38, 0x55, + 0x52, 0x6d, 0x5a, 0x67, 0x4c, 0x66, 0x42, 0x69, 0x59, 0x42, 0x4c, 0x77, 0x43, 0x50, 0x41, 0x6c, 0x73, 0x4c, + 0x64, 0x42, 0x2f, 0x31, 0x64, 0x4e, 0x49, 0x67, 0x44, 0x71, 0x69, 0x44, 0x66, 0x67, 0x44, 0x38, 0x47, 0x2f, + 0x67, 0x5c, 0x0a, + 0x09, 0x49, 0x30, 0x48, 0x2b, 0x61, 0x47, 0x41, 0x42, 0x63, 0x43, 0x72, 0x77, 0x4f, 0x76, 0x42, 0x62, 0x59, + 0x47, 0x65, 0x71, 0x37, 0x48, 0x51, 0x76, 0x76, 0x78, 0x33, 0x59, 0x56, 0x32, 0x42, 0x6a, 0x4e, 0x76, 0x41, + 0x44, 0x34, 0x4c, 0x77, 0x4d, 0x32, 0x55, 0x72, 0x67, 0x65, 0x71, 0x41, 0x37, 0x51, 0x37, 0x62, 0x48, 0x30, + 0x32, 0x5a, 0x73, 0x4b, 0x6e, 0x69, 0x34, 0x77, 0x4d, 0x61, 0x41, 0x30, 0x44, 0x51, 0x43, 0x6c, 0x34, 0x4a, + 0x48, 0x5c, 0x0a, + 0x09, 0x41, 0x65, 0x33, 0x41, 0x54, 0x4f, 0x41, 0x30, 0x34, 0x46, 0x6e, 0x67, 0x36, 0x5a, 0x52, 0x4f, 0x45, + 0x39, 0x62, 0x59, 0x35, 0x77, 0x4e, 0x54, 0x4d, 0x61, 0x4c, 0x76, 0x77, 0x54, 0x72, 0x77, 0x6c, 0x38, 0x44, + 0x65, 0x51, 0x48, 0x63, 0x36, 0x73, 0x4d, 0x4e, 0x2f, 0x7a, 0x77, 0x55, 0x32, 0x41, 0x6e, 0x4f, 0x41, 0x31, + 0x63, 0x41, 0x70, 0x67, 0x64, 0x35, 0x68, 0x34, 0x44, 0x37, 0x67, 0x69, 0x38, 0x41, 0x30, 0x34, 0x4d, 0x66, + 0x41, 0x5c, 0x0a, + 0x09, 0x66, 0x4a, 0x63, 0x4a, 0x65, 0x41, 0x43, 0x34, 0x41, 0x64, 0x69, 0x56, 0x38, 0x6d, 0x55, 0x68, 0x38, + 0x42, 0x41, 0x77, 0x31, 0x75, 0x2b, 0x66, 0x42, 0x76, 0x34, 0x4a, 0x76, 0x4e, 0x66, 0x74, 0x41, 0x54, 0x77, + 0x49, 0x66, 0x44, 0x72, 0x6a, 0x57, 0x63, 0x64, 0x53, 0x49, 0x63, 0x59, 0x34, 0x34, 0x48, 0x38, 0x5a, 0x4f, + 0x6f, 0x4f, 0x44, 0x70, 0x4a, 0x46, 0x77, 0x48, 0x53, 0x50, 0x70, 0x4b, 0x6b, 0x6d, 0x50, 0x53, 0x75, 0x70, + 0x53, 0x5c, 0x0a, + 0x09, 0x4e, 0x66, 0x36, 0x65, 0x30, 0x72, 0x31, 0x51, 0x30, 0x69, 0x62, 0x6c, 0x34, 0x77, 0x6c, 0x4a, 0x73, + 0x31, 0x4a, 0x6c, 0x4e, 0x72, 0x70, 0x73, 0x75, 0x61, 0x54, 0x4a, 0x6b, 0x76, 0x62, 0x34, 0x66, 0x59, 0x2b, + 0x6b, 0x54, 0x6b, 0x6e, 0x50, 0x42, 0x65, 0x55, 0x66, 0x6c, 0x76, 0x53, 0x76, 0x34, 0x50, 0x35, 0x41, 0x38, + 0x48, 0x75, 0x62, 0x70, 0x4c, 0x61, 0x67, 0x33, 0x71, 0x6d, 0x53, 0x58, 0x67, 0x39, 0x6b, 0x48, 0x53, 0x6d, + 0x37, 0x5c, 0x0a, + 0x09, 0x69, 0x34, 0x4f, 0x79, 0x63, 0x33, 0x4b, 0x65, 0x2f, 0x51, 0x32, 0x58, 0x74, 0x2b, 0x58, 0x49, 0x42, + 0x33, 0x55, 0x4e, 0x64, 0x38, 0x66, 0x32, 0x35, 0x66, 0x71, 0x4d, 0x70, 0x46, 0x32, 0x71, 0x78, 0x6d, 0x46, + 0x4a, 0x4f, 0x34, 0x4c, 0x37, 0x34, 0x31, 0x54, 0x70, 0x2f, 0x4c, 0x63, 0x39, 0x37, 0x36, 0x43, 0x6b, 0x64, + 0x5a, 0x4a, 0x57, 0x2b, 0x50, 0x57, 0x77, 0x4b, 0x68, 0x31, 0x35, 0x57, 0x4e, 0x4c, 0x70, 0x67, 0x59, 0x30, + 0x76, 0x5c, 0x0a, + 0x09, 0x65, 0x66, 0x34, 0x32, 0x53, 0x58, 0x66, 0x36, 0x37, 0x78, 0x32, 0x53, 0x5a, 0x67, 0x59, 0x36, 0x69, + 0x79, 0x51, 0x64, 0x43, 0x6d, 0x79, 0x2b, 0x4b, 0x6d, 0x6d, 0x32, 0x70, 0x47, 0x5a, 0x4a, 0x6c, 0x30, 0x6e, + 0x61, 0x36, 0x2f, 0x6b, 0x2f, 0x44, 0x4d, 0x72, 0x63, 0x35, 0x58, 0x6e, 0x2f, 0x6b, 0x54, 0x51, 0x74, 0x35, + 0x2f, 0x6b, 0x53, 0x38, 0x6e, 0x30, 0x2b, 0x52, 0x37, 0x37, 0x56, 0x35, 0x61, 0x66, 0x6e, 0x79, 0x42, 0x75, + 0x57, 0x5c, 0x0a, + 0x09, 0x41, 0x47, 0x4d, 0x6b, 0x6a, 0x52, 0x70, 0x6b, 0x48, 0x54, 0x63, 0x46, 0x44, 0x66, 0x36, 0x79, 0x70, + 0x47, 0x39, 0x49, 0x75, 0x6c, 0x6a, 0x53, 0x73, 0x5a, 0x4a, 0x61, 0x4a, 0x58, 0x57, 0x37, 0x62, 0x47, 0x47, + 0x71, 0x4d, 0x54, 0x73, 0x6c, 0x54, 0x63, 0x2b, 0x6f, 0x37, 0x36, 0x4b, 0x67, 0x76, 0x6c, 0x75, 0x43, 0x2f, + 0x4a, 0x6c, 0x42, 0x66, 0x6a, 0x4c, 0x43, 0x4c, 0x4d, 0x34, 0x6f, 0x66, 0x32, 0x2b, 0x67, 0x39, 0x2b, 0x57, + 0x55, 0x5c, 0x0a, + 0x09, 0x37, 0x42, 0x4c, 0x50, 0x50, 0x79, 0x4b, 0x70, 0x33, 0x66, 0x4e, 0x32, 0x65, 0x74, 0x34, 0x39, 0x37, + 0x6e, 0x4f, 0x36, 0x76, 0x6b, 0x6b, 0x79, 0x49, 0x6b, 0x6e, 0x53, 0x30, 0x70, 0x77, 0x32, 0x65, 0x4d, 0x72, + 0x6c, 0x38, 0x77, 0x62, 0x5a, 0x6c, 0x76, 0x30, 0x69, 0x77, 0x48, 0x73, 0x6b, 0x76, 0x53, 0x52, 0x37, 0x4d, + 0x79, 0x5a, 0x4c, 0x57, 0x69, 0x5a, 0x70, 0x72, 0x61, 0x52, 0x6e, 0x4a, 0x50, 0x31, 0x4d, 0x4e, 0x68, 0x79, + 0x33, 0x5c, 0x0a, + 0x09, 0x46, 0x6c, 0x51, 0x38, 0x56, 0x64, 0x4a, 0x62, 0x37, 0x76, 0x68, 0x4c, 0x6b, 0x6c, 0x5a, 0x4a, 0x2b, + 0x70, 0x54, 0x73, 0x62, 0x65, 0x6d, 0x72, 0x63, 0x7a, 0x4e, 0x6c, 0x51, 0x37, 0x41, 0x6b, 0x66, 0x56, 0x66, + 0x53, 0x32, 0x41, 0x79, 0x64, 0x70, 0x4d, 0x4e, 0x76, 0x63, 0x7a, 0x38, 0x54, 0x76, 0x44, 0x2b, 0x6e, 0x7a, + 0x75, 0x38, 0x45, 0x4f, 0x6e, 0x39, 0x4a, 0x79, 0x56, 0x34, 0x49, 0x5a, 0x41, 0x64, 0x79, 0x37, 0x48, 0x30, + 0x6f, 0x5c, 0x0a, + 0x09, 0x30, 0x45, 0x6c, 0x2f, 0x52, 0x73, 0x4c, 0x4f, 0x75, 0x6c, 0x33, 0x53, 0x52, 0x46, 0x57, 0x6a, 0x52, + 0x39, 0x4c, 0x7a, 0x33, 0x6e, 0x34, 0x72, 0x4a, 0x4b, 0x32, 0x57, 0x39, 0x4a, 0x72, 0x4c, 0x33, 0x6e, 0x54, + 0x2f, 0x73, 0x33, 0x7a, 0x2b, 0x75, 0x6d, 0x7a, 0x45, 0x2b, 0x6d, 0x41, 0x2f, 0x32, 0x6d, 0x37, 0x51, 0x42, + 0x47, 0x68, 0x33, 0x78, 0x37, 0x5a, 0x4c, 0x32, 0x71, 0x31, 0x73, 0x2f, 0x45, 0x33, 0x53, 0x47, 0x54, 0x6e, + 0x6c, 0x5c, 0x0a, + 0x09, 0x46, 0x2b, 0x65, 0x55, 0x32, 0x53, 0x4c, 0x70, 0x67, 0x6a, 0x34, 0x36, 0x64, 0x36, 0x75, 0x58, 0x65, + 0x55, 0x35, 0x53, 0x55, 0x34, 0x37, 0x4f, 0x61, 0x74, 0x64, 0x35, 0x53, 0x74, 0x4a, 0x70, 0x67, 0x5a, 0x33, + 0x6a, 0x4d, 0x33, 0x54, 0x48, 0x71, 0x50, 0x4b, 0x32, 0x4a, 0x5a, 0x67, 0x66, 0x79, 0x4f, 0x38, 0x4f, 0x38, + 0x6a, 0x66, 0x6e, 0x32, 0x47, 0x73, 0x50, 0x64, 0x4d, 0x37, 0x4b, 0x6b, 0x46, 0x38, 0x58, 0x2b, 0x48, 0x78, + 0x69, 0x5c, 0x0a, + 0x09, 0x6f, 0x4e, 0x75, 0x74, 0x66, 0x4c, 0x77, 0x73, 0x47, 0x39, 0x57, 0x4b, 0x32, 0x71, 0x4b, 0x6c, 0x68, + 0x6e, 0x7a, 0x41, 0x56, 0x39, 0x34, 0x30, 0x4d, 0x46, 0x6d, 0x43, 0x54, 0x4b, 0x4c, 0x67, 0x62, 0x6d, 0x77, + 0x61, 0x38, 0x31, 0x66, 0x67, 0x5a, 0x4f, 0x42, 0x61, 0x34, 0x43, 0x78, 0x67, 0x50, 0x58, 0x41, 0x4f, 0x6c, + 0x66, 0x6b, 0x71, 0x77, 0x43, 0x4c, 0x67, 0x70, 0x38, 0x48, 0x39, 0x49, 0x31, 0x68, 0x6b, 0x76, 0x42, 0x51, + 0x34, 0x5c, 0x0a, + 0x09, 0x45, 0x39, 0x67, 0x41, 0x58, 0x41, 0x6e, 0x63, 0x58, 0x79, 0x4d, 0x2b, 0x62, 0x66, 0x4e, 0x30, 0x4d, + 0x78, 0x5a, 0x6c, 0x5a, 0x32, 0x47, 0x2f, 0x70, 0x78, 0x33, 0x59, 0x71, 0x6c, 0x6b, 0x50, 0x46, 0x76, 0x48, + 0x50, 0x41, 0x64, 0x61, 0x6b, 0x64, 0x4b, 0x2f, 0x78, 0x4f, 0x74, 0x2f, 0x79, 0x35, 0x35, 0x67, 0x48, 0x33, + 0x4f, 0x4c, 0x2b, 0x41, 0x6a, 0x77, 0x47, 0x66, 0x4d, 0x46, 0x2f, 0x37, 0x79, 0x45, 0x62, 0x34, 0x34, 0x50, + 0x66, 0x5c, 0x0a, + 0x09, 0x6b, 0x7a, 0x4c, 0x6b, 0x47, 0x7a, 0x77, 0x39, 0x47, 0x7a, 0x6a, 0x6f, 0x74, 0x73, 0x59, 0x44, 0x56, + 0x32, 0x41, 0x7a, 0x6a, 0x54, 0x4f, 0x42, 0x6b, 0x37, 0x41, 0x70, 0x35, 0x6b, 0x48, 0x67, 0x65, 0x61, 0x41, + 0x54, 0x4f, 0x4a, 0x52, 0x6a, 0x4c, 0x30, 0x46, 0x50, 0x44, 0x66, 0x6e, 0x41, 0x6b, 0x63, 0x4f, 0x4d, 0x59, + 0x77, 0x4f, 0x47, 0x48, 0x70, 0x44, 0x30, 0x67, 0x5a, 0x52, 0x38, 0x73, 0x69, 0x7a, 0x36, 0x6c, 0x71, 0x54, + 0x37, 0x5c, 0x0a, + 0x09, 0x55, 0x2b, 0x57, 0x53, 0x59, 0x4f, 0x68, 0x5a, 0x53, 0x54, 0x4d, 0x43, 0x32, 0x53, 0x6d, 0x71, 0x44, + 0x4e, 0x6e, 0x64, 0x71, 0x68, 0x33, 0x55, 0x58, 0x4f, 0x2b, 0x36, 0x75, 0x79, 0x56, 0x4e, 0x79, 0x4e, 0x46, + 0x5a, 0x45, 0x2f, 0x69, 0x35, 0x55, 0x4e, 0x4c, 0x6a, 0x67, 0x65, 0x33, 0x52, 0x67, 0x64, 0x34, 0x73, 0x56, + 0x61, 0x4c, 0x70, 0x4f, 0x31, 0x77, 0x33, 0x77, 0x52, 0x57, 0x75, 0x63, 0x34, 0x79, 0x6b, 0x2f, 0x5a, 0x36, + 0x33, 0x5c, 0x0a, + 0x09, 0x4d, 0x63, 0x66, 0x65, 0x37, 0x4b, 0x44, 0x63, 0x68, 0x52, 0x6e, 0x79, 0x46, 0x74, 0x6c, 0x77, 0x4c, + 0x55, 0x6e, 0x6e, 0x53, 0x76, 0x71, 0x35, 0x2f, 0x31, 0x35, 0x54, 0x34, 0x31, 0x6d, 0x48, 0x37, 0x63, 0x6f, + 0x54, 0x6a, 0x41, 0x34, 0x65, 0x39, 0x4a, 0x34, 0x63, 0x6e, 0x66, 0x6b, 0x75, 0x44, 0x34, 0x4f, 0x65, 0x70, + 0x5a, 0x36, 0x33, 0x56, 0x39, 0x6e, 0x44, 0x63, 0x4a, 0x73, 0x71, 0x45, 0x66, 0x32, 0x33, 0x61, 0x6a, 0x6a, + 0x58, 0x5c, 0x0a, + 0x09, 0x4a, 0x6d, 0x6d, 0x66, 0x36, 0x7a, 0x36, 0x6d, 0x33, 0x74, 0x2f, 0x6b, 0x4e, 0x6c, 0x56, 0x50, 0x77, + 0x57, 0x36, 0x58, 0x64, 0x46, 0x37, 0x51, 0x41, 0x62, 0x2b, 0x54, 0x39, 0x41, 0x6c, 0x4a, 0x4e, 0x30, 0x72, + 0x36, 0x72, 0x2b, 0x64, 0x74, 0x56, 0x34, 0x56, 0x4d, 0x53, 0x65, 0x64, 0x30, 0x71, 0x52, 0x4a, 0x67, 0x72, + 0x66, 0x53, 0x38, 0x58, 0x54, 0x6b, 0x2b, 0x6e, 0x52, 0x48, 0x59, 0x4f, 0x7a, 0x56, 0x48, 0x4a, 0x2f, 0x6c, + 0x6b, 0x5c, 0x0a, + 0x09, 0x4c, 0x70, 0x4b, 0x30, 0x49, 0x4e, 0x44, 0x2f, 0x61, 0x6f, 0x33, 0x6e, 0x6e, 0x61, 0x6a, 0x73, 0x4f, + 0x4b, 0x42, 0x46, 0x30, 0x6a, 0x63, 0x6c, 0x58, 0x56, 0x6d, 0x6a, 0x2f, 0x4a, 0x41, 0x53, 0x6f, 0x44, 0x6c, + 0x77, 0x2f, 0x4f, 0x4d, 0x46, 0x46, 0x57, 0x78, 0x77, 0x6e, 0x54, 0x76, 0x39, 0x50, 0x76, 0x6d, 0x4f, 0x66, + 0x72, 0x2b, 0x67, 0x7a, 0x4e, 0x64, 0x63, 0x5a, 0x32, 0x30, 0x66, 0x48, 0x50, 0x78, 0x63, 0x34, 0x4d, 0x63, + 0x6d, 0x5c, 0x0a, + 0x09, 0x53, 0x5a, 0x2b, 0x56, 0x64, 0x65, 0x44, 0x4a, 0x73, 0x76, 0x6c, 0x38, 0x69, 0x48, 0x56, 0x65, 0x35, + 0x6a, 0x70, 0x56, 0x53, 0x42, 0x44, 0x69, 0x46, 0x56, 0x56, 0x2f, 0x74, 0x39, 0x74, 0x55, 0x47, 0x63, 0x57, + 0x36, 0x5a, 0x42, 0x48, 0x35, 0x52, 0x2f, 0x33, 0x2b, 0x7a, 0x59, 0x4a, 0x32, 0x57, 0x53, 0x58, 0x70, 0x4a, + 0x38, 0x71, 0x50, 0x53, 0x2f, 0x37, 0x73, 0x64, 0x58, 0x7a, 0x53, 0x37, 0x33, 0x38, 0x55, 0x2b, 0x4c, 0x42, + 0x4b, 0x5c, 0x0a, + 0x09, 0x6c, 0x5a, 0x63, 0x6c, 0x4a, 0x4e, 0x55, 0x79, 0x74, 0x39, 0x6d, 0x74, 0x33, 0x6e, 0x48, 0x56, 0x58, + 0x43, 0x39, 0x37, 0x71, 0x4d, 0x44, 0x6d, 0x6b, 0x42, 0x4f, 0x41, 0x77, 0x4f, 0x6e, 0x5a, 0x42, 0x54, 0x6f, + 0x33, 0x75, 0x4d, 0x34, 0x6d, 0x76, 0x31, 0x2f, 0x68, 0x39, 0x30, 0x56, 0x76, 0x39, 0x32, 0x32, 0x75, 0x38, + 0x33, 0x67, 0x66, 0x6e, 0x62, 0x78, 0x4b, 0x31, 0x57, 0x39, 0x36, 0x47, 0x73, 0x6c, 0x63, 0x75, 0x79, 0x73, + 0x6f, 0x5c, 0x0a, + 0x09, 0x30, 0x79, 0x45, 0x4c, 0x45, 0x4c, 0x65, 0x35, 0x62, 0x39, 0x2b, 0x57, 0x39, 0x4f, 0x36, 0x4d, 0x75, + 0x71, 0x64, 0x4a, 0x2b, 0x70, 0x4d, 0x73, 0x36, 0x42, 0x76, 0x6e, 0x65, 0x55, 0x74, 0x6b, 0x52, 0x42, 0x68, + 0x6f, 0x6f, 0x38, 0x36, 0x53, 0x66, 0x56, 0x61, 0x53, 0x47, 0x63, 0x38, 0x59, 0x53, 0x59, 0x2b, 0x6b, 0x66, + 0x4e, 0x34, 0x75, 0x43, 0x78, 0x52, 0x33, 0x70, 0x76, 0x4a, 0x66, 0x6c, 0x44, 0x51, 0x6c, 0x56, 0x56, 0x2b, + 0x72, 0x5c, 0x0a, + 0x09, 0x70, 0x41, 0x64, 0x6c, 0x6e, 0x36, 0x56, 0x68, 0x49, 0x55, 0x42, 0x52, 0x59, 0x35, 0x77, 0x64, 0x36, + 0x4a, 0x30, 0x67, 0x47, 0x36, 0x6f, 0x6b, 0x36, 0x52, 0x63, 0x35, 0x2b, 0x6a, 0x4e, 0x55, 0x47, 0x59, 0x35, + 0x76, 0x37, 0x49, 0x65, 0x6a, 0x37, 0x54, 0x4a, 0x79, 0x68, 0x61, 0x75, 0x41, 0x6d, 0x32, 0x56, 0x44, 0x66, + 0x42, 0x69, 0x76, 0x6e, 0x44, 0x54, 0x55, 0x44, 0x54, 0x52, 0x45, 0x56, 0x35, 0x4f, 0x6b, 0x61, 0x79, 0x54, + 0x39, 0x5c, 0x0a, + 0x09, 0x51, 0x37, 0x31, 0x78, 0x52, 0x4e, 0x4c, 0x76, 0x4a, 0x56, 0x32, 0x72, 0x36, 0x72, 0x6a, 0x6c, 0x71, + 0x46, 0x78, 0x46, 0x65, 0x77, 0x45, 0x39, 0x32, 0x4c, 0x72, 0x37, 0x45, 0x71, 0x71, 0x6a, 0x2b, 0x68, 0x41, + 0x74, 0x32, 0x50, 0x70, 0x30, 0x43, 0x37, 0x59, 0x75, 0x50, 0x67, 0x72, 0x34, 0x44, 0x52, 0x61, 0x31, 0x58, + 0x77, 0x7a, 0x38, 0x32, 0x76, 0x58, 0x47, 0x41, 0x6c, 0x63, 0x44, 0x79, 0x37, 0x43, 0x39, 0x37, 0x52, 0x65, + 0x77, 0x5c, 0x0a, + 0x09, 0x55, 0x79, 0x37, 0x39, 0x58, 0x64, 0x74, 0x75, 0x78, 0x74, 0x62, 0x32, 0x44, 0x31, 0x49, 0x64, 0x71, + 0x65, 0x38, 0x44, 0x6a, 0x6e, 0x4d, 0x66, 0x30, 0x76, 0x73, 0x43, 0x6a, 0x59, 0x59, 0x5a, 0x32, 0x4f, 0x78, + 0x71, 0x41, 0x76, 0x59, 0x4d, 0x57, 0x34, 0x48, 0x58, 0x68, 0x73, 0x75, 0x5a, 0x6f, 0x74, 0x33, 0x41, 0x54, + 0x6d, 0x78, 0x36, 0x31, 0x56, 0x61, 0x67, 0x30, 0x34, 0x4d, 0x39, 0x78, 0x42, 0x52, 0x73, 0x65, 0x76, 0x4d, + 0x41, 0x5c, 0x0a, + 0x09, 0x38, 0x41, 0x54, 0x77, 0x4d, 0x57, 0x41, 0x74, 0x73, 0x4d, 0x35, 0x74, 0x7a, 0x4d, 0x4d, 0x32, 0x4d, + 0x38, 0x42, 0x32, 0x33, 0x53, 0x35, 0x6c, 0x59, 0x42, 0x73, 0x62, 0x52, 0x37, 0x78, 0x38, 0x47, 0x67, 0x6b, + 0x42, 0x69, 0x6e, 0x78, 0x74, 0x46, 0x47, 0x7a, 0x7a, 0x71, 0x79, 0x46, 0x51, 0x64, 0x43, 0x43, 0x6b, 0x30, + 0x39, 0x50, 0x4a, 0x4e, 0x65, 0x70, 0x49, 0x31, 0x67, 0x41, 0x6d, 0x65, 0x72, 0x6f, 0x45, 0x6d, 0x31, 0x4f, + 0x33, 0x5c, 0x0a, + 0x09, 0x41, 0x4a, 0x64, 0x67, 0x57, 0x36, 0x72, 0x6a, 0x73, 0x4c, 0x6e, 0x75, 0x66, 0x64, 0x6a, 0x57, 0x61, + 0x48, 0x38, 0x61, 0x34, 0x48, 0x7a, 0x67, 0x4c, 0x75, 0x44, 0x34, 0x41, 0x70, 0x32, 0x45, 0x58, 0x4c, 0x58, + 0x6d, 0x30, 0x78, 0x45, 0x70, 0x46, 0x49, 0x30, 0x41, 0x7a, 0x32, 0x42, 0x62, 0x6e, 0x30, 0x58, 0x37, 0x33, + 0x47, 0x42, 0x76, 0x66, 0x52, 0x65, 0x32, 0x4b, 0x41, 0x53, 0x32, 0x69, 0x48, 0x51, 0x35, 0x63, 0x43, 0x35, + 0x77, 0x5c, 0x0a, + 0x09, 0x41, 0x64, 0x59, 0x35, 0x4c, 0x77, 0x4b, 0x2f, 0x6f, 0x6e, 0x72, 0x42, 0x71, 0x4b, 0x2b, 0x34, 0x41, + 0x37, 0x67, 0x49, 0x32, 0x38, 0x70, 0x64, 0x6e, 0x69, 0x45, 0x66, 0x52, 0x2b, 0x58, 0x49, 0x56, 0x4e, 0x34, + 0x43, 0x54, 0x6b, 0x51, 0x4f, 0x69, 0x6d, 0x4b, 0x41, 0x56, 0x75, 0x78, 0x74, 0x33, 0x55, 0x6a, 0x2b, 0x53, + 0x74, 0x7a, 0x52, 0x77, 0x48, 0x4c, 0x67, 0x5a, 0x75, 0x7a, 0x62, 0x50, 0x6a, 0x39, 0x44, 0x76, 0x67, 0x41, + 0x6a, 0x5c, 0x0a, + 0x09, 0x31, 0x39, 0x76, 0x41, 0x75, 0x36, 0x6a, 0x48, 0x6e, 0x76, 0x6b, 0x37, 0x47, 0x45, 0x57, 0x66, 0x67, + 0x45, 0x50, 0x59, 0x53, 0x5a, 0x6e, 0x68, 0x50, 0x6a, 0x47, 0x79, 0x79, 0x74, 0x4d, 0x4f, 0x62, 0x4e, 0x6b, + 0x35, 0x6a, 0x61, 0x73, 0x39, 0x58, 0x55, 0x2f, 0x73, 0x2f, 0x48, 0x35, 0x6a, 0x4a, 0x42, 0x77, 0x4b, 0x2f, + 0x53, 0x4e, 0x32, 0x48, 0x41, 0x76, 0x67, 0x62, 0x6d, 0x77, 0x64, 0x50, 0x55, 0x45, 0x48, 0x46, 0x6e, 0x4d, + 0x41, 0x5c, 0x0a, + 0x09, 0x66, 0x4f, 0x39, 0x6f, 0x4f, 0x76, 0x56, 0x4f, 0x77, 0x55, 0x67, 0x35, 0x45, 0x6e, 0x59, 0x4f, 0x46, + 0x70, 0x4f, 0x30, 0x59, 0x6d, 0x2f, 0x36, 0x76, 0x64, 0x68, 0x52, 0x72, 0x6c, 0x75, 0x78, 0x36, 0x48, 0x38, + 0x39, 0x39, 0x69, 0x6d, 0x49, 0x36, 0x43, 0x64, 0x47, 0x43, 0x67, 0x48, 0x41, 0x64, 0x68, 0x42, 0x58, 0x30, + 0x76, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x77, 0x77, 0x35, 0x78, 0x37, 0x65, 0x35, 0x57, 0x49, 0x71, 0x49, 0x6d, + 0x52, 0x5c, 0x0a, + 0x09, 0x52, 0x41, 0x43, 0x77, 0x6b, 0x65, 0x42, 0x6d, 0x62, 0x4c, 0x36, 0x2f, 0x42, 0x54, 0x76, 0x67, 0x75, + 0x59, 0x34, 0x34, 0x2f, 0x52, 0x73, 0x77, 0x52, 0x68, 0x6f, 0x42, 0x49, 0x6f, 0x59, 0x59, 0x49, 0x79, 0x45, + 0x49, 0x6a, 0x4b, 0x67, 0x6a, 0x49, 0x67, 0x46, 0x4b, 0x6a, 0x6b, 0x69, 0x41, 0x6b, 0x69, 0x4d, 0x53, 0x6f, + 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, 0x35, 0x49, 0x67, 0x46, 0x4b, 0x6a, 0x6b, 0x69, 0x41, 0x6b, 0x69, 0x4d, + 0x53, 0x5c, 0x0a, + 0x09, 0x6f, 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, 0x35, 0x49, 0x67, 0x46, 0x4b, 0x6a, 0x6b, 0x69, 0x41, 0x6b, + 0x69, 0x4d, 0x53, 0x6f, 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, 0x35, 0x49, 0x67, 0x46, 0x4b, 0x6a, 0x6b, 0x69, + 0x41, 0x6b, 0x69, 0x4d, 0x53, 0x6f, 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, 0x35, 0x49, 0x67, 0x46, 0x4b, 0x6a, + 0x6b, 0x69, 0x41, 0x6b, 0x69, 0x4d, 0x53, 0x6f, 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, 0x35, 0x49, 0x67, 0x46, + 0x4b, 0x5c, 0x0a, + 0x09, 0x6a, 0x6b, 0x69, 0x41, 0x6b, 0x69, 0x4d, 0x53, 0x6f, 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, 0x35, 0x49, + 0x67, 0x46, 0x4b, 0x6a, 0x6b, 0x69, 0x41, 0x6b, 0x69, 0x4d, 0x53, 0x6f, 0x4f, 0x53, 0x49, 0x42, 0x43, 0x67, + 0x35, 0x49, 0x67, 0x46, 0x4b, 0x6a, 0x76, 0x38, 0x44, 0x2f, 0x7a, 0x63, 0x46, 0x56, 0x65, 0x67, 0x2b, 0x6a, + 0x62, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x53, 0x55, 0x56, 0x4f, 0x52, 0x4b, 0x35, 0x43, 0x59, 0x49, 0x49, + 0x3d, 0x5c, 0x0a, + 0x09, 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, @@ -1608,53 +4808,326 @@ const unsigned char boot_lua[] = 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5f, 0x22, 0x2c, 0x20, 0x22, 0x2e, 0x22, 0x29, 0x2c, 0x20, 0x22, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x22, 0x29, 0x29, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, + 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x61, 0x69, 0x6e, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x73, 0x65, 0x65, 0x64, 0x28, - 0x6f, 0x73, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x29, 0x0a, - 0x09, 0x09, 0x70, 0x69, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x0a, - 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x78, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x79, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x28, 0x70, 0x69, 0x67, 0x5f, 0x70, 0x6e, 0x67, 0x2c, 0x20, 0x22, 0x70, 0x69, 0x67, 0x2e, 0x70, 0x6e, 0x67, - 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x7d, 0x0a, - 0x09, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, - 0x61, 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x6e, 0x67, 0x2c, - 0x20, 0x22, 0x68, 0x65, 0x61, 0x72, 0x74, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x29, 0x0a, - 0x09, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, - 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x32, 0x2e, 0x34, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, - 0x35, 0x30, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x32, 0x2e, 0x32, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x32, - 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x2c, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x32, - 0x35, 0x30, 0x2c, 0x20, 0x33, 0x35, 0x2c, 0x20, 0x31, 0x2e, 0x38, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x33, - 0x30, 0x30, 0x2c, 0x20, 0x34, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x36, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x33, - 0x35, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x34, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x34, - 0x30, 0x30, 0x2c, 0x20, 0x36, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x32, 0x29, 0x0a, - 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x34, - 0x35, 0x30, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x31, 0x29, 0x0a, + 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x62, + 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x63, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x73, 0x6f, 0x0a, + 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x77, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6d, 0x61, 0x6b, + 0x65, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, 0x74, 0x20, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x20, 0x6c, 0x6f, + 0x6f, 0x6b, 0x73, 0x20, 0x64, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, + 0x2e, 0x69, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x28, 0x22, 0x73, 0x75, 0x62, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, + 0x31, 0x33, 0x37, 0x2c, 0x20, 0x31, 0x39, 0x34, 0x2c, 0x20, 0x32, 0x31, 0x38, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, + 0x31, 0x31, 0x2c, 0x20, 0x38, 0x38, 0x2c, 0x20, 0x31, 0x32, 0x33, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x6e, 0x5f, 0x77, 0x20, 0x3d, 0x20, 0x6c, 0x6f, + 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, + 0x74, 0x68, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x6e, 0x5f, 0x68, 0x20, 0x3d, 0x20, 0x6c, 0x6f, + 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, + 0x3d, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x5f, 0x70, 0x6e, 0x67, 0x2c, 0x20, 0x22, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x77, 0x20, + 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, + 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x68, 0x20, + 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, + 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x77, 0x69, + 0x6e, 0x5f, 0x77, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x34, 0x35, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x77, 0x69, + 0x6e, 0x5f, 0x68, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x35, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x70, 0x6e, 0x67, 0x2c, 0x20, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x77, + 0x20, 0x3d, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x3a, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x68, + 0x20, 0x3d, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x3a, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x09, 0x09, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x6c, + 0x6f, 0x61, 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x6e, + 0x67, 0x2c, 0x20, 0x22, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x77, 0x20, 0x3d, 0x20, 0x62, + 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, + 0x74, 0x68, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x68, 0x20, 0x3d, 0x20, 0x62, + 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x31, 0x34, 0x30, 0x0a, + 0x09, 0x09, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x2d, 0x38, 0x30, 0x0a, + 0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x61, + 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x6e, 0x67, 0x2c, 0x20, 0x22, + 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x32, 0x35, 0x0a, + 0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x39, 0x0a, + 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x42, 0x61, 0x62, 0x79, 0x20, 0x52, 0x61, 0x69, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x78, 0x20, 0x3d, + 0x20, 0x31, 0x31, 0x30, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x79, 0x20, 0x3d, + 0x20, 0x38, 0x30, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x61, + 0x64, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x62, 0x61, 0x62, 0x79, 0x5f, 0x70, 0x6e, 0x67, 0x2c, 0x20, 0x22, + 0x62, 0x61, 0x62, 0x79, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x77, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, + 0x6e, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x68, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, + 0x6e, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, + 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x6f, 0x78, 0x20, 0x3d, 0x20, 0x2d, 0x72, 0x61, 0x69, 0x6e, 0x2e, + 0x69, 0x6d, 0x67, 0x5f, 0x77, 0x20, 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x6f, 0x79, 0x20, 0x3d, 0x20, 0x2d, 0x72, 0x61, 0x69, 0x6e, 0x2e, + 0x69, 0x6d, 0x67, 0x5f, 0x68, 0x20, 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x62, 0x61, 0x74, 0x63, 0x68, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, + 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x72, 0x69, + 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x28, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x2c, 0x20, 0x35, 0x31, 0x32, 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x09, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x0a, + 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, + 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, 0x20, 0x3d, 0x20, 0x72, 0x61, + 0x69, 0x6e, 0x2e, 0x62, 0x61, 0x74, 0x63, 0x68, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x78, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x2e, + 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x78, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x2e, + 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x79, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x78, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x2e, + 0x6f, 0x78, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x2e, + 0x6f, 0x79, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x20, 0x3d, 0x20, + 0x32, 0x20, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, + 0x28, 0x29, 0x20, 0x2f, 0x20, 0x73, 0x78, 0x29, 0x20, 0x2b, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x68, 0x20, 0x3d, 0x20, + 0x32, 0x20, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x73, 0x79, 0x29, 0x20, 0x2b, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x67, 0x65, 0x74, 0x42, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x20, 0x3c, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, + 0x20, 0x2a, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x68, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x73, 0x65, 0x74, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x53, 0x69, 0x7a, 0x65, 0x28, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x20, 0x2a, 0x20, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x68, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x5f, 0x68, 0x20, 0x2d, 0x20, 0x31, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6a, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x5f, 0x77, 0x20, 0x2d, 0x20, 0x31, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x20, + 0x3d, 0x20, 0x28, 0x6a, 0x20, 0x25, 0x20, 0x32, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x79, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x30, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x79, 0x20, 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x6f, 0x78, 0x20, 0x2b, + 0x20, 0x6a, 0x20, 0x2a, 0x20, 0x73, 0x78, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x6f, 0x79, 0x20, 0x2b, + 0x20, 0x69, 0x20, 0x2a, 0x20, 0x73, 0x79, 0x20, 0x2b, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x79, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x61, 0x64, 0x64, 0x28, 0x78, 0x2c, 0x20, 0x79, + 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x75, 0x6e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x61, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x09, 0x09, 0x0a, + 0x09, 0x09, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x0a, + 0x09, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, - 0x09, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x28, 0x64, 0x74, + 0x09, 0x09, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x2b, 0x20, 0x64, 0x74, 0x20, 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x63, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x6f, 0x64, 0x66, 0x28, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x29, 0x0a, + 0x09, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x61, 0x69, 0x6e, 0x28, 0x66, 0x72, 0x61, 0x63, + 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x6c, 0x6f, + 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, + 0x74, 0x68, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x34, 0x35, 0x0a, + 0x09, 0x09, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, + 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x35, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, + 0x61, 0x77, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x6f, 0x64, 0x65, 0x20, + 0x3d, 0x20, 0x22, 0x73, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x28, 0x22, + 0x73, 0x75, 0x62, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x65, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x73, 0x65, + 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x69, 0x74, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x4f, 0x4b, 0x2e, 0x0a, + 0x09, 0x09, 0x09, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x73, + 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x79, 0x20, 0x2a, 0x20, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x74, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x79, 0x20, 0x3d, 0x20, + 0x2d, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x79, 0x20, 0x2b, 0x20, + 0x79, 0x20, 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x69, 0x67, 0x5f, 0x79, 0x20, 0x3d, 0x20, 0x2d, 0x72, + 0x61, 0x69, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x79, 0x20, 0x2b, 0x20, 0x79, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x6d, 0x6f, + 0x64, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x31, 0x32, 0x38, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2c, 0x20, 0x2d, 0x72, 0x61, + 0x69, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x78, 0x2c, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x5f, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x22, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x22, + 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x72, 0x61, 0x69, 0x6e, 0x2e, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2c, 0x20, 0x2d, 0x72, 0x61, + 0x69, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x78, 0x2c, 0x20, 0x62, 0x69, 0x67, 0x5f, + 0x79, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, + 0x61, 0x77, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x63, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x6f, 0x64, 0x66, 0x28, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x63, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x78, 0x20, 0x3d, 0x20, 0x78, 0x20, 0x2b, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x78, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x79, 0x20, 0x2b, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x79, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x74, 0x78, 0x2c, + 0x20, 0x74, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, + 0x37, 0x30, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, + 0x61, 0x77, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x78, 0x2c, 0x20, 0x79, + 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x20, + 0x3d, 0x20, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x70, + 0x69, 0x20, 0x2a, 0x20, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x2a, 0x20, 0x32, 0x29, 0x20, 0x2b, 0x20, + 0x31, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x78, 0x20, 0x3d, 0x20, 0x78, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x79, 0x20, 0x3d, 0x20, 0x79, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x36, 0x34, 0x20, 0x2b, 0x20, 0x31, 0x36, 0x2a, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x74, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x2c, 0x20, 0x62, 0x78, 0x2c, 0x20, 0x62, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x37, 0x2c, + 0x20, 0x30, 0x2e, 0x37, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x33, 0x32, 0x20, 0x2b, 0x20, 0x31, 0x36, 0x2a, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x74, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x2c, 0x20, 0x62, 0x78, 0x2c, 0x20, 0x62, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x36, 0x35, + 0x2c, 0x20, 0x30, 0x2e, 0x36, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x22, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x31, 0x36, 0x20, 0x2b, 0x20, 0x31, 0x36, 0x2a, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x74, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x2c, 0x20, 0x62, 0x78, 0x2c, 0x20, 0x62, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x36, 0x2c, + 0x20, 0x30, 0x2e, 0x36, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, + 0x61, 0x77, 0x5f, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x73, 0x63, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x20, 0x2a, + 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x69, 0x20, + 0x2a, 0x20, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x78, 0x20, 0x3d, 0x20, 0x78, 0x20, 0x2b, 0x20, 0x62, + 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x78, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x79, 0x20, 0x3d, 0x20, 0x79, 0x20, 0x2b, 0x20, 0x62, + 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x6f, 0x73, 0x63, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x62, + 0x78, 0x2c, 0x20, 0x62, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x37, 0x30, + 0x2c, 0x20, 0x37, 0x30, 0x29, 0x0a, + 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x28, 0x62, 0x78, 0x2c, 0x20, 0x62, 0x79, + 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, + 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x78, 0x2c, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x2e, 0x79, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x78, 0x2c, 0x20, 0x6f, 0x79, 0x20, 0x3d, 0x20, 0x69, + 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x77, 0x20, 0x2f, 0x20, 0x32, + 0x2c, 0x20, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x68, 0x20, + 0x2f, 0x20, 0x32, 0x0a, + 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, + 0x78, 0x2c, 0x20, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x22, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x22, + 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, + 0x61, 0x77, 0x28, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x6f, + 0x78, 0x2c, 0x20, 0x6f, 0x79, 0x29, 0x0a, + 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x62, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, - 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, - 0x35, 0x34, 0x2c, 0x20, 0x32, 0x32, 0x34, 0x2c, 0x20, 0x32, 0x33, 0x38, 0x29, 0x0a, - 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x73, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x69, 0x67, 0x28, 0x70, 0x69, 0x67, 0x29, 0x0a, + 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, + 0x35, 0x35, 0x29, 0x0a, + 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x28, 0x29, 0x0a, + 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, @@ -1680,6 +5153,8 @@ const unsigned char boot_lua[] = 0x73, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x09, 0x74, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 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, @@ -1709,14 +5184,44 @@ const unsigned char boot_lua[] = 0x67, 0x29, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x6d, 0x73, 0x67, 0x2c, 0x20, 0x32, 0x29, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x69, 0x63, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x69, 0x63, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x2e, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x20, 0x6f, 0x72, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, + 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, + 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x38, + 0x30, 0x30, 0x2c, 0x20, 0x36, 0x30, 0x30, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6f, + 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x56, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x47, 0x72, + 0x61, 0x62, 0x62, 0x65, 0x64, 0x28, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x74, 0x6f, 0x70, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6a, 0x6f, 0x79, 0x73, + 0x74, 0x69, 0x63, 0x6b, 0x20, 0x76, 0x69, 0x62, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, + 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, + 0x73, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x2e, 0x67, 0x65, + 0x74, 0x4a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x29, 0x29, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x09, 0x76, 0x3a, 0x73, 0x65, 0x74, 0x56, 0x69, 0x62, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, @@ -1726,10 +5231,8 @@ const unsigned char boot_lua[] = 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 0x39, 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, - 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x46, 0x6f, 0x6e, 0x74, 0x28, - 0x31, 0x34, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x46, 0x6f, 0x6e, 0x74, 0x28, 0x66, 0x6f, 0x6e, 0x74, 0x29, 0x0a, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4e, 0x65, 0x77, 0x46, 0x6f, + 0x6e, 0x74, 0x28, 0x31, 0x34, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a, @@ -1737,6 +5240,8 @@ const unsigned char boot_lua[] = 0x75, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, + 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x22, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x5c, 0x6e, 0x22, 0x29, 0x0a, @@ -1774,109 +5279,35 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, - 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x61, 0x69, 0x74, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x65, 0x73, 0x63, - 0x61, 0x70, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, + 0x29, 0x0a, + 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x20, 0x69, + 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28, + 0x29, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x65, 0x73, + 0x63, 0x61, 0x70, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x65, 0x6e, 0x64, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x0a, - 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, - 0x61, 0x73, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x61, - 0x6d, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, - 0x64, 0x2e, 0x22, 0x29, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x69, 0x63, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x28, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x28, 0x29, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x2e, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x28, - 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73, - 0x65, 0x74, 0x28, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 0x39, - 0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, - 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x46, 0x6f, 0x6e, 0x74, 0x28, - 0x31, 0x34, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x46, 0x6f, 0x6e, 0x74, 0x28, 0x66, 0x6f, 0x6e, 0x74, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, - 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, 0x65, - 0x61, 0x72, 0x28, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, - 0x09, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x28, 0x22, 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6f, 0x63, 0x63, - 0x75, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x75, 0x73, 0x65, 0x64, 0x20, 0x25, - 0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x70, 0x2e, 0x5c, 0x6e, 0x59, 0x6f, 0x75, 0x20, 0x63, 0x61, - 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x20, 0x25, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x25, 0x73, 0x2e, 0x22, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x68, - 0x69, 0x73, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, - 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x22, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, - 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x75, 0x72, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x22, 0x20, - 0x61, 0x74, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x2e, 0x75, 0x72, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x22, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, - 0x61, 0x77, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, - 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x66, 0x28, 0x70, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x6c, 0x6f, - 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, - 0x74, 0x68, 0x28, 0x29, 0x20, 0x2d, 0x20, 0x37, 0x30, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x0a, - 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, - 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x61, 0x69, 0x74, 0x28, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65, + 0x70, 0x28, 0x30, 0x2e, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x65, 0x73, 0x63, - 0x61, 0x70, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x65, 0x72, 0x45, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x28, - 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x65, 0x72, 0x72, 0x68, 0x61, - 0x6e, 0x64, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, - 0x64, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x29, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6c, + 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, diff --git a/src/scripts/graphics.lua b/src/scripts/graphics.lua index dbd0fa69a..2af520bcb 100644 --- a/src/scripts/graphics.lua +++ b/src/scripts/graphics.lua @@ -1,5 +1,5 @@ --[[ -Copyright (c) 2006-2013 LOVE Development Team +Copyright (c) 2006-2014 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 @@ -1295,16 +1295,18 @@ do #define number float #define Image sampler2D #define extern uniform -#define Texel texture2D]] +#define Texel texture2D +#define love_Canvases gl_FragData]] local GLSL_UNIFORMS = [[ -#define ModelViewMatrix gl_ModelViewMatrix +#define TransformMatrix gl_ModelViewMatrix #define ProjectionMatrix gl_ProjectionMatrix -#define ModelViewProjectionMatrix gl_ModelViewProjectionMatrix +#define TransformProjectionMatrix gl_ModelViewProjectionMatrix #define NormalMatrix gl_NormalMatrix -uniform sampler2D _tex0_;]] +uniform sampler2D _tex0_; +uniform vec2 love_ScreenParams;]] - local GLSL_VERT = { + local GLSL_VERTEX = { HEADER = [[ #define VERTEX @@ -1319,11 +1321,11 @@ uniform sampler2D _tex0_;]] void main() { VaryingTexCoord = VertexTexCoord; VaryingColor = VertexColor; - gl_Position = position(ModelViewProjectionMatrix, VertexPosition); + gl_Position = position(TransformProjectionMatrix, VertexPosition); }]], } - local GLSL_FRAG = { + local GLSL_PIXEL = { HEADER = [[ #define PIXEL @@ -1332,64 +1334,105 @@ void main() { FOOTER = [[ void main() { - // fix weird crashing issue in OSX when _tex0_ is unused within effect() + // fix crashing issue in OSX when _tex0_ is unused within effect() float dummy = texture2D(_tex0_, vec2(.5)).r; - gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy); + + // See Shader::checkSetScreenParams in Shader.cpp. + vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenParams[0]) + love_ScreenParams[1]); + + gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord); +}]], + + FOOTER_MULTI_CANVAS = [[ +void main() { + // fix crashing issue in OSX when _tex0_ is unused within effect() + float dummy = texture2D(_tex0_, vec2(.5)).r; + + // See Shader::checkSetScreenParams in Shader.cpp. + vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenParams[0]) + love_ScreenParams[1]); + + effects(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord); }]], } - local function createVertCode(vertcode) - local vertcodes = { + local function createVertexCode(vertexcode) + local vertexcodes = { GLSL_VERSION, - GLSL_SYNTAX, GLSL_VERT.HEADER, GLSL_UNIFORMS, + GLSL_SYNTAX, GLSL_VERTEX.HEADER, GLSL_UNIFORMS, "#line 0", - vertcode, - GLSL_VERT.FOOTER, + vertexcode, + GLSL_VERTEX.FOOTER, } - return table_concat(vertcodes, "\n") + return table_concat(vertexcodes, "\n") end - local function createFragCode(fragcode) - local fragcodes = { + local function createPixelCode(pixelcode, is_multicanvas) + local pixelcodes = { GLSL_VERSION, - GLSL_SYNTAX, GLSL_FRAG.HEADER, GLSL_UNIFORMS, + GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS, "#line 0", - fragcode, - GLSL_FRAG.FOOTER + pixelcode, + is_multicanvas and GLSL_PIXEL.FOOTER_MULTI_CANVAS or GLSL_PIXEL.FOOTER, } - return table_concat(fragcodes, "\n") + return table_concat(pixelcodes, "\n") end - function love.graphics._shaderCodeToGLSL(vertcode, fragcode) - if vertcode then - local s = vertcode:gsub("\r\n\t", " ") - s = s:gsub("%w+(%s+)%(", "") - if s:match("vec4%s*effect%(") then - fragcode = vertcode -- first argument contains frag shader code + local function isVertexCode(code) + return code:match("vec4%s*position%(") ~= nil + end + + local function isPixelCode(code) + if code:match("vec4%s*effect%(") then + return true + elseif code:match("void%s*effects%(") then -- render to multiple canvases simultaniously + return true, true + else + return false + end + end + + function love.graphics._shaderCodeToGLSL(arg1, arg2) + local vertexcode, pixelcode + local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect" + + if arg1 then + local s = arg1:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing + s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()" + + if isVertexCode(s) then + vertexcode = arg1 -- first arg contains vertex shader code end - if not s:match("vec4%s*position%(") then - vertcode = nil -- first argument doesn't contain vert shader code + + local ispixel, isMultiCanvas = isPixelCode(s) + if ispixel then + pixelcode = arg1 -- first arg contains pixel shader code + is_multicanvas = isMultiCanvas end end - if fragcode then - local s = fragcode:gsub("\r\n\t", " ") - s = s:gsub("%w+(%s+)%(", "") - if s:match("vec4%s*position%(") then - vertcode = fragcode -- second argument contains vert shader code + + if arg2 then + local s = arg2:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing + s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()" + + if isVertexCode(s) then + vertexcode = arg2 -- second arg contains vertex shader code end - if not s:match("vec4%s*effect%(") then - fragcode = nil -- second argument doesn't contain frag shader code + + local ispixel, isMultiCanvas = isPixelCode(s) + if ispixel then + pixelcode = arg2 -- second arg contains pixel shader code + is_multicanvas = isMultiCanvas end end - if vertcode then - vertcode = createVertCode(vertcode) + if vertexcode then + vertexcode = createVertexCode(vertexcode) end - if fragcode then - fragcode = createFragCode(fragcode) + if pixelcode then + pixelcode = createPixelCode(pixelcode, is_multicanvas) end - return vertcode, fragcode + return vertexcode, pixelcode end function love.graphics._transformGLSLErrorMessages(message) @@ -1418,80 +1461,4 @@ void main() { if #lines == 1 then return message end return table_concat(lines, "\n") end - - -- helper to transform a matrix from {{a,b,c}, {d,e,f}, ...} to - -- {a, b, c, d, e, f, ...} - local function flattenMatrices(mat, ...) - if not mat then return end - - local tonumber = tonumber - - local ret,l = {}, 1 - ret.dimension = #mat - - for i = 1,#mat do - for k = 1,#mat[i] do - ret[l], l = tonumber(mat[i][k]), l+1 - end - end - - return ret, flattenMatrices(...) - end - - -- automagic uniform setter - local function shader_dispatch_send(self, name, value, ...) - local valuetype = type(value) - if valuetype == "number" or valuetype == "boolean" then -- scalar - self:sendFloat(name, value, ...) - elseif valuetype == "userdata" and value:typeOf("Image") then - self:sendImage(name, value) - elseif valuetype == "userdata" and value:typeOf("Canvas") then - self:sendCanvas(name, value) - elseif valuetype == "table" then -- vector or matrix - valuetype = type(value[1]) - if valuetype == "number" or valuetype == "boolean" then - self:sendFloat(name, value, ...) - elseif valuetype == "table" then - self:sendMatrix(name, flattenMatrices(value, ...)) - else - error("Cannot send value (unsupported type: {"..valuetype.."}).") - end - else - if valuetype == "userdata" and value.type then valuetype = value.type end - error("Cannot send value (unsupported type: "..valuetype..").") - end - end - - local newShader = love.graphics.newShader - function love.graphics.newShader(vertcode, fragcode) - love.graphics.newShader = function(vertcode, fragcode) - if love.filesystem then - if vertcode and love.filesystem.exists(vertcode) then - vertcode = love.filesystem.read(vertcode) - end - if fragcode and love.filesystem.exists(fragcode) then - fragcode = love.filesystem.read(fragcode) - end - end - return newShader(vertcode, fragcode) - end - - local shader = love.graphics.newShader(vertcode, fragcode) - local meta = getmetatable(shader) - meta.send = shader_dispatch_send - meta.sendBoolean = meta.sendFloat - return shader - end - - - -- PixelEffect compatibility functions - - function love.graphics.newPixelEffect(fragcode) - return love.graphics.newShader(nil, fragcode) - end - - love.graphics.setPixelEffect = love.graphics.setShader - love.graphics.getPixelEffect = love.graphics.getShader - - love.graphics._effectCodeToGLSL = love.graphics._shaderCodeToGLSL end diff --git a/src/scripts/graphics.lua.h b/src/scripts/graphics.lua.h index 9439c0e1a..c08ac6326 100644 --- a/src/scripts/graphics.lua.h +++ b/src/scripts/graphics.lua.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2013 LOVE Development Team + * Copyright (c) 2006-2014 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 @@ -6276,25 +6276,29 @@ const unsigned char graphics_lua[] = 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x75, 0x72, 0x65, 0x32, 0x44, 0x5d, 0x5d, 0x0a, + 0x75, 0x72, 0x65, 0x32, 0x44, 0x0a, + 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x76, 0x61, + 0x73, 0x65, 0x73, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x5d, 0x5d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a, - 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x4d, + 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a, - 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, + 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a, 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, 0x56, 0x45, 0x52, 0x54, 0x20, 0x3d, - 0x20, 0x7b, 0x0a, + 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x0a, + 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, + 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3b, 0x5d, 0x5d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, + 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x50, 0x6f, 0x73, 0x69, @@ -6317,13 +6321,13 @@ const unsigned char graphics_lua[] = 0x09, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x3b, 0x0a, 0x7d, 0x5d, 0x5d, 0x2c, 0x0a, 0x09, 0x7d, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41, 0x47, 0x20, 0x3d, - 0x20, 0x7b, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x20, + 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x78, @@ -6333,119 +6337,202 @@ const unsigned char graphics_lua[] = 0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x5d, 0x5d, 0x2c, 0x0a, 0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, - 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, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 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, 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, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a, + 0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, + 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, + 0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, + 0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, + 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, - 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x73, 0x74, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, - 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a, + 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x73, 0x74, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x29, 0x3b, 0x0a, + 0x7d, 0x5d, 0x5d, 0x2c, 0x0a, + 0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e, + 0x56, 0x41, 0x53, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a, + 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, + 0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 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, 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, 0x2f, 0x2f, 0x20, 0x53, 0x65, 0x65, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x53, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x20, 0x69, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x63, 0x70, 0x70, 0x2e, 0x0a, + 0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, + 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, + 0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, + 0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, + 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a, + 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, + 0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x73, 0x74, 0x2c, 0x20, 0x70, 0x69, 0x78, + 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x3b, 0x0a, 0x7d, 0x5d, 0x5d, 0x2c, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, - 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x20, - 0x3d, 0x20, 0x7b, 0x0a, + 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x76, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47, 0x4c, - 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x47, 0x4c, - 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a, + 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, + 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x22, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x30, 0x22, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45, + 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x2e, 0x46, 0x4f, 0x4f, + 0x54, 0x45, 0x52, 0x2c, 0x0a, + 0x09, 0x09, 0x7d, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x63, 0x61, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x22, + 0x5c, 0x6e, 0x22, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65, + 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, + 0x76, 0x61, 0x73, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x73, + 0x20, 0x3d, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47, 0x4c, + 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x47, + 0x4c, 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x22, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x30, 0x22, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, + 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x41, 0x4e, 0x56, 0x41, 0x53, 0x20, 0x6f, + 0x72, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, - 0x63, 0x61, 0x74, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x22, 0x5c, 0x6e, - 0x22, 0x29, 0x0a, + 0x63, 0x61, 0x74, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x22, 0x5c, + 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, - 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x20, - 0x3d, 0x20, 0x7b, 0x0a, - 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x2c, 0x20, 0x47, 0x4c, - 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41, 0x47, 0x2e, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x47, 0x4c, - 0x53, 0x4c, 0x5f, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x22, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x30, 0x22, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x52, 0x41, 0x47, 0x2e, 0x46, 0x4f, 0x4f, 0x54, 0x45, - 0x52, 0x0a, - 0x09, 0x09, 0x7d, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, - 0x63, 0x61, 0x74, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x20, 0x22, 0x5c, 0x6e, - 0x22, 0x29, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, + 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x28, 0x22, 0x76, 0x65, 0x63, 0x34, 0x25, 0x73, 0x2a, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x25, 0x28, 0x22, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, + 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x76, + 0x65, 0x63, 0x34, 0x25, 0x73, 0x2a, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x28, 0x22, 0x76, 0x6f, 0x69, 0x64, 0x25, 0x73, 0x2a, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x25, + 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x76, 0x61, + 0x73, 0x65, 0x73, 0x20, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x74, 0x61, 0x6e, 0x69, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 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, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x54, - 0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, - 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, - 0x6f, 0x64, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x74, 0x22, 0x2c, - 0x20, 0x22, 0x20, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x77, 0x2b, - 0x28, 0x25, 0x73, 0x2b, 0x29, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x76, 0x65, 0x63, - 0x34, 0x25, 0x73, 0x2a, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x28, 0x61, 0x72, 0x67, 0x31, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x32, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, + 0x2c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, + 0x6e, 0x76, 0x61, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x68, + 0x61, 0x73, 0x20, 0x22, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x22, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x22, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x22, 0x0a, + 0x09, 0x09, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x31, 0x3a, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x20, 0x22, + 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x0a, + 0x09, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x28, 0x25, 0x77, + 0x2b, 0x29, 0x28, 0x25, 0x73, 0x2b, 0x29, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x28, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x28, 0x29, 0x22, 0x20, 0x74, 0x6f, 0x20, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x29, 0x22, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, + 0x28, 0x73, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x61, + 0x72, 0x67, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x73, 0x68, 0x61, + 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2c, 0x20, + 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x73, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x72, + 0x67, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, + 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x32, 0x3a, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x20, 0x22, + 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x0a, + 0x09, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x28, 0x25, 0x77, + 0x2b, 0x29, 0x28, 0x25, 0x73, 0x2b, 0x29, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x28, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x28, 0x29, 0x22, 0x20, 0x74, 0x6f, 0x20, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x29, 0x22, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, + 0x28, 0x73, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x61, + 0x72, 0x67, 0x32, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x67, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x73, 0x68, + 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2c, 0x20, + 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x73, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x72, + 0x67, 0x32, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x67, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x73, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x0a, + 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x76, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x72, - 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x66, 0x72, 0x61, - 0x67, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, - 0x22, 0x76, 0x65, 0x63, 0x34, 0x25, 0x73, 0x2a, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x28, - 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, - 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x76, - 0x65, 0x72, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x09, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x76, + 0x61, 0x73, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, - 0x6f, 0x64, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x72, 0x5c, 0x6e, 0x5c, 0x74, 0x22, 0x2c, - 0x20, 0x22, 0x20, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x77, 0x2b, - 0x28, 0x25, 0x73, 0x2b, 0x29, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x76, 0x65, 0x63, - 0x34, 0x25, 0x73, 0x2a, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x72, 0x61, - 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x61, 0x72, - 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x76, 0x65, - 0x72, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, - 0x22, 0x76, 0x65, 0x63, 0x34, 0x25, 0x73, 0x2a, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x25, 0x28, 0x22, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, - 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, - 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, - 0x66, 0x72, 0x61, 0x67, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x56, 0x65, 0x72, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, - 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, - 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, - 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x64, + 0x65, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 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, @@ -6522,164 +6609,6 @@ const unsigned char graphics_lua[] = 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x66, 0x72, 0x6f, - 0x6d, 0x20, 0x7b, 0x7b, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x7d, 0x2c, 0x20, 0x7b, 0x64, 0x2c, 0x65, 0x2c, 0x66, - 0x7d, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x7d, 0x20, 0x74, 0x6f, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x7b, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x65, - 0x2c, 0x20, 0x66, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x7d, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6c, - 0x61, 0x74, 0x74, 0x65, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x63, 0x65, 0x73, 0x28, 0x6d, 0x61, 0x74, 0x2c, - 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x3d, - 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x2c, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x7d, - 0x2c, 0x20, 0x31, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, - 0x23, 0x6d, 0x61, 0x74, 0x0a, - 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x23, 0x6d, 0x61, 0x74, 0x20, 0x64, - 0x6f, 0x0a, - 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x23, 0x6d, 0x61, 0x74, 0x5b, - 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x6c, 0x5d, 0x2c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x6d, 0x61, 0x74, 0x5b, 0x69, 0x5d, 0x5b, 0x6b, 0x5d, 0x29, 0x2c, - 0x20, 0x6c, 0x2b, 0x31, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x61, 0x74, - 0x74, 0x65, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x63, 0x65, 0x73, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x20, 0x75, 0x6e, 0x69, 0x66, - 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x65, 0x74, 0x74, 0x65, 0x72, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x68, - 0x61, 0x64, 0x65, 0x72, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x6e, 0x64, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, - 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x0a, - 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x66, 0x28, 0x22, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x66, 0x28, 0x22, 0x43, 0x61, 0x6e, - 0x76, 0x61, 0x73, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, - 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x6d, - 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a, - 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, - 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74, - 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x61, 0x74, 0x72, 0x69, - 0x78, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x66, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x4d, 0x61, 0x74, - 0x72, 0x69, 0x63, 0x65, 0x73, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, - 0x73, 0x65, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x7b, 0x22, 0x2e, 0x2e, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x7d, 0x29, 0x2e, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, - 0x20, 0x22, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x73, - 0x65, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x29, 0x2e, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3d, - 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, - 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x0a, - 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x28, 0x76, 0x65, - 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, - 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, - 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, - 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, - 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, - 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, - 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, - 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, - 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6c, - 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, - 0x61, 0x64, 0x65, 0x72, 0x28, 0x76, 0x65, 0x72, 0x74, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x72, 0x61, - 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, - 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x29, 0x0a, - 0x09, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x61, 0x64, - 0x65, 0x72, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, - 0x20, 0x3d, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x2d, 0x2d, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6f, - 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x0a, - 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x28, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x28, 0x6e, 0x69, 0x6c, - 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, - 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, - 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x0a, - 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, - 0x50, 0x69, 0x78, 0x65, 0x6c, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, - 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x0a, - 0x09, 0x0a, - 0x09, 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, 0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x3d, 0x20, 0x6c, - 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x73, 0x68, 0x61, 0x64, - 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x54, 0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, }; // [graphics.lua] } // love \ No newline at end of file