From d491afe404d7e2c6a2872c8f8dd98d8d5957c2d7 Mon Sep 17 00:00:00 2001 From: Martin Moracek Date: Fri, 2 Jan 2009 18:42:17 +0100 Subject: [PATCH] Initial commit, includes Lua with broken Luabind as a backup for branching purposes --- CMakeLists.txt | 5 + Doxyfile | 316 + LICENSE | 333 + TODO.txt | 172 + config/client.xml | 17 + data-client/effects/fnt_texture.cgfx | 47 + data-client/effects/gui_texture.cgfx | 48 + data-client/fonts/dejavu-mono.xml | 7 + data-client/fonts/dejavu-sans-condensed.xml | 7 + data-client/fonts/dejavu-sans.xml | 7 + data-client/fonts/dejavu-serif-condensed.xml | 7 + data-client/fonts/dejavu-serif.xml | 7 + data-client/fonts/gputeks.xml | 7 + data-client/fonts/liberation-mono.xml | 7 + data-client/fonts/liberation-sans.xml | 7 + data-client/fonts/liberation-serif.xml | 7 + data-client/fonts/misc/7monkey.xml | 4 + data-client/fonts/misc/7swordsmen.xml | 4 + data-client/fonts/misc/anglican.xml | 4 + data-client/fonts/misc/bettynoir.xml | 4 + data-client/fonts/misc/bottlerocket.xml | 5 + data-client/fonts/misc/caeldera.xml | 4 + data-client/fonts/misc/catholic.xml | 4 + data-client/fonts/misc/chopin.xml | 4 + data-client/fonts/misc/decrepit.xml | 4 + data-client/fonts/misc/deutsch.xml | 4 + data-client/fonts/misc/dragonfly.xml | 4 + data-client/fonts/misc/gessele.xml | 4 + data-client/fonts/misc/gorilla.xml | 5 + data-client/fonts/misc/lexia.xml | 5 + data-client/fonts/misc/marspolice.xml | 5 + data-client/fonts/misc/maxhand.xml | 4 + data-client/fonts/misc/mccoy.xml | 4 + data-client/fonts/misc/nasalization.xml | 4 + data-client/fonts/misc/neuropolitical.xml | 4 + data-client/fonts/misc/oldgermen.xml | 4 + data-client/fonts/misc/paternoster.xml | 4 + data-client/fonts/misc/prefix.xml | 4 + data-client/fonts/misc/radio-condensed.xml | 4 + data-client/fonts/misc/radio.xml | 7 + data-client/fonts/misc/randi.xml | 4 + data-client/fonts/misc/spaceage.xml | 4 + data-client/fonts/misc/spacedock.xml | 4 + data-client/fonts/misc/spirit.xml | 4 + data-client/fonts/misc/subamera.xml | 4 + data-client/fonts/misc/toolate.xml | 4 + data-client/fonts/misc/typewriter.xml | 4 + data-client/fonts/misc/typicalwriter.xml | 4 + data-client/fonts/misc/venus.xml | 4 + data-client/fonts/misc/vibrocentric.xml | 4 + data-client/fonts/misc/village.xml | 4 + data-client/fonts/misc/virginie.xml | 4 + data-client/fonts/misc/walrod.xml | 4 + data-client/fonts/misc/warmonger.xml | 4 + data-client/fonts/misc/zirkon.xml | 4 + data-client/gui/cursors/co-green.xml | 13 + data-client/gui/main.xml | 8 + data-client/gui/skin/skulpture.xml | 240 + data-client/gui/widgets/main-console.xml | 79 + data-client/gui/widgets/main-normal.xml | 85 + data-client/gui/widgets/main-perc.xml | 85 + data-client/gui/widgets/main-wdgs.xml | 85 + data-client/gui/widgets/splash.xml | 153 + data-client/gui/widgets/test.xml | 172 + data-client/script/init.lua | 52 + data-server/script/init.lua | 83 + data-shared/models/fighter.x | 14144 ++++++++++++++++++++ include/assertion.h | 51 + include/common.h | 35 + include/config.h | 36 + include/core/application.h | 53 + include/core/client/display.h | 67 + include/core/conf_core.h | 31 + include/core/init_sdl.cpp | 44 + include/core/script_core.h | 39 + include/core/timer.h | 75 + include/core/vmachine.h | 65 + include/cpair.h | 114 + include/exception.h | 58 + include/gui/basic.h | 255 + include/gui/font/font.h | 117 + include/gui/gui.h | 183 + include/gui/init_basic.cpp | 61 + include/gui/pixmap.h | 144 + include/gui/plaintext.h | 76 + include/gui/richtext.h | 264 + include/gui/text.h | 164 + include/gui/widget.h | 174 + include/input/input.h | 207 + include/lua/lauxlib.h | 171 + include/lua/lua.h | 388 + include/lua/luaconf.h | 744 + include/lua/lualib.h | 53 + include/luabind/adopt_policy.hpp | 156 + include/luabind/back_reference.hpp | 112 + include/luabind/back_reference_fwd.hpp | 37 + include/luabind/class.hpp | 1462 ++ include/luabind/class_info.hpp | 47 + include/luabind/config.hpp | 161 + include/luabind/container_policy.hpp | 138 + include/luabind/copy_policy.hpp | 61 + include/luabind/dependency_policy.hpp | 119 + include/luabind/detail/calc_arity.hpp | 61 + include/luabind/detail/call.hpp | 214 + include/luabind/detail/call_function.hpp | 443 + include/luabind/detail/call_member.hpp | 362 + include/luabind/detail/call_operator_iterate.hpp | 66 + include/luabind/detail/class_cache.hpp | 89 + include/luabind/detail/class_registry.hpp | 99 + include/luabind/detail/class_rep.hpp | 384 + include/luabind/detail/compute_score.hpp | 106 + include/luabind/detail/construct_rep.hpp | 86 + include/luabind/detail/constructor.hpp | 111 + include/luabind/detail/conversion_storage.hpp | 41 + include/luabind/detail/convert_to_lua.hpp | 92 + include/luabind/detail/debug.hpp | 55 + include/luabind/detail/decorate_type.hpp | 266 + include/luabind/detail/deduce_signature.hpp | 118 + include/luabind/detail/enum_maker.hpp | 122 + include/luabind/detail/find_best_match.hpp | 59 + include/luabind/detail/format_signature.hpp | 136 + include/luabind/detail/garbage_collector.hpp | 53 + include/luabind/detail/get_overload_signature.hpp | 54 + include/luabind/detail/get_signature.hpp | 215 + include/luabind/detail/has_get_pointer.hpp | 107 + include/luabind/detail/implicit_cast.hpp | 51 + include/luabind/detail/is_indirect_const.hpp | 70 + include/luabind/detail/link_compatibility.hpp | 60 + include/luabind/detail/most_derived.hpp | 44 + include/luabind/detail/object_call.hpp | 52 + include/luabind/detail/object_funs.hpp | 224 + include/luabind/detail/object_rep.hpp | 131 + include/luabind/detail/open.hpp | 45 + include/luabind/detail/operator_id.hpp | 79 + include/luabind/detail/other.hpp | 119 + include/luabind/detail/overload_rep.hpp | 141 + include/luabind/detail/overload_rep_base.hpp | 81 + include/luabind/detail/pcall.hpp | 36 + include/luabind/detail/pointee_sizeof.hpp | 54 + include/luabind/detail/pointee_typeid.hpp | 39 + include/luabind/detail/policy.hpp | 1069 ++ include/luabind/detail/primitives.hpp | 85 + include/luabind/detail/property.hpp | 33 + include/luabind/detail/ref.hpp | 128 + include/luabind/detail/signature_match.hpp | 90 + include/luabind/detail/stack_utils.hpp | 52 + include/luabind/detail/typetraits.hpp | 190 + include/luabind/detail/yes_no.hpp | 34 + include/luabind/discard_result_policy.hpp | 72 + include/luabind/error.hpp | 92 + include/luabind/exception_handler.hpp | 110 + include/luabind/from_stack.hpp | 42 + include/luabind/function.hpp | 62 + include/luabind/get_pointer.hpp | 39 + include/luabind/handle.hpp | 136 + include/luabind/iterator_policy.hpp | 113 + include/luabind/lua_include.hpp | 30 + include/luabind/luabind.hpp | 32 + include/luabind/make_function.hpp | 91 + include/luabind/nil.hpp | 40 + include/luabind/object.hpp | 1377 ++ include/luabind/open.hpp | 36 + include/luabind/operator.hpp | 355 + include/luabind/out_value_policy.hpp | 270 + include/luabind/prefix.hpp | 31 + include/luabind/raw_policy.hpp | 80 + include/luabind/return_reference_to_policy.hpp | 73 + include/luabind/scope.hpp | 101 + include/luabind/tag_function.hpp | 87 + include/luabind/value_wrapper.hpp | 168 + include/luabind/weak_ref.hpp | 59 + include/luabind/wrapper_base.hpp | 188 + include/luabind/yield_policy.hpp | 67 + include/math/math.h | 329 + include/math/matrix.h | 810 ++ include/math/quaternion.h | 401 + include/math/transform.h | 327 + include/math/vector.h | 954 ++ include/math/volumes.h | 268 + include/mem_off.h | 62 + include/mem_on.h | 50 + include/memory/init_mmgr.cpp | 55 + include/memory/mmgr.h | 149 + include/old-mem_off.h | 38 + include/old-mem_on.h | 38 + include/platform.h | 149 + include/renderer/buffers.h | 201 + include/renderer/canvas.h | 70 + include/renderer/effect.h | 134 + include/renderer/renderer.h | 121 + include/renderer/texture.h | 125 + include/stdtypes.h | 58 + include/types.h | 71 + include/utf8.h | 34 + include/utf8/checked.h | 318 + include/utf8/core.h | 259 + include/utf8/unchecked.h | 228 + include/vfs/console.h | 72 + include/vfs/export.h | 143 + include/vfs/fstream.h | 109 + include/vfs/init_io.cpp | 36 + include/vfs/init_logger.cpp | 38 + include/vfs/interface.h | 197 + include/vfs/logfile.h | 165 + include/vfs/operators.h | 60 + include/vfs/vario.h | 50 + include/xml/tinyxml.h | 1802 +++ include/xml/xmlutils.h | 49 + projects/CMakeLists.txt | 18 + projects/lib-core/CMakeLists.txt | 42 + projects/lib-font/CMakeLists.txt | 44 + projects/lib-gui/CMakeLists.txt | 54 + projects/lib-input/CMakeLists.txt | 31 + projects/lib-lua/CMakeLists.txt | 116 + projects/lib-math/CMakeLists.txt | 41 + projects/lib-memory/CMakeLists.txt | 47 + projects/lib-renderer/CMakeLists.txt | 70 + projects/lib-tinyxml/CMakeLists.txt | 38 + projects/lib-vfs/CMakeLists.txt | 59 + projects/luac/CMakeLists.txt | 91 + projects/luac/luac.cpp | 200 + projects/luac/print.cpp | 227 + projects/luac/vfs_wrapper.cpp | 83 + projects/terra-client/CMakeLists.txt | 60 + projects/terra-server/CMakeLists.txt | 146 + src/client/client.cpp | 137 + src/client/client.h | 48 + src/client/conf_client.cpp | 64 + src/client/conf_client.h | 33 + src/client/main.cpp | 130 + src/client/script_client.cpp | 126 + src/client/script_client.h | 41 + src/client/static.cpp | 40 + src/core/application.cpp | 42 + src/core/client/display.cpp | 135 + src/core/conf_core.cpp | 52 + src/core/script_core.cpp | 94 + src/core/timer.cpp | 108 + src/core/vmachine.cpp | 233 + src/gui/basic.cpp | 746 ++ src/gui/cursor.cpp | 237 + src/gui/cursor.h | 113 + src/gui/font/font.cpp | 169 + src/gui/font/freetype.cpp | 396 + src/gui/font/freetype.h | 136 + src/gui/gui.cpp | 363 + src/gui/pixmap.cpp | 355 + src/gui/plaintext.cpp | 196 + src/gui/richtext.cpp | 1143 ++ src/gui/skin.cpp | 228 + src/gui/skin.h | 122 + src/gui/text.cpp | 271 + src/gui/widget.cpp | 484 + src/input/input.cpp | 498 + src/lua/lapi.cpp | 1087 ++ src/lua/lapi.h | 16 + src/lua/lauxlib.cpp | 653 + src/lua/lbaselib.cpp | 655 + src/lua/lcode.cpp | 839 ++ src/lua/lcode.h | 76 + src/lua/ldblib.cpp | 398 + src/lua/ldebug.cpp | 638 + src/lua/ldebug.h | 33 + src/lua/ldo.cpp | 518 + src/lua/ldo.h | 57 + src/lua/ldump.cpp | 164 + src/lua/lfunc.cpp | 174 + src/lua/lfunc.h | 34 + src/lua/lgc.cpp | 711 + src/lua/lgc.h | 110 + src/lua/linit.cpp | 38 + src/lua/liolib.cpp | 559 + src/lua/llex.cpp | 461 + src/lua/llex.h | 81 + src/lua/llimits.h | 128 + src/lua/lmathlib.cpp | 263 + src/lua/lmem.cpp | 86 + src/lua/lmem.h | 48 + src/lua/loadlib.cpp | 666 + src/lua/lobject.cpp | 217 + src/lua/lobject.h | 381 + src/lua/lopcodes.cpp | 102 + src/lua/lopcodes.h | 268 + src/lua/loslib.cpp | 247 + src/lua/lparser.cpp | 1339 ++ src/lua/lparser.h | 82 + src/lua/lstate.cpp | 214 + src/lua/lstate.h | 169 + src/lua/lstring.cpp | 111 + src/lua/lstring.h | 31 + src/lua/lstrlib.cpp | 874 ++ src/lua/ltable.cpp | 588 + src/lua/ltable.h | 40 + src/lua/ltablib.cpp | 287 + src/lua/ltm.cpp | 75 + src/lua/ltm.h | 54 + src/lua/lundump.cpp | 227 + src/lua/lundump.h | 36 + src/lua/lvm.cpp | 764 ++ src/lua/lvm.h | 36 + src/lua/lzio.cpp | 82 + src/lua/lzio.h | 67 + src/luabind/class.cpp | 424 + src/luabind/class_info.cpp | 76 + src/luabind/class_registry.cpp | 240 + src/luabind/class_rep.cpp | 818 ++ src/luabind/create_class.cpp | 142 + src/luabind/error.cpp | 76 + src/luabind/exception_handler.cpp | 84 + src/luabind/find_best_match.cpp | 83 + src/luabind/function.cpp | 211 + src/luabind/implicit_cast.cpp | 62 + src/luabind/link_compatibility.cpp | 41 + src/luabind/object_rep.cpp | 112 + src/luabind/open.cpp | 94 + src/luabind/overload_rep.cpp | 37 + src/luabind/pcall.cpp | 58 + src/luabind/ref.cpp | 176 + src/luabind/scope.cpp | 199 + src/luabind/stack_content_by_name.cpp | 57 + src/luabind/weak_ref.cpp | 203 + src/luabind/wrapper_base.cpp | 53 + src/math/volumes.cpp | 1134 ++ src/memory/mmgr.cpp | 1496 +++ src/renderer/cg_effect.cpp | 405 + src/renderer/cg_effect.h | 100 + src/renderer/cg_renderer.cpp | 501 + src/renderer/cg_renderer.h | 87 + src/renderer/gl_buffers.cpp | 515 + src/renderer/gl_buffers.h | 120 + src/renderer/gl_canvas.cpp | 116 + src/renderer/gl_canvas.h | 47 + src/renderer/gl_texture.cpp | 403 + src/renderer/gl_texture.h | 64 + src/renderer/image_dds.cpp | 865 ++ src/renderer/image_dds.h | 82 + src/renderer/image_tga.cpp | 265 + src/renderer/image_tga.h | 53 + src/server/main.cpp | 95 + src/vfs/console.cpp | 94 + src/vfs/diskfile.cpp | 614 + src/vfs/diskfile.h | 126 + src/vfs/export.cpp | 788 ++ src/vfs/fstream.cpp | 266 + src/vfs/interface.cpp | 441 + src/vfs/logfile.cpp | 284 + src/vfs/operators.cpp | 53 + src/vfs/vario.cpp | 1375 ++ src/vfs/zipfile.cpp | 30 + src/vfs/zipfile.h | 47 + src/xml/tinyxml.cpp | 1888 +++ src/xml/tinyxmlerror.cpp | 53 + src/xml/tinyxmlparser.cpp | 1638 +++ src/xml/xmlutils.cpp | 146 + 354 files changed, 80620 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 Doxyfile create mode 100644 LICENSE create mode 100644 TODO.txt create mode 100644 config/client.xml create mode 100644 data-client/effects/fnt_texture.cgfx create mode 100644 data-client/effects/gui_texture.cgfx create mode 100644 data-client/fonts/dejavu-mono.xml create mode 100644 data-client/fonts/dejavu-sans-condensed.xml create mode 100644 data-client/fonts/dejavu-sans.xml create mode 100644 data-client/fonts/dejavu-serif-condensed.xml create mode 100644 data-client/fonts/dejavu-serif.xml create mode 100644 data-client/fonts/gputeks.xml create mode 100644 data-client/fonts/liberation-mono.xml create mode 100644 data-client/fonts/liberation-sans.xml create mode 100644 data-client/fonts/liberation-serif.xml create mode 100644 data-client/fonts/misc/7monkey.xml create mode 100644 data-client/fonts/misc/7swordsmen.xml create mode 100644 data-client/fonts/misc/anglican.xml create mode 100644 data-client/fonts/misc/bettynoir.xml create mode 100644 data-client/fonts/misc/bottlerocket.xml create mode 100644 data-client/fonts/misc/caeldera.xml create mode 100644 data-client/fonts/misc/catholic.xml create mode 100644 data-client/fonts/misc/chopin.xml create mode 100644 data-client/fonts/misc/decrepit.xml create mode 100644 data-client/fonts/misc/deutsch.xml create mode 100644 data-client/fonts/misc/dragonfly.xml create mode 100644 data-client/fonts/misc/gessele.xml create mode 100644 data-client/fonts/misc/gorilla.xml create mode 100644 data-client/fonts/misc/lexia.xml create mode 100644 data-client/fonts/misc/marspolice.xml create mode 100644 data-client/fonts/misc/maxhand.xml create mode 100644 data-client/fonts/misc/mccoy.xml create mode 100644 data-client/fonts/misc/nasalization.xml create mode 100644 data-client/fonts/misc/neuropolitical.xml create mode 100644 data-client/fonts/misc/oldgermen.xml create mode 100644 data-client/fonts/misc/paternoster.xml create mode 100644 data-client/fonts/misc/prefix.xml create mode 100644 data-client/fonts/misc/radio-condensed.xml create mode 100644 data-client/fonts/misc/radio.xml create mode 100644 data-client/fonts/misc/randi.xml create mode 100644 data-client/fonts/misc/spaceage.xml create mode 100644 data-client/fonts/misc/spacedock.xml create mode 100644 data-client/fonts/misc/spirit.xml create mode 100644 data-client/fonts/misc/subamera.xml create mode 100644 data-client/fonts/misc/toolate.xml create mode 100644 data-client/fonts/misc/typewriter.xml create mode 100644 data-client/fonts/misc/typicalwriter.xml create mode 100644 data-client/fonts/misc/venus.xml create mode 100644 data-client/fonts/misc/vibrocentric.xml create mode 100644 data-client/fonts/misc/village.xml create mode 100644 data-client/fonts/misc/virginie.xml create mode 100644 data-client/fonts/misc/walrod.xml create mode 100644 data-client/fonts/misc/warmonger.xml create mode 100644 data-client/fonts/misc/zirkon.xml create mode 100644 data-client/gui/cursors/co-green.xml create mode 100644 data-client/gui/main.xml create mode 100644 data-client/gui/skin/skulpture.xml create mode 100644 data-client/gui/widgets/main-console.xml create mode 100644 data-client/gui/widgets/main-normal.xml create mode 100644 data-client/gui/widgets/main-perc.xml create mode 100644 data-client/gui/widgets/main-wdgs.xml create mode 100644 data-client/gui/widgets/splash.xml create mode 100644 data-client/gui/widgets/test.xml create mode 100644 data-client/script/init.lua create mode 100644 data-server/script/init.lua create mode 100644 data-shared/models/fighter.x create mode 100644 include/assertion.h create mode 100644 include/common.h create mode 100644 include/config.h create mode 100644 include/core/application.h create mode 100644 include/core/client/display.h create mode 100644 include/core/conf_core.h create mode 100644 include/core/init_sdl.cpp create mode 100644 include/core/script_core.h create mode 100644 include/core/timer.h create mode 100644 include/core/vmachine.h create mode 100644 include/cpair.h create mode 100644 include/exception.h create mode 100644 include/gui/basic.h create mode 100644 include/gui/font/font.h create mode 100644 include/gui/gui.h create mode 100644 include/gui/init_basic.cpp create mode 100644 include/gui/pixmap.h create mode 100644 include/gui/plaintext.h create mode 100644 include/gui/richtext.h create mode 100644 include/gui/text.h create mode 100644 include/gui/widget.h create mode 100644 include/input/input.h create mode 100644 include/lua/lauxlib.h create mode 100644 include/lua/lua.h create mode 100644 include/lua/luaconf.h create mode 100644 include/lua/lualib.h create mode 100644 include/luabind/adopt_policy.hpp create mode 100755 include/luabind/back_reference.hpp create mode 100755 include/luabind/back_reference_fwd.hpp create mode 100644 include/luabind/class.hpp create mode 100755 include/luabind/class_info.hpp create mode 100644 include/luabind/config.hpp create mode 100644 include/luabind/container_policy.hpp create mode 100644 include/luabind/copy_policy.hpp create mode 100644 include/luabind/dependency_policy.hpp create mode 100644 include/luabind/detail/calc_arity.hpp create mode 100644 include/luabind/detail/call.hpp create mode 100644 include/luabind/detail/call_function.hpp create mode 100644 include/luabind/detail/call_member.hpp create mode 100755 include/luabind/detail/call_operator_iterate.hpp create mode 100755 include/luabind/detail/class_cache.hpp create mode 100644 include/luabind/detail/class_registry.hpp create mode 100644 include/luabind/detail/class_rep.hpp create mode 100644 include/luabind/detail/compute_score.hpp create mode 100644 include/luabind/detail/construct_rep.hpp create mode 100644 include/luabind/detail/constructor.hpp create mode 100644 include/luabind/detail/conversion_storage.hpp create mode 100644 include/luabind/detail/convert_to_lua.hpp create mode 100755 include/luabind/detail/debug.hpp create mode 100644 include/luabind/detail/decorate_type.hpp create mode 100644 include/luabind/detail/deduce_signature.hpp create mode 100644 include/luabind/detail/enum_maker.hpp create mode 100644 include/luabind/detail/find_best_match.hpp create mode 100644 include/luabind/detail/format_signature.hpp create mode 100644 include/luabind/detail/garbage_collector.hpp create mode 100644 include/luabind/detail/get_overload_signature.hpp create mode 100644 include/luabind/detail/get_signature.hpp create mode 100755 include/luabind/detail/has_get_pointer.hpp create mode 100644 include/luabind/detail/implicit_cast.hpp create mode 100755 include/luabind/detail/is_indirect_const.hpp create mode 100755 include/luabind/detail/link_compatibility.hpp create mode 100755 include/luabind/detail/most_derived.hpp create mode 100755 include/luabind/detail/object_call.hpp create mode 100644 include/luabind/detail/object_funs.hpp create mode 100644 include/luabind/detail/object_rep.hpp create mode 100644 include/luabind/detail/open.hpp create mode 100644 include/luabind/detail/operator_id.hpp create mode 100644 include/luabind/detail/other.hpp create mode 100644 include/luabind/detail/overload_rep.hpp create mode 100644 include/luabind/detail/overload_rep_base.hpp create mode 100755 include/luabind/detail/pcall.hpp create mode 100755 include/luabind/detail/pointee_sizeof.hpp create mode 100755 include/luabind/detail/pointee_typeid.hpp create mode 100644 include/luabind/detail/policy.hpp create mode 100644 include/luabind/detail/primitives.hpp create mode 100644 include/luabind/detail/property.hpp create mode 100644 include/luabind/detail/ref.hpp create mode 100644 include/luabind/detail/signature_match.hpp create mode 100755 include/luabind/detail/stack_utils.hpp create mode 100644 include/luabind/detail/typetraits.hpp create mode 100755 include/luabind/detail/yes_no.hpp create mode 100644 include/luabind/discard_result_policy.hpp create mode 100755 include/luabind/error.hpp create mode 100644 include/luabind/exception_handler.hpp create mode 100755 include/luabind/from_stack.hpp create mode 100644 include/luabind/function.hpp create mode 100755 include/luabind/get_pointer.hpp create mode 100755 include/luabind/handle.hpp create mode 100755 include/luabind/iterator_policy.hpp create mode 100755 include/luabind/lua_include.hpp create mode 100644 include/luabind/luabind.hpp create mode 100644 include/luabind/make_function.hpp create mode 100644 include/luabind/nil.hpp create mode 100644 include/luabind/object.hpp create mode 100755 include/luabind/open.hpp create mode 100755 include/luabind/operator.hpp create mode 100644 include/luabind/out_value_policy.hpp create mode 100755 include/luabind/prefix.hpp create mode 100755 include/luabind/raw_policy.hpp create mode 100644 include/luabind/return_reference_to_policy.hpp create mode 100755 include/luabind/scope.hpp create mode 100644 include/luabind/tag_function.hpp create mode 100755 include/luabind/value_wrapper.hpp create mode 100755 include/luabind/weak_ref.hpp create mode 100755 include/luabind/wrapper_base.hpp create mode 100755 include/luabind/yield_policy.hpp create mode 100644 include/math/math.h create mode 100644 include/math/matrix.h create mode 100644 include/math/quaternion.h create mode 100644 include/math/transform.h create mode 100644 include/math/vector.h create mode 100644 include/math/volumes.h create mode 100644 include/mem_off.h create mode 100644 include/mem_on.h create mode 100644 include/memory/init_mmgr.cpp create mode 100644 include/memory/mmgr.h create mode 100644 include/old-mem_off.h create mode 100644 include/old-mem_on.h create mode 100644 include/platform.h create mode 100644 include/renderer/buffers.h create mode 100644 include/renderer/canvas.h create mode 100644 include/renderer/effect.h create mode 100644 include/renderer/renderer.h create mode 100644 include/renderer/texture.h create mode 100644 include/stdtypes.h create mode 100644 include/types.h create mode 100644 include/utf8.h create mode 100644 include/utf8/checked.h create mode 100644 include/utf8/core.h create mode 100644 include/utf8/unchecked.h create mode 100644 include/vfs/console.h create mode 100644 include/vfs/export.h create mode 100644 include/vfs/fstream.h create mode 100644 include/vfs/init_io.cpp create mode 100644 include/vfs/init_logger.cpp create mode 100644 include/vfs/interface.h create mode 100644 include/vfs/logfile.h create mode 100644 include/vfs/operators.h create mode 100644 include/vfs/vario.h create mode 100644 include/xml/tinyxml.h create mode 100644 include/xml/xmlutils.h create mode 100644 projects/CMakeLists.txt create mode 100644 projects/lib-core/CMakeLists.txt create mode 100644 projects/lib-font/CMakeLists.txt create mode 100644 projects/lib-gui/CMakeLists.txt create mode 100644 projects/lib-input/CMakeLists.txt create mode 100644 projects/lib-lua/CMakeLists.txt create mode 100644 projects/lib-math/CMakeLists.txt create mode 100644 projects/lib-memory/CMakeLists.txt create mode 100644 projects/lib-renderer/CMakeLists.txt create mode 100644 projects/lib-tinyxml/CMakeLists.txt create mode 100644 projects/lib-vfs/CMakeLists.txt create mode 100644 projects/luac/CMakeLists.txt create mode 100644 projects/luac/luac.cpp create mode 100644 projects/luac/print.cpp create mode 100755 projects/luac/vfs_wrapper.cpp create mode 100644 projects/terra-client/CMakeLists.txt create mode 100755 projects/terra-server/CMakeLists.txt create mode 100644 src/client/client.cpp create mode 100644 src/client/client.h create mode 100644 src/client/conf_client.cpp create mode 100644 src/client/conf_client.h create mode 100644 src/client/main.cpp create mode 100644 src/client/script_client.cpp create mode 100644 src/client/script_client.h create mode 100644 src/client/static.cpp create mode 100644 src/core/application.cpp create mode 100644 src/core/client/display.cpp create mode 100644 src/core/conf_core.cpp create mode 100644 src/core/script_core.cpp create mode 100644 src/core/timer.cpp create mode 100644 src/core/vmachine.cpp create mode 100644 src/gui/basic.cpp create mode 100644 src/gui/cursor.cpp create mode 100644 src/gui/cursor.h create mode 100644 src/gui/font/font.cpp create mode 100644 src/gui/font/freetype.cpp create mode 100644 src/gui/font/freetype.h create mode 100644 src/gui/gui.cpp create mode 100644 src/gui/pixmap.cpp create mode 100644 src/gui/plaintext.cpp create mode 100644 src/gui/richtext.cpp create mode 100644 src/gui/skin.cpp create mode 100644 src/gui/skin.h create mode 100644 src/gui/text.cpp create mode 100644 src/gui/widget.cpp create mode 100644 src/input/input.cpp create mode 100644 src/lua/lapi.cpp create mode 100644 src/lua/lapi.h create mode 100644 src/lua/lauxlib.cpp create mode 100644 src/lua/lbaselib.cpp create mode 100644 src/lua/lcode.cpp create mode 100644 src/lua/lcode.h create mode 100644 src/lua/ldblib.cpp create mode 100644 src/lua/ldebug.cpp create mode 100644 src/lua/ldebug.h create mode 100644 src/lua/ldo.cpp create mode 100644 src/lua/ldo.h create mode 100644 src/lua/ldump.cpp create mode 100644 src/lua/lfunc.cpp create mode 100644 src/lua/lfunc.h create mode 100644 src/lua/lgc.cpp create mode 100644 src/lua/lgc.h create mode 100644 src/lua/linit.cpp create mode 100644 src/lua/liolib.cpp create mode 100644 src/lua/llex.cpp create mode 100644 src/lua/llex.h create mode 100644 src/lua/llimits.h create mode 100644 src/lua/lmathlib.cpp create mode 100644 src/lua/lmem.cpp create mode 100644 src/lua/lmem.h create mode 100644 src/lua/loadlib.cpp create mode 100644 src/lua/lobject.cpp create mode 100644 src/lua/lobject.h create mode 100644 src/lua/lopcodes.cpp create mode 100644 src/lua/lopcodes.h create mode 100644 src/lua/loslib.cpp create mode 100644 src/lua/lparser.cpp create mode 100644 src/lua/lparser.h create mode 100644 src/lua/lstate.cpp create mode 100644 src/lua/lstate.h create mode 100644 src/lua/lstring.cpp create mode 100644 src/lua/lstring.h create mode 100644 src/lua/lstrlib.cpp create mode 100644 src/lua/ltable.cpp create mode 100644 src/lua/ltable.h create mode 100644 src/lua/ltablib.cpp create mode 100644 src/lua/ltm.cpp create mode 100644 src/lua/ltm.h create mode 100644 src/lua/lundump.cpp create mode 100644 src/lua/lundump.h create mode 100644 src/lua/lvm.cpp create mode 100644 src/lua/lvm.h create mode 100644 src/lua/lzio.cpp create mode 100644 src/lua/lzio.h create mode 100755 src/luabind/class.cpp create mode 100755 src/luabind/class_info.cpp create mode 100755 src/luabind/class_registry.cpp create mode 100755 src/luabind/class_rep.cpp create mode 100755 src/luabind/create_class.cpp create mode 100755 src/luabind/error.cpp create mode 100644 src/luabind/exception_handler.cpp create mode 100755 src/luabind/find_best_match.cpp create mode 100644 src/luabind/function.cpp create mode 100755 src/luabind/implicit_cast.cpp create mode 100755 src/luabind/link_compatibility.cpp create mode 100755 src/luabind/object_rep.cpp create mode 100755 src/luabind/open.cpp create mode 100644 src/luabind/overload_rep.cpp create mode 100755 src/luabind/pcall.cpp create mode 100755 src/luabind/ref.cpp create mode 100755 src/luabind/scope.cpp create mode 100755 src/luabind/stack_content_by_name.cpp create mode 100755 src/luabind/weak_ref.cpp create mode 100755 src/luabind/wrapper_base.cpp create mode 100644 src/math/volumes.cpp create mode 100644 src/memory/mmgr.cpp create mode 100644 src/renderer/cg_effect.cpp create mode 100644 src/renderer/cg_effect.h create mode 100644 src/renderer/cg_renderer.cpp create mode 100644 src/renderer/cg_renderer.h create mode 100644 src/renderer/gl_buffers.cpp create mode 100644 src/renderer/gl_buffers.h create mode 100644 src/renderer/gl_canvas.cpp create mode 100644 src/renderer/gl_canvas.h create mode 100644 src/renderer/gl_texture.cpp create mode 100644 src/renderer/gl_texture.h create mode 100644 src/renderer/image_dds.cpp create mode 100644 src/renderer/image_dds.h create mode 100644 src/renderer/image_tga.cpp create mode 100644 src/renderer/image_tga.h create mode 100644 src/server/main.cpp create mode 100644 src/vfs/console.cpp create mode 100644 src/vfs/diskfile.cpp create mode 100644 src/vfs/diskfile.h create mode 100644 src/vfs/export.cpp create mode 100644 src/vfs/fstream.cpp create mode 100644 src/vfs/interface.cpp create mode 100644 src/vfs/logfile.cpp create mode 100644 src/vfs/operators.cpp create mode 100644 src/vfs/vario.cpp create mode 100644 src/vfs/zipfile.cpp create mode 100644 src/vfs/zipfile.h create mode 100644 src/xml/tinyxml.cpp create mode 100644 src/xml/tinyxmlerror.cpp create mode 100644 src/xml/tinyxmlparser.cpp create mode 100644 src/xml/xmlutils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d999779 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,5 @@ +project(terrastrategy) + +cmake_minimum_required(VERSION 2.6) + +add_subdirectory(projects) diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..fbcc153 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,316 @@ +# Doxyfile 1.5.5-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = terrastrategy +PROJECT_NUMBER = 0.1 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/martin/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +BUILTIN_STL_SUPPORT = YES +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = src/client src/core src/core/client src/gui \ + src/gui/font src/input src/math src/memory \ + src/renderer src/server src/vfs src/xml/xmlutils.cpp \ + include include/core include/core/client include/gui \ + include/input include/math include/memory \ + include/renderer include/vfs include/xml/xmlutils.h +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY \ + *.F90 \ + *.F \ + *.VHD \ + *.VHDL \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = no +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NONE +TREEVIEW_WIDTH = 250 +FORMULA_FONTSIZE = 10 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = terrastrategy.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_FONTNAME = FreeSans +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..77068b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,333 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..1e4e1af --- /dev/null +++ b/TODO.txt @@ -0,0 +1,172 @@ +Actual TODO: +~~~~~~~~~~~~ + +-registrace trid widgetu +-poresit widget - roztahovani a tak, je to nejake nedotazene + +-jednoduche test menu s vypisovanim debug informaci + +-edit widgety +-LOG_RESOURCE ujednotit + +-per frame statistics - dodelat + +-client rect - nastaveni orezavaciho regionu widgetu +-overlay widget - obdelnikovy widget pro ruzne vizualni efekty +-image widget? nebo take overlay? + +-dodelat texturovou tridu - rozmslet, co s cube mapami a 3d texturami + +-zacit smolit scenu +-RenderWidget + +-COLLADA import + +-NACPAT VSUDE SPRAVNE config.h a types.h, ci stltypes.h + az v ramci cisteni kodu +-common.h + +-pro retezcove konstanty pouzit const char * a ne std::string (jako parametry fci) + +-renderer - const iteratory? +-nastavovani bufferu, take pres iteratory + +-zmenit nazvy souboru (interface.cpp -> vfs.cpp) a opravit doxygen hlavicky +--------------------------------------------------------------------------- + +-widget constraints +-widget factory by si mela pri vytvareni widgetu zkontrolovat hloubku zanoreni + -treba jen v debug rezimu + +-scroll bar, progress bar + +-animated texture - xml + -one or more textures with one or more frames + -texture coordinates are adjusted using texture matrix + +-pruchod a inicializace activated eventu? + +-EXT_draw_instanced extension +-EXT_bindable_uniform +-ARB_occlusion_query + +-aserce -> ASSERT, CHECK, REQUIRE +-pos vs. itr + +----------------------------------------------------------- + +-pojmenovavani scen (application si udrzuje mapu) + +Future features: +~~~~~~~~~~~~~~~ +-streamable content + +Most important tasks: +~~~~~~~~~~~~~~~~~~~~~ +-urcit smer svetla podobne jako Opengl? (x, y, z, 0) + +-proceduralne generovana scena: sablona nactena z xml, spusten jeji init skript, + ktery ji naplni (napr.) skript si pripravi data, ktera se pomoci deep copy + prekopiruji do sceny + +-cascaded shadow maps? devmaster.net article +-staticke/dynamicke objekty? +-svetla z textur, nebo alespon svitive textury (svetylka lodi) + -nebo emissive textury (nutnost pro kosmicke lode :)) + +-picking vs. ray casting - vyber jestli chce vybirat i transparentni objekty, nebo ne + mozna jeste flag selectable, aby se nevybiraly sprity, triggery apod. + -select group - bitove skupiny pro vyber (takze max 32) + +-vlastnost light importance - objekt neni osvetlen svetly s nizsi/vyssi dulezitosti +-static flag - objekt ma fixni geometrii a muzee se podle toho k nemu chovat + +-adapt SOIL library for image reader/writers + +=========================================== + +-upravit hlavicky souboru - copyrighty!! +-decals budou obecne meshe promitle na model (tj. klidne i special) + +Big TODO areas: +~~~~~~~~~~~~~~~ + +o Renderer + -shadows + -hdr + bloom + -animation, skinning + -changing videomode + -ubershader for global lights? + -decals + -particles (PhysX?) + -LOD (progressive meshes) + +o Scripting + -parallelism support + -random number generator + +o GUI + -stin textu + +o Networking + -event serialization + -sender/receiver? + +o Audio + -OpenAL module + -sound + -music + +o Vfs + -support for zip and other archives + -colour printing - manipulators and sprintf + -vfs_export - removed unused functions, rename to vfs_lwrapper + +o Physics + -support for the PhysX toolkit or other middleware + +o Ai + +o Input + -switch to OIS (libois-dev) + -tag for key events to mark whether it's meta key or not + -uppercase/lowercase? or conversion function, maybe return just keysyms + and export transform function to script (keysym + keymod -> chr/utf8) + -watch out for international keyboards? + -utf8 + +o Polishing + -write documentation - when codebase is stable + +o Possible parallelisation + -frustum culling - "search" mapping + -getting effective lights of models + -for each model get lights that influence it + -cpu skinning (at least bbox skinning) + -rendering in separate thread? + -audio thread + -networking thread + +o Copyright issues + -Lua + -TinyXML + -Freetype2 - linked + -Freetype autohinter - catharon licence + ?Cg + -fonts, cursors, skins + +Other stuff: +~~~~~~~~~~~~ + +Possible optimizations: +~~~~~~~~~~~~~~~~~~~~~~~ +-vectors - data alignment,templates +-built-in profiler + +---------------------------------- +Little benchamrking: +~~~~~~~~~~~~~~~~~~~ +Most efficient way of filling buffers: +-Lock with amReadWrite/amWrite - rendering? +-Set +-Lock with amRead diff --git a/config/client.xml b/config/client.xml new file mode 100644 index 0000000..aba0a5c --- /dev/null +++ b/config/client.xml @@ -0,0 +1,17 @@ + + + + + + + + + + 1280 + 1024 + 32 + + + + + diff --git a/data-client/effects/fnt_texture.cgfx b/data-client/effects/fnt_texture.cgfx new file mode 100644 index 0000000..74bf0e0 --- /dev/null +++ b/data-client/effects/fnt_texture.cgfx @@ -0,0 +1,47 @@ +/* + * Pixmap gui effect + */ + +struct VS_OUTPUT { + float4 vPosition : POSITION; + float2 vTexCoords : TEXCOORD0; + float4 vColour : COLOR; +}; + +VS_OUTPUT myvs(uniform float4x4 ModelViewProj, float4 vPosition : POSITION, float4 vColor : COLOR, float2 vTexCoords : TEXCOORD0) +{ + VS_OUTPUT vout; + + vout.vTexCoords = vTexCoords; + vout.vPosition = mul(glstate.matrix.mvp, vPosition); + vout.vColour = vColor; + + return vout; +} + +float4 myfs(float2 vTexCoords : TEXCOORD0, float4 vColor : COLOR, uniform sampler2D tex) : COLOR +{ + float4 col = tex2D(tex, vTexCoords); + return col * vColor; +} + +sampler2D fnt_Texture = sampler_state { + minFilter = Linear; + magFilter = Linear; +}; + +technique t0 { + pass p0 { + + BlendEnable = true; + BlendFunc = float2(SrcAlpha, OneMinusSrcAlpha); + AlphaTestEnable = true; + AlphaFunc = float2(Greater, 0.0f); + DepthTestEnable = false; +// CullFaceEnable = true; + CullFace = Back; + + VertexShader = compile arbvp1 myvs(glstate.matrix.mvp); + PixelShader = compile fp40 myfs(fnt_Texture); + } +} diff --git a/data-client/effects/gui_texture.cgfx b/data-client/effects/gui_texture.cgfx new file mode 100644 index 0000000..48adc6d --- /dev/null +++ b/data-client/effects/gui_texture.cgfx @@ -0,0 +1,48 @@ +/* + * Pixmap gui effect + */ + +struct VS_INPUT { + float4 vPosition : POSITION; +}; + +struct VS_OUTPUT { + float4 vPosition : POSITION; + float2 vTexCoords : TEXCOORD0; +}; + +VS_OUTPUT myvs(uniform float4x4 ModelViewProj, float4 vPosition : POSITION, float2 vTexCoords : TEXCOORD0) +{ + VS_OUTPUT vout; + + vout.vTexCoords = vTexCoords; + vout.vPosition = mul(glstate.matrix.mvp, vPosition); + + return vout; +} + +float4 myfs(float2 vTexCoords : TEXCOORD0, uniform sampler2D tex) : COLOR +{ + float4 col = tex2D(tex, vTexCoords); + return col; +} + +//float4x4 mvp : ModelViewProjection /**/; + +sampler2D gui_Texture; + +technique t0 { + pass p0 { + + BlendEnable = true; + BlendFunc = float2(SrcAlpha, OneMinusSrcAlpha); + AlphaTestEnable = true; + AlphaFunc = float2(Greater, 0.0f); + DepthTestEnable = false; + CullFaceEnable = true; + CullFace = Back; + + VertexShader = compile arbvp1 myvs(glstate.matrix.mvp); + PixelShader = compile fp40 myfs(gui_Texture); + } +} diff --git a/data-client/fonts/dejavu-mono.xml b/data-client/fonts/dejavu-mono.xml new file mode 100644 index 0000000..e1e9ecd --- /dev/null +++ b/data-client/fonts/dejavu-mono.xml @@ -0,0 +1,7 @@ + + + fonts/dejavu/DejaVuSansMono.ttf + fonts/dejavu/DejaVuSansMono-Bold.ttf + fonts/dejavu/DejaVuSansMono-Oblique.ttf + fonts/dejavu/DejaVuSansMono-BoldOblique.ttf + diff --git a/data-client/fonts/dejavu-sans-condensed.xml b/data-client/fonts/dejavu-sans-condensed.xml new file mode 100644 index 0000000..2a1a0c9 --- /dev/null +++ b/data-client/fonts/dejavu-sans-condensed.xml @@ -0,0 +1,7 @@ + + + fonts/dejavu/DejaVuSansCondensed.ttf + fonts/dejavu/DejaVuSansCondensed-Bold.ttf + fonts/dejavu/DejaVuSansCondensed-BoldOblique.ttf + fonts/dejavu/DejaVuSansCondensed-Oblique.ttf + diff --git a/data-client/fonts/dejavu-sans.xml b/data-client/fonts/dejavu-sans.xml new file mode 100644 index 0000000..c229ff0 --- /dev/null +++ b/data-client/fonts/dejavu-sans.xml @@ -0,0 +1,7 @@ + + + fonts/dejavu/DejaVuSans.ttf + fonts/dejavu/DejaVuSans-Bold.ttf + fonts/dejavu/DejaVuSans-Oblique.ttf + fonts/dejavu/DejaVuSans-BoldOblique.ttf + diff --git a/data-client/fonts/dejavu-serif-condensed.xml b/data-client/fonts/dejavu-serif-condensed.xml new file mode 100644 index 0000000..1889606 --- /dev/null +++ b/data-client/fonts/dejavu-serif-condensed.xml @@ -0,0 +1,7 @@ + + + fonts/dejavu/DejaVuSerifCondensed.ttf + fonts/dejavu/DejaVuSerifCondensed-Bold.ttf + fonts/dejavu/DejaVuSerifCondensed-Italic.ttf + fonts/dejavu/DejaVuSerifCondensed-BoldItalic.ttf + diff --git a/data-client/fonts/dejavu-serif.xml b/data-client/fonts/dejavu-serif.xml new file mode 100644 index 0000000..a2f89cd --- /dev/null +++ b/data-client/fonts/dejavu-serif.xml @@ -0,0 +1,7 @@ + + + fonts/dejavu/DejaVuSerif.ttf + fonts/dejavu/DejaVuSerif-Bold.ttf + fonts/dejavu/DejaVuSerif-Italic.ttf + fonts/dejavu/DejaVuSerif-BoldItalic.ttf + diff --git a/data-client/fonts/gputeks.xml b/data-client/fonts/gputeks.xml new file mode 100644 index 0000000..8ccbb6b --- /dev/null +++ b/data-client/fonts/gputeks.xml @@ -0,0 +1,7 @@ + + + fonts/gputeks/Gputeks-Regular.ttf + fonts/gputeks/Gputeks-Bold.ttf + fonts/gputeks/Gputeks-Regular.ttf + fonts/gputeks/Gputeks-Bold.ttf + diff --git a/data-client/fonts/liberation-mono.xml b/data-client/fonts/liberation-mono.xml new file mode 100644 index 0000000..7135bd1 --- /dev/null +++ b/data-client/fonts/liberation-mono.xml @@ -0,0 +1,7 @@ + + + fonts/liberation/LiberationMono-Regular.ttf + fonts/liberation/LiberationMono-Bold.ttf + fonts/liberation/LiberationMono-Italic.ttf + fonts/liberation/LiberationMono-BoldItalic.ttf + diff --git a/data-client/fonts/liberation-sans.xml b/data-client/fonts/liberation-sans.xml new file mode 100644 index 0000000..765e931 --- /dev/null +++ b/data-client/fonts/liberation-sans.xml @@ -0,0 +1,7 @@ + + + fonts/liberation/LiberationSans-Regular.ttf + fonts/liberation/LiberationSans-Bold.ttf + fonts/liberation/LiberationSans-Italic.ttf + fonts/liberation/LiberationSans-BoldItalic.ttf + diff --git a/data-client/fonts/liberation-serif.xml b/data-client/fonts/liberation-serif.xml new file mode 100644 index 0000000..9ebaa38 --- /dev/null +++ b/data-client/fonts/liberation-serif.xml @@ -0,0 +1,7 @@ + + + fonts/liberation/LiberationSerif-Regular.ttf + fonts/liberation/LiberationSerif-Bold.ttf + fonts/liberation/LiberationSerif-Italic.ttf + fonts/liberation/LiberationSerif-BoldItalic.ttf + diff --git a/data-client/fonts/misc/7monkey.xml b/data-client/fonts/misc/7monkey.xml new file mode 100644 index 0000000..ab45e27 --- /dev/null +++ b/data-client/fonts/misc/7monkey.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/SEVEMFBR.ttf + diff --git a/data-client/fonts/misc/7swordsmen.xml b/data-client/fonts/misc/7swordsmen.xml new file mode 100644 index 0000000..1037d21 --- /dev/null +++ b/data-client/fonts/misc/7swordsmen.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/SEVESBRG.ttf + diff --git a/data-client/fonts/misc/anglican.xml b/data-client/fonts/misc/anglican.xml new file mode 100644 index 0000000..f173318 --- /dev/null +++ b/data-client/fonts/misc/anglican.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/AnglicanText.ttf + diff --git a/data-client/fonts/misc/bettynoir.xml b/data-client/fonts/misc/bettynoir.xml new file mode 100644 index 0000000..27e19de --- /dev/null +++ b/data-client/fonts/misc/bettynoir.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/bettynoir.ttf + diff --git a/data-client/fonts/misc/bottlerocket.xml b/data-client/fonts/misc/bottlerocket.xml new file mode 100644 index 0000000..f066e3d --- /dev/null +++ b/data-client/fonts/misc/bottlerocket.xml @@ -0,0 +1,5 @@ + + + fonts/misc/ttf/BOTTRBRG.ttf + fonts/misc/ttf/BOTTRBB_.ttf + diff --git a/data-client/fonts/misc/caeldera.xml b/data-client/fonts/misc/caeldera.xml new file mode 100644 index 0000000..55f3850 --- /dev/null +++ b/data-client/fonts/misc/caeldera.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/CAELDERA.ttf + diff --git a/data-client/fonts/misc/catholic.xml b/data-client/fonts/misc/catholic.xml new file mode 100644 index 0000000..6942cbe --- /dev/null +++ b/data-client/fonts/misc/catholic.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/CATHSGBR.ttf + diff --git a/data-client/fonts/misc/chopin.xml b/data-client/fonts/misc/chopin.xml new file mode 100644 index 0000000..8cd32ca --- /dev/null +++ b/data-client/fonts/misc/chopin.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/CHOPS___.ttf + diff --git a/data-client/fonts/misc/decrepit.xml b/data-client/fonts/misc/decrepit.xml new file mode 100644 index 0000000..2e36f7b --- /dev/null +++ b/data-client/fonts/misc/decrepit.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/decrepit.ttf + diff --git a/data-client/fonts/misc/deutsch.xml b/data-client/fonts/misc/deutsch.xml new file mode 100644 index 0000000..c258f7f --- /dev/null +++ b/data-client/fonts/misc/deutsch.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Deutsch.ttf + diff --git a/data-client/fonts/misc/dragonfly.xml b/data-client/fonts/misc/dragonfly.xml new file mode 100644 index 0000000..6eee394 --- /dev/null +++ b/data-client/fonts/misc/dragonfly.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Dragonfly.ttf + diff --git a/data-client/fonts/misc/gessele.xml b/data-client/fonts/misc/gessele.xml new file mode 100644 index 0000000..f6c2d6f --- /dev/null +++ b/data-client/fonts/misc/gessele.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/GES_____.ttf + diff --git a/data-client/fonts/misc/gorilla.xml b/data-client/fonts/misc/gorilla.xml new file mode 100644 index 0000000..fd8431e --- /dev/null +++ b/data-client/fonts/misc/gorilla.xml @@ -0,0 +1,5 @@ + + + fonts/misc/ttf/gm.ttf + fonts/misc/ttf/gm_italic.ttf + diff --git a/data-client/fonts/misc/lexia.xml b/data-client/fonts/misc/lexia.xml new file mode 100644 index 0000000..df5d116 --- /dev/null +++ b/data-client/fonts/misc/lexia.xml @@ -0,0 +1,5 @@ + + + fonts/misc/ttf/LEXIA___.ttf + fonts/misc/ttf/LEXIB___.ttf + diff --git a/data-client/fonts/misc/marspolice.xml b/data-client/fonts/misc/marspolice.xml new file mode 100644 index 0000000..8e30fc3 --- /dev/null +++ b/data-client/fonts/misc/marspolice.xml @@ -0,0 +1,5 @@ + + + fonts/misc/ttf/marspolice.ttf + fonts/misc/ttf/marspolice_i.ttf + diff --git a/data-client/fonts/misc/maxhand.xml b/data-client/fonts/misc/maxhand.xml new file mode 100644 index 0000000..bb9dd55 --- /dev/null +++ b/data-client/fonts/misc/maxhand.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Max's_Handwritin.ttf + diff --git a/data-client/fonts/misc/mccoy.xml b/data-client/fonts/misc/mccoy.xml new file mode 100644 index 0000000..598a588 --- /dev/null +++ b/data-client/fonts/misc/mccoy.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/MCCODRG_.ttf + diff --git a/data-client/fonts/misc/nasalization.xml b/data-client/fonts/misc/nasalization.xml new file mode 100644 index 0000000..7276e6c --- /dev/null +++ b/data-client/fonts/misc/nasalization.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/nasaliza.ttf + diff --git a/data-client/fonts/misc/neuropolitical.xml b/data-client/fonts/misc/neuropolitical.xml new file mode 100644 index 0000000..021bdaf --- /dev/null +++ b/data-client/fonts/misc/neuropolitical.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/NEURPOLI.ttf + diff --git a/data-client/fonts/misc/oldgermen.xml b/data-client/fonts/misc/oldgermen.xml new file mode 100644 index 0000000..ca7095e --- /dev/null +++ b/data-client/fonts/misc/oldgermen.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Old_germ.ttf + diff --git a/data-client/fonts/misc/paternoster.xml b/data-client/fonts/misc/paternoster.xml new file mode 100644 index 0000000..27ff85a --- /dev/null +++ b/data-client/fonts/misc/paternoster.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Paternos.ttf + diff --git a/data-client/fonts/misc/prefix.xml b/data-client/fonts/misc/prefix.xml new file mode 100644 index 0000000..056bff3 --- /dev/null +++ b/data-client/fonts/misc/prefix.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/prefix.ttf + diff --git a/data-client/fonts/misc/radio-condensed.xml b/data-client/fonts/misc/radio-condensed.xml new file mode 100644 index 0000000..7c8ccd7 --- /dev/null +++ b/data-client/fonts/misc/radio-condensed.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Radiofc.ttf + diff --git a/data-client/fonts/misc/radio.xml b/data-client/fonts/misc/radio.xml new file mode 100644 index 0000000..e59cda4 --- /dev/null +++ b/data-client/fonts/misc/radio.xml @@ -0,0 +1,7 @@ + + + fonts/misc/ttf/Radiof.ttf + fonts/misc/ttf/Radiofb.ttf + fonts/misc/ttf/Radiofi.ttf + fonts/misc/ttf/Radiofbi.ttf + diff --git a/data-client/fonts/misc/randi.xml b/data-client/fonts/misc/randi.xml new file mode 100644 index 0000000..ed984ec --- /dev/null +++ b/data-client/fonts/misc/randi.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Randi.ttf + diff --git a/data-client/fonts/misc/spaceage.xml b/data-client/fonts/misc/spaceage.xml new file mode 100644 index 0000000..d39a396 --- /dev/null +++ b/data-client/fonts/misc/spaceage.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/space_age.ttf + diff --git a/data-client/fonts/misc/spacedock.xml b/data-client/fonts/misc/spacedock.xml new file mode 100644 index 0000000..daea715 --- /dev/null +++ b/data-client/fonts/misc/spacedock.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Spacedock_Stencil.ttf + diff --git a/data-client/fonts/misc/spirit.xml b/data-client/fonts/misc/spirit.xml new file mode 100644 index 0000000..b6168a8 --- /dev/null +++ b/data-client/fonts/misc/spirit.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/spiritmedium.ttf + diff --git a/data-client/fonts/misc/subamera.xml b/data-client/fonts/misc/subamera.xml new file mode 100644 index 0000000..428c41f --- /dev/null +++ b/data-client/fonts/misc/subamera.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Subamera.ttf + diff --git a/data-client/fonts/misc/toolate.xml b/data-client/fonts/misc/toolate.xml new file mode 100644 index 0000000..e572d0e --- /dev/null +++ b/data-client/fonts/misc/toolate.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Too_Late.ttf + diff --git a/data-client/fonts/misc/typewriter.xml b/data-client/fonts/misc/typewriter.xml new file mode 100644 index 0000000..4cbeba7 --- /dev/null +++ b/data-client/fonts/misc/typewriter.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/TYPENR__.ttf + diff --git a/data-client/fonts/misc/typicalwriter.xml b/data-client/fonts/misc/typicalwriter.xml new file mode 100644 index 0000000..9d01324 --- /dev/null +++ b/data-client/fonts/misc/typicalwriter.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/TYPIW___.ttf + diff --git a/data-client/fonts/misc/venus.xml b/data-client/fonts/misc/venus.xml new file mode 100644 index 0000000..51c1c40 --- /dev/null +++ b/data-client/fonts/misc/venus.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/VENUSRIS.ttf + diff --git a/data-client/fonts/misc/vibrocentric.xml b/data-client/fonts/misc/vibrocentric.xml new file mode 100644 index 0000000..385f1f4 --- /dev/null +++ b/data-client/fonts/misc/vibrocentric.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/VIBROCEN.ttf + diff --git a/data-client/fonts/misc/village.xml b/data-client/fonts/misc/village.xml new file mode 100644 index 0000000..6c1e9be --- /dev/null +++ b/data-client/fonts/misc/village.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/VILLIBRG.ttf + diff --git a/data-client/fonts/misc/virginie.xml b/data-client/fonts/misc/virginie.xml new file mode 100644 index 0000000..b986eb1 --- /dev/null +++ b/data-client/fonts/misc/virginie.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/Virginie.ttf + diff --git a/data-client/fonts/misc/walrod.xml b/data-client/fonts/misc/walrod.xml new file mode 100644 index 0000000..b0d869b --- /dev/null +++ b/data-client/fonts/misc/walrod.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/WALROD__.ttf + diff --git a/data-client/fonts/misc/warmonger.xml b/data-client/fonts/misc/warmonger.xml new file mode 100644 index 0000000..0aaf32e --- /dev/null +++ b/data-client/fonts/misc/warmonger.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/warmongerbb.otf + diff --git a/data-client/fonts/misc/zirkon.xml b/data-client/fonts/misc/zirkon.xml new file mode 100644 index 0000000..8c053d9 --- /dev/null +++ b/data-client/fonts/misc/zirkon.xml @@ -0,0 +1,4 @@ + + + fonts/misc/ttf/ZIRKON__.ttf + diff --git a/data-client/gui/cursors/co-green.xml b/data-client/gui/cursors/co-green.xml new file mode 100644 index 0000000..44d874c --- /dev/null +++ b/data-client/gui/cursors/co-green.xml @@ -0,0 +1,13 @@ + + + + effects/gui_texture.cgfx + textures/gui/arrow.tga + + + + + + + diff --git a/data-client/gui/main.xml b/data-client/gui/main.xml new file mode 100644 index 0000000..0ad2878 --- /dev/null +++ b/data-client/gui/main.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data-client/gui/skin/skulpture.xml b/data-client/gui/skin/skulpture.xml new file mode 100644 index 0000000..7259d7c --- /dev/null +++ b/data-client/gui/skin/skulpture.xml @@ -0,0 +1,240 @@ + + + effects/gui_texture.cgfx + + + fonts/dejavu-mono.xml + + effects/fnt_texture.cgfx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data-client/gui/widgets/main-console.xml b/data-client/gui/widgets/main-console.xml new file mode 100644 index 0000000..444f58b --- /dev/null +++ b/data-client/gui/widgets/main-console.xml @@ -0,0 +1,79 @@ + + + materials/gui_pixmap.xml + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/liberation-serif.xml + + + + Žlutá žába smutně kuňká. + + materials/gui_text.xml + + + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/dejavu-mono.xml + + + + + + + + + debug@terra + : + ]]> + + + materials/gui_text.xml + + + + + \ No newline at end of file diff --git a/data-client/gui/widgets/main-normal.xml b/data-client/gui/widgets/main-normal.xml new file mode 100644 index 0000000..b776570 --- /dev/null +++ b/data-client/gui/widgets/main-normal.xml @@ -0,0 +1,85 @@ + + + materials/gui_pixmap.xml + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/liberation-serif.xml + + + + Žlutá žába smutně kuňká. + + materials/gui_text.xml + + + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/dejavu-sans.xml + + + + + + + + + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pharetra elit sit amet nunc. + In bibendum urna id risus iaculis aliquam. Morbi feugiat, mi quis porttitor commodo, dolor magna + condimentum leo, non molestie nulla dui ut massa. Proin enim. Vestibulum ultrices nulla + et velit.

+

Aliquam suscipit, lorem eu ultricies bibendum, est neque iaculis mauris, lobortis + feugiat felis libero vel diam. Morbi eget ante. Phasellus non erat. Vivamus at erat id + ipsum ornare mattis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc metus. Aenean sem. + Donec eros. Sed tellus. Proin posuere velit convallis leo. Vivamus semper felis a ipsum.

+ ]]> +
+ + materials/gui_text.xml +
+
+
+
+
\ No newline at end of file diff --git a/data-client/gui/widgets/main-perc.xml b/data-client/gui/widgets/main-perc.xml new file mode 100644 index 0000000..dfb41d8 --- /dev/null +++ b/data-client/gui/widgets/main-perc.xml @@ -0,0 +1,85 @@ + + + materials/gui_pixmap.xml + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/liberation-serif.xml + + + + Žlutá žába smutně kuňká. + + materials/gui_text.xml + + + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/dejavu-sans.xml + + + + + + + + + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pharetra elit sit amet nunc. + In bibendum urna id risus iaculis aliquam. Morbi feugiat, mi quis porttitor commodo, dolor magna + condimentum leo, non molestie nulla dui ut massa. Proin enim. Vestibulum ultrices nulla + et velit.

+

Aliquam suscipit, lorem eu ultricies bibendum, est neque iaculis mauris, lobortis + feugiat felis libero vel diam. Morbi eget ante. Phasellus non erat. Vivamus at erat id + ipsum ornare mattis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc metus. Aenean sem. + Donec eros. Sed tellus. Proin posuere velit convallis leo. Vivamus semper felis a ipsum.

+ ]]> +
+ + materials/gui_text.xml +
+
+
+
+
\ No newline at end of file diff --git a/data-client/gui/widgets/main-wdgs.xml b/data-client/gui/widgets/main-wdgs.xml new file mode 100644 index 0000000..b776570 --- /dev/null +++ b/data-client/gui/widgets/main-wdgs.xml @@ -0,0 +1,85 @@ + + + materials/gui_pixmap.xml + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/liberation-serif.xml + + + + Žlutá žába smutně kuňká. + + materials/gui_text.xml + + + + + + + + + materials/gui_pixmap.xml + + + + + + + true + + fonts/dejavu-sans.xml + + + + + + + + + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pharetra elit sit amet nunc. + In bibendum urna id risus iaculis aliquam. Morbi feugiat, mi quis porttitor commodo, dolor magna + condimentum leo, non molestie nulla dui ut massa. Proin enim. Vestibulum ultrices nulla + et velit.

+

Aliquam suscipit, lorem eu ultricies bibendum, est neque iaculis mauris, lobortis + feugiat felis libero vel diam. Morbi eget ante. Phasellus non erat. Vivamus at erat id + ipsum ornare mattis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc metus. Aenean sem. + Donec eros. Sed tellus. Proin posuere velit convallis leo. Vivamus semper felis a ipsum.

+ ]]> +
+ + materials/gui_text.xml +
+
+
+
+
\ No newline at end of file diff --git a/data-client/gui/widgets/splash.xml b/data-client/gui/widgets/splash.xml new file mode 100644 index 0000000..417e6e9 --- /dev/null +++ b/data-client/gui/widgets/splash.xml @@ -0,0 +1,153 @@ + + + + + + effects/gui_texture.cgfx + + + + + + + true + + fonts/dejavu-mono.xml + + effects/fnt_texture.cgfx + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pharetra elit sit amet nunc. + In bibendum urna id risus iaculis aliquam. Morbi feugiat, mi quis porttitor commodo, dolor magna + condimentum leo, non molestie nulla dui ut massa. Proin enim. Vestibulum ultrices nulla + et velit.

+

Aliquam suscipit, lorem eu ultricies bibendum, est neque iaculis mauris, lobortis + feugiat felis libero vel diam. Morbi eget ante. Phasellus non erat. Vivamus at erat id + ipsum ornare mattis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc metus. Aenean sem. + Donec eros. Sed tellus. Proin posuere velit convallis leo. Vivamus semper felis a ipsum.

+ ]]> +
+
+ + + + + + true + + fonts/dejavu-mono.xml + + effects/fnt_texture.cgfx + + + + + Blablabla + + +
+ + +
\ No newline at end of file diff --git a/data-client/gui/widgets/test.xml b/data-client/gui/widgets/test.xml new file mode 100644 index 0000000..60b546d --- /dev/null +++ b/data-client/gui/widgets/test.xml @@ -0,0 +1,172 @@ + + + + + + effects/gui_texture.cgfx + + + + + + + true + + fonts/dejavu-mono.xml + + effects/fnt_texture.cgfx + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pharetra elit sit amet nunc. + In bibendum urna id risus iaculis aliquam. Morbi feugiat, mi quis porttitor commodo, dolor magna + condimentum leo, non molestie nulla dui ut massa. Proin enim. Vestibulum ultrices nulla + et velit.

+

Aliquam suscipit, lorem eu ultricies bibendum, est neque iaculis mauris, lobortis + feugiat felis libero vel diam. Morbi eget ante. Phasellus non erat. Vivamus at erat id + ipsum ornare mattis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc metus. Aenean sem. + Donec eros. Sed tellus. Proin posuere velit convallis leo. Vivamus semper felis a ipsum.

+ ]]> +
+
+ + + quit_button + + + + + true + + effects/gui_texture.cgfx + + + fonts/dejavu-mono.xml + + effects/fnt_texture.cgfx + + + + Quit! + + + + args = ... + if args ~= nil then + print("Argument is " .. args.name) + end + + if a == nil then + print("You clicked the button and I know it. That's pretty cool, isn't it?") + a = 1 + else + print("You did it again, didn't you?") + end + + + +
+ + +
\ No newline at end of file diff --git a/data-client/script/init.lua b/data-client/script/init.lua new file mode 100644 index 0000000..7e9df75 --- /dev/null +++ b/data-client/script/init.lua @@ -0,0 +1,52 @@ +function AppInit(app) + print("Initializing...") + + math.randomseed(os.time()) + + local res = true + +-- dis = Display() +-- print(dis:GetDriverName()) +-- di = dis:GetDisplayInfo() +-- print(di.width, di.height, di.bpp, di.fullscreen, di.stereo) + +-- print "Available modes:" +-- itr = dis:ListModes() +-- +-- for x,m in next,itr do +-- print(m.width, m.height, m.bpp, m.fullscreen, m.stereo) +-- end + + + res = true and app:SetDesktop("gui/main.xml", "gui/skin/skulpture.xml") + + if res == true then + print("Initialization successful.") + else + error("Initialization failed!") + end + +end + +function AppMain(app) + +-- frameCount = frameCount + 1 + + --app:Quit() + +end + +function AppEnd(app) + +-- time = os.clock() - timeStart +-- print("\nTotal running time: " .. time .. " s") +-- print("Total frame count: " .. frameCount) +-- print("Average frames per second: " .. frameCount / time) + +-- f = io.open("lualog.txt", "w") +-- f:write("\nTotal running time: " .. time .. " s") +-- f:write("Total frame count: " .. frameCount) +-- f:write("Average frames per second: " .. frameCount / time) +-- f:close() + +end diff --git a/data-server/script/init.lua b/data-server/script/init.lua new file mode 100644 index 0000000..829ad28 --- /dev/null +++ b/data-server/script/init.lua @@ -0,0 +1,83 @@ +-- Server build is currently being used for +-- script benchmarking purposes + +function vt3(x, y, z) + local res = {x, y, z} + res["add"] = function(a, b) + a[1] = a[1] + b[1] + a[2] = a[2] + b[2] + a[3] = a[3] + b[3] + end + setmetatable(res, mt) + return res +end + +mt = { __add = function (a, b) + return vt3(a[1] + b[1], a[2] + b[2], a[3] + b[3]) + end } + +function testluavec(t) + local b=vt3(0,0,0) + local c=vt3(0,1,2) + + local tim=os.clock() + for i=0,t do + --b = b + vt3(0,1,2) + --b = b + c + b:add(c) + end + tim = os.clock() - tim + print(b[1], b[2], b[3]) + return tim +end + +function testterravec(t) + local b=vec3(0,0,0) + local c=vec3(0,1,2) + local tim=os.clock() + for i=0,t do + --b = b + vec3(0,1,2) + --b = b + c + b:add(c) + end + tim = os.clock() - tim + print(b.x, b.y, b.z) + return tim +end + +-- function addvec(a,b) +-- return {a[1]+b[1],a[2]+b[2],a[3]+b[3]} +-- end +-- +-- function testluavec(t) +-- local b={0,0,0} +-- local tim=os.clock() +-- for i=0,t do +-- b = addvec(b,{0,1,2}) +-- end +-- tim = os.clock() - tim +-- print(b[1], b[2], b[3]) +-- return tim +-- end +-- +-- function testterravec(t) +-- local b=v3(0,0,0) +-- local tim=os.clock() +-- for i=0,t do +-- b = b + v3(0,1,2) +-- end +-- tim = os.clock() - tim +-- print(b[1], b[2], b[3]) +-- return tim +-- end + +function AppInit() + t = testluavec(1000000) + print(t) + + t = testterravec(1000000) + print(t) +end + +function AppEnd() +end diff --git a/data-shared/models/fighter.x b/data-shared/models/fighter.x new file mode 100644 index 0000000..82bc519 --- /dev/null +++ b/data-shared/models/fighter.x @@ -0,0 +1,14144 @@ +xof 0303txt 0032 +template Frame { + <3d82ab46-62da-11cf-ab39-0020af71e433> + [...] +} + +template Matrix4x4 { + + array FLOAT matrix[16]; +} + +template FrameTransformMatrix { + + Matrix4x4 frameMatrix; +} + +template Vector { + <3d82ab5e-62da-11cf-ab39-0020af71e433> + FLOAT x; + FLOAT y; + FLOAT z; +} + +template MeshFace { + <3d82ab5f-62da-11cf-ab39-0020af71e433> + DWORD nFaceVertexIndices; + array DWORD faceVertexIndices[nFaceVertexIndices]; +} + +template Mesh { + <3d82ab44-62da-11cf-ab39-0020af71e433> + DWORD nVertices; + array Vector vertices[nVertices]; + DWORD nFaces; + array MeshFace faces[nFaces]; + [...] +} + +template MeshNormals { + + DWORD nNormals; + array Vector normals[nNormals]; + DWORD nFaceNormals; + array MeshFace faceNormals[nFaceNormals]; +} + +template Coords2d { + + FLOAT u; + FLOAT v; +} + +template MeshTextureCoords { + + DWORD nTextureCoords; + array Coords2d textureCoords[nTextureCoords]; +} + +template ColorRGBA { + <35ff44e0-6c7c-11cf-8f52-0040333594a3> + FLOAT red; + FLOAT green; + FLOAT blue; + FLOAT alpha; +} + +template ColorRGB { + + FLOAT red; + FLOAT green; + FLOAT blue; +} + +template Material { + <3d82ab4d-62da-11cf-ab39-0020af71e433> + ColorRGBA faceColor; + FLOAT power; + ColorRGB specularColor; + ColorRGB emissiveColor; + [...] +} + +template MeshMaterialList { + + DWORD nMaterials; + DWORD nFaceIndexes; + array DWORD faceIndexes[nFaceIndexes]; + [Material <3d82ab4d-62da-11cf-ab39-0020af71e433>] +} + +template TextureFilename { + + STRING filename; +} + +Frame { + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;; + } + +Mesh CINEMA4D_Mesh { + 1615; + // Turret_base + -0.011;-78.543;-333.462;, + 19.988;-58.543;-333.281;, + 17.399;-58.543;-343.305;, + 10.145;-58.543;-350.691;, + -9.854;-58.543;-350.872;, + -17.241;-58.543;-343.619;, + -20.011;-58.543;-333.643;, + -17.422;-58.543;-323.619;, + -10.168;-58.543;-316.233;, + -0.193;-58.543;-313.463;, + 9.831;-58.543;-316.052;, + 17.218;-58.543;-323.305;, + 17.308;-68.543;-333.305;, + 15.066;-68.543;-341.986;, + 8.784;-68.543;-348.383;, + -8.535;-68.543;-348.54;, + -14.932;-68.543;-342.258;, + -17.331;-68.543;-333.619;, + -15.089;-68.543;-324.938;, + -8.807;-68.543;-318.541;, + -0.168;-68.543;-316.142;, + 8.512;-68.543;-318.384;, + 14.909;-68.543;-324.666;, + 9.988;-75.863;-333.371;, + 8.694;-75.863;-338.383;, + -8.626;-75.863;-338.54;, + -10.011;-75.863;-333.553;, + -8.717;-75.863;-328.541;, + -5.09;-75.863;-324.847;, + -0.102;-75.863;-323.462;, + 4.91;-75.863;-324.757;, + 8.603;-75.863;-328.384;, + 7.132;-68.543;-348.842;, + -6.987;-58.543;-335.204;, + 7.012;-58.543;-335.082;, + 7.056;-75.863;-340.051;, + -6.896;-71.873;-345.64;, + 7.104;-71.853;-345.531;, + -6.844;-58.543;-351.65;, + -6.944;-75.863;-340.193;, + 7.012;-75.5;-335.082;, + -6.987;-75.5;-335.204;, + 7.156;-58.543;-351.521;, + 0.056;-75.863;-340.122;, + -6.867;-68.543;-348.971;, + // Gatling_base + 7.02;-67.122;-336.852;, + -6.979;-67.122;-336.979;, + -6.602;-67.2;-358.048;, + 7.032;-67.2;-357.924;, + 4.97;-62.172;-336.889;, + -4.929;-72.072;-336.942;, + -4.606;-72.02;-358.012;, + 5.035;-62.379;-357.96;, + 0.02;-74.122;-336.89;, + 0.021;-60.122;-336.941;, + 0.215;-60.383;-358.011;, + 0.215;-74.017;-357.961;, + -4.929;-62.172;-336.979;, + 4.97;-72.072;-336.853;, + 5.035;-72.02;-357.925;, + -4.605;-62.379;-358.048;, + -6.79;-67.199;-357.87;, + -4.74;-72.149;-357.833;, + 7.209;-67.199;-357.743;, + 5.159;-62.249;-357.78;, + 0.21;-74.199;-357.781;, + 5.159;-72.149;-357.743;, + 0.21;-60.199;-357.832;, + -4.74;-62.249;-357.87;, + // Gatling_base_2 + -6.927;-74.158;-342.112;, + -6.927;-69.491;-342.129;, + -6.927;-64.825;-342.146;, + -6.926;-60.158;-342.163;, + -2.26;-74.158;-342.071;, + -2.26;-69.491;-342.088;, + -2.26;-64.825;-342.105;, + -2.26;-60.158;-342.123;, + 2.406;-74.158;-342.03;, + 2.406;-69.491;-342.048;, + 2.406;-64.825;-342.065;, + 2.407;-60.158;-342.082;, + 7.073;-74.158;-341.99;, + 7.073;-69.491;-342.007;, + 7.073;-64.825;-342.024;, + 7.073;-60.158;-342.041;, + 7.032;-74.141;-337.323;, + 7.032;-69.474;-337.34;, + 7.032;-64.808;-337.358;, + 7.032;-60.141;-337.375;, + 6.991;-74.124;-332.657;, + 6.991;-69.457;-332.674;, + 6.992;-64.79;-332.691;, + 6.992;-60.124;-332.708;, + 6.951;-74.106;-327.99;, + 6.951;-69.44;-328.008;, + 6.951;-64.773;-328.025;, + 6.951;-60.107;-328.042;, + 2.284;-74.106;-328.031;, + 2.284;-69.44;-328.048;, + 2.284;-64.773;-328.065;, + 2.285;-60.107;-328.083;, + -2.382;-74.106;-328.072;, + -2.382;-69.44;-328.089;, + -2.382;-64.773;-328.106;, + -2.382;-60.107;-328.123;, + -7.049;-74.106;-328.112;, + -7.049;-69.44;-328.13;, + -7.049;-64.773;-328.147;, + -7.048;-60.107;-328.164;, + -7.008;-74.124;-332.779;, + -7.008;-69.457;-332.796;, + -7.008;-64.79;-332.813;, + -7.008;-60.124;-332.83;, + -6.967;-74.141;-337.445;, + -6.967;-69.474;-337.462;, + -6.967;-64.808;-337.48;, + -6.967;-60.141;-337.497;, + -2.301;-60.141;-337.456;, + -2.341;-60.124;-332.79;, + 2.366;-60.141;-337.416;, + 2.325;-60.124;-332.749;, + -2.342;-74.124;-332.738;, + -2.301;-74.141;-337.405;, + 2.325;-74.124;-332.697;, + 2.365;-74.141;-337.364;, + // Gatling_mid + 6.261;-69.703;-372.775;, + -5.558;-64.807;-372.901;, + -5.535;-64.817;-374.369;, + 6.265;-69.705;-374.244;, + 6.261;-64.807;-372.793;, + -5.558;-69.704;-372.883;, + -5.535;-69.705;-374.351;, + 6.265;-64.817;-374.262;, + -2.097;-73.166;-372.838;, + 2.8;-61.345;-372.838;, + 2.809;-61.361;-374.306;, + -2.079;-73.161;-374.306;, + -2.096;-61.345;-372.882;, + 2.799;-73.165;-372.794;, + 2.809;-73.161;-374.262;, + -2.079;-61.361;-374.35;, + -5.698;-64.75;-374.208;, + -5.698;-69.769;-374.189;, + 6.419;-69.769;-374.08;, + 6.419;-64.75;-374.098;, + -2.149;-73.318;-374.144;, + 2.87;-73.318;-374.099;, + 2.87;-61.201;-374.143;, + -2.149;-61.201;-374.189;, + -5.708;-64.745;-373.05;, + -5.708;-69.764;-373.032;, + 6.408;-69.764;-372.922;, + 6.409;-64.745;-372.94;, + -2.159;-73.313;-372.986;, + 2.86;-73.313;-372.941;, + 2.86;-61.196;-372.985;, + -2.159;-61.196;-373.031;, + 2.666;-68.219;-374.114;, + 2.666;-66.305;-374.121;, + 1.313;-64.952;-374.138;, + -0.6;-64.952;-374.156;, + -1.953;-66.305;-374.163;, + -1.953;-68.219;-374.156;, + -0.6;-69.572;-374.139;, + 1.313;-69.572;-374.121;, + 2.656;-68.214;-372.966;, + 2.656;-66.301;-372.973;, + 1.303;-64.948;-372.991;, + -0.611;-64.948;-373.008;, + -1.964;-66.301;-373.015;, + -1.964;-68.214;-373.008;, + -0.611;-69.567;-372.991;, + 1.303;-69.567;-372.974;, + -2.11;-68.274;-372.857;, + 2.799;-66.24;-372.82;, + -2.11;-66.24;-372.864;, + 2.799;-68.274;-372.812;, + -0.672;-69.712;-372.838;, + -0.672;-64.802;-372.856;, + 1.361;-64.802;-372.838;, + 1.361;-69.712;-372.82;, + 2.813;-68.279;-374.28;, + 2.813;-66.246;-374.288;, + 1.375;-64.808;-374.306;, + -0.659;-64.808;-374.324;, + -2.097;-66.246;-374.332;, + -2.097;-68.279;-374.325;, + -0.659;-69.717;-374.306;, + 1.375;-69.717;-374.288;, + // Gatling_fin_1 + 6.428;-69.771;-391.139;, + -5.392;-64.875;-391.265;, + -5.376;-64.882;-391.882;, + 6.424;-69.769;-391.757;, + 6.428;-64.875;-391.157;, + -5.392;-69.771;-391.247;, + -5.376;-69.769;-391.864;, + 6.424;-64.881;-391.775;, + -1.93;-73.233;-391.202;, + 2.966;-61.413;-391.202;, + 2.968;-61.425;-391.819;, + -1.92;-73.226;-391.819;, + -1.93;-61.413;-391.246;, + 2.966;-73.233;-391.158;, + 2.968;-73.226;-391.775;, + -1.92;-61.425;-391.863;, + -5.538;-64.815;-391.815;, + -5.538;-69.834;-391.797;, + 6.579;-69.833;-391.687;, + 6.579;-64.814;-391.705;, + -1.989;-73.383;-391.751;, + 3.03;-73.383;-391.706;, + 3.03;-61.265;-391.75;, + -1.989;-61.266;-391.796;, + -5.542;-64.813;-391.328;, + -5.542;-69.832;-391.31;, + 6.574;-69.832;-391.2;, + 6.574;-64.813;-391.219;, + -1.994;-73.381;-391.265;, + 3.025;-73.381;-391.219;, + 3.026;-61.264;-391.264;, + -1.993;-61.264;-391.309;, + 2.826;-68.284;-391.724;, + 2.826;-66.37;-391.731;, + 1.473;-65.017;-391.748;, + -0.44;-65.017;-391.766;, + -1.793;-66.37;-391.773;, + -1.794;-68.284;-391.766;, + -0.441;-69.637;-391.749;, + 1.473;-69.636;-391.731;, + 2.821;-68.282;-391.242;, + 2.821;-66.368;-391.249;, + 1.468;-65.015;-391.266;, + -0.445;-65.015;-391.283;, + -1.798;-66.368;-391.291;, + -1.798;-68.282;-391.284;, + -0.445;-69.635;-391.266;, + 1.468;-69.635;-391.249;, + -1.943;-68.342;-391.221;, + 2.966;-66.308;-391.184;, + -1.943;-66.308;-391.228;, + 2.966;-68.342;-391.176;, + -0.506;-69.779;-391.202;, + -0.505;-64.87;-391.22;, + 1.528;-64.87;-391.202;, + 1.528;-69.779;-391.184;, + 2.971;-68.344;-391.793;, + 2.971;-66.31;-391.801;, + 1.534;-64.872;-391.819;, + -0.5;-64.872;-391.837;, + -1.938;-66.31;-391.845;, + -1.938;-68.344;-391.838;, + -0.5;-69.782;-391.819;, + 1.533;-69.782;-391.801;, + // Gatling_fin_2 + 6.441;-69.776;-392.583;, + -5.379;-64.88;-392.708;, + -5.363;-64.887;-393.325;, + 6.437;-69.775;-393.2;, + 6.441;-64.88;-392.601;, + -5.379;-69.777;-392.69;, + -5.363;-69.775;-393.307;, + 6.437;-64.887;-393.218;, + -1.917;-73.239;-392.646;, + 2.979;-61.418;-392.645;, + 2.981;-61.431;-393.262;, + -1.907;-73.231;-393.263;, + -1.917;-61.418;-392.689;, + 2.979;-73.239;-392.601;, + 2.981;-73.231;-393.218;, + -1.907;-61.431;-393.306;, + -5.525;-64.82;-393.258;, + -5.525;-69.839;-393.24;, + 6.592;-69.839;-393.13;, + 6.592;-64.82;-393.148;, + -1.976;-73.388;-393.194;, + 3.043;-73.388;-393.149;, + 3.043;-61.271;-393.194;, + -1.976;-61.271;-393.239;, + -5.529;-64.818;-392.772;, + -5.529;-69.837;-392.753;, + 6.587;-69.837;-392.643;, + 6.587;-64.818;-392.662;, + -1.981;-73.386;-392.708;, + 3.038;-73.386;-392.662;, + 3.039;-61.269;-392.707;, + -1.98;-61.269;-392.752;, + 2.839;-68.289;-393.167;, + 2.839;-66.375;-393.174;, + 1.486;-65.022;-393.192;, + -0.427;-65.022;-393.209;, + -1.78;-66.375;-393.216;, + -1.78;-68.289;-393.209;, + -0.428;-69.642;-393.192;, + 1.486;-69.642;-393.175;, + 2.834;-68.287;-392.685;, + 2.834;-66.374;-392.692;, + 1.482;-65.021;-392.709;, + -0.432;-65.021;-392.727;, + -1.785;-66.374;-392.734;, + -1.785;-68.287;-392.727;, + -0.432;-69.64;-392.71;, + 1.481;-69.64;-392.692;, + -1.93;-68.347;-392.664;, + 2.979;-66.313;-392.627;, + -1.93;-66.313;-392.671;, + 2.979;-68.347;-392.619;, + -0.493;-69.785;-392.645;, + -0.492;-64.875;-392.664;, + 1.541;-64.875;-392.645;, + 1.541;-69.785;-392.627;, + 2.984;-68.349;-393.236;, + 2.984;-66.316;-393.244;, + 1.547;-64.878;-393.262;, + -0.487;-64.878;-393.281;, + -1.925;-66.316;-393.288;, + -1.925;-68.349;-393.281;, + -0.487;-69.787;-393.262;, + 1.546;-69.787;-393.244;, + -2.36;-67.327;-392.671;, + // Gatling_fin_3 + 6.453;-69.782;-393.966;, + -5.366;-64.886;-394.091;, + -5.351;-64.892;-394.708;, + 6.449;-69.78;-394.583;, + 6.454;-64.885;-393.984;, + -5.366;-69.782;-394.073;, + -5.351;-69.78;-394.69;, + 6.449;-64.892;-394.601;, + -1.904;-73.244;-394.029;, + 2.992;-61.423;-394.028;, + 2.993;-61.436;-394.645;, + -1.895;-73.236;-394.646;, + -1.904;-61.423;-394.073;, + 2.991;-73.244;-393.985;, + 2.993;-73.236;-394.602;, + -1.894;-61.436;-394.69;, + -5.512;-64.825;-394.642;, + -5.512;-69.844;-394.623;, + 6.604;-69.844;-394.513;, + 6.604;-64.825;-394.532;, + -1.964;-73.393;-394.578;, + 3.055;-73.393;-394.533;, + 3.055;-61.276;-394.577;, + -1.963;-61.276;-394.623;, + -5.517;-64.823;-394.155;, + -5.517;-69.842;-394.137;, + 6.6;-69.842;-394.027;, + 6.6;-64.823;-394.045;, + -1.968;-73.391;-394.091;, + 3.051;-73.391;-394.046;, + 3.051;-61.274;-394.091;, + -1.968;-61.274;-394.136;, + 2.851;-68.294;-394.551;, + 2.851;-66.381;-394.558;, + 1.498;-65.028;-394.575;, + -0.415;-65.028;-394.593;, + -1.768;-66.381;-394.6;, + -1.768;-68.294;-394.593;, + -0.415;-69.647;-394.576;, + 1.498;-69.647;-394.558;, + 2.847;-68.292;-394.069;, + 2.847;-66.379;-394.076;, + 1.494;-65.026;-394.093;, + -0.419;-65.026;-394.11;, + -1.772;-66.379;-394.117;, + -1.772;-68.292;-394.11;, + -0.419;-69.645;-394.093;, + 1.494;-69.645;-394.076;, + -1.918;-68.352;-394.047;, + 2.991;-66.318;-394.01;, + -1.918;-66.319;-394.055;, + 2.991;-68.352;-394.003;, + -0.48;-69.79;-394.029;, + -0.48;-64.881;-394.047;, + 1.554;-64.881;-394.029;, + 1.553;-69.79;-394.011;, + 2.997;-68.354;-394.62;, + 2.997;-66.321;-394.627;, + 1.559;-64.883;-394.646;, + -0.474;-64.883;-394.664;, + -1.912;-66.321;-394.672;, + -1.912;-68.354;-394.664;, + -0.474;-69.792;-394.646;, + 1.559;-69.792;-394.628;, + -2.722;-68.254;-394.672;, + -2.722;-66.416;-394.679;, + -2.341;-67.335;-394.672;, + // Barrel_11 + -4.082;-67.156;-346.078;, + -2.801;-68.165;-396.065;, + -2.782;-67.156;-346.066;, + -2.332;-67.338;-395.664;, + -2.713;-66.419;-395.67;, + -2.46;-67.34;-396.065;, + -3.163;-66.236;-346.073;, + -3.632;-66.038;-395.68;, + -4.552;-66.419;-395.687;, + -2.801;-66.515;-396.071;, + -4.932;-67.338;-395.687;, + -4.082;-65.856;-346.082;, + -3.626;-66.173;-396.08;, + -4.552;-68.258;-395.68;, + -3.632;-68.638;-395.671;, + -5.001;-66.236;-346.089;, + -2.713;-68.258;-395.664;, + -4.451;-66.515;-396.086;, + -2.455;-67.338;-395.665;, + -5.382;-67.156;-346.089;, + -4.793;-67.34;-396.086;, + -2.799;-66.508;-395.672;, + -5.001;-68.075;-346.083;, + -3.63;-66.164;-395.68;, + -4.46;-66.508;-395.687;, + -4.451;-68.165;-396.08;, + -4.804;-67.338;-395.687;, + -4.082;-68.456;-346.073;, + -4.46;-68.169;-395.681;, + -3.626;-68.507;-396.071;, + -3.163;-68.075;-346.066;, + -3.63;-68.513;-395.672;, + -2.799;-68.169;-395.665;, + -2.879;-68.085;-396.066;, + -2.57;-67.34;-396.066;, + -2.879;-66.595;-396.071;, + -3.624;-66.286;-396.079;, + -4.369;-66.595;-396.085;, + -4.678;-67.34;-396.085;, + -4.369;-68.085;-396.079;, + -3.624;-68.394;-396.071;, + -3.129;-68.036;-359.259;, + -2.784;-67.204;-359.259;, + -3.129;-66.373;-359.265;, + -3.96;-66.029;-359.274;, + -4.791;-66.373;-359.281;, + -5.136;-67.204;-359.281;, + -4.791;-68.036;-359.274;, + -3.96;-68.38;-359.266;, + // Barrel_1 + 4.285;-67.156;-346.002;, + 5.565;-68.165;-395.989;, + 5.585;-67.156;-345.99;, + 6.034;-67.338;-395.588;, + 5.653;-66.419;-395.595;, + 5.907;-67.34;-395.989;, + 5.204;-66.236;-345.997;, + 4.734;-66.038;-395.604;, + 3.815;-66.419;-395.611;, + 5.565;-66.515;-395.995;, + 3.434;-67.338;-395.611;, + 4.285;-65.856;-346.007;, + 4.74;-66.173;-396.004;, + 3.815;-68.258;-395.605;, + 4.734;-68.638;-395.595;, + 3.365;-66.236;-346.014;, + 5.653;-68.258;-395.588;, + 3.915;-66.515;-396.01;, + 5.911;-67.338;-395.59;, + 2.985;-67.156;-346.014;, + 3.574;-67.34;-396.01;, + 5.567;-66.508;-395.596;, + 3.365;-68.075;-346.007;, + 4.737;-66.164;-395.605;, + 3.906;-66.508;-395.611;, + 3.915;-68.165;-396.004;, + 3.562;-67.338;-395.611;, + 4.285;-68.456;-345.997;, + 3.906;-68.169;-395.605;, + 4.74;-68.507;-395.995;, + 5.204;-68.075;-345.99;, + 4.737;-68.513;-395.596;, + 5.567;-68.169;-395.59;, + 5.488;-68.085;-395.99;, + 5.797;-67.34;-395.99;, + 5.488;-66.595;-395.996;, + 4.743;-66.286;-396.004;, + 3.997;-66.595;-396.009;, + 3.688;-67.34;-396.009;, + 3.997;-68.085;-396.004;, + 4.742;-68.394;-395.996;, + 5.238;-68.036;-359.184;, + 5.582;-67.204;-359.184;, + 5.238;-66.373;-359.19;, + 4.407;-66.029;-359.199;, + 3.575;-66.373;-359.205;, + 3.231;-67.204;-359.205;, + 3.575;-68.036;-359.199;, + 4.407;-68.38;-359.19;, + // Barrel_13 + 0.103;-62.982;-346.055;, + 1.384;-63.991;-396.042;, + 1.403;-62.982;-346.044;, + 1.853;-63.165;-395.641;, + 1.472;-62.245;-395.648;, + 1.726;-63.166;-396.042;, + 1.022;-62.062;-346.05;, + 0.553;-61.865;-395.658;, + -0.366;-62.245;-395.665;, + 1.384;-62.341;-396.048;, + -0.747;-63.165;-395.665;, + 0.103;-61.682;-346.06;, + 0.559;-61.999;-396.057;, + -0.366;-64.084;-395.658;, + 0.553;-64.465;-395.648;, + -0.816;-62.062;-346.067;, + 1.472;-64.084;-395.641;, + -0.266;-62.341;-396.063;, + 1.73;-63.165;-395.643;, + -1.197;-62.982;-346.067;, + -0.608;-63.166;-396.064;, + 1.386;-62.334;-395.649;, + -0.816;-63.901;-346.06;, + 0.555;-61.99;-395.658;, + -0.275;-62.334;-395.664;, + -0.266;-63.991;-396.057;, + -0.619;-63.165;-395.664;, + 0.103;-64.282;-346.051;, + -0.275;-63.995;-395.658;, + 0.559;-64.333;-396.049;, + 1.022;-63.901;-346.044;, + 0.555;-64.339;-395.649;, + 1.386;-63.995;-395.643;, + 1.306;-63.911;-396.043;, + 1.615;-63.166;-396.043;, + 1.307;-62.421;-396.049;, + 0.561;-62.112;-396.057;, + -0.184;-62.421;-396.062;, + -0.493;-63.166;-396.062;, + -0.184;-63.911;-396.057;, + 0.561;-64.22;-396.049;, + 1.057;-63.862;-359.237;, + 1.401;-63.03;-359.237;, + 1.057;-62.199;-359.243;, + 0.225;-61.855;-359.252;, + -0.606;-62.199;-359.258;, + -0.95;-63.03;-359.258;, + -0.606;-63.862;-359.252;, + 0.225;-64.206;-359.243;, + // Barrel_14 + 0.103;-71.33;-346.025;, + 1.384;-72.339;-396.012;, + 1.403;-71.33;-346.013;, + 1.853;-71.512;-395.61;, + 1.472;-70.593;-395.617;, + 1.725;-71.514;-396.012;, + 1.022;-70.41;-346.02;, + 0.553;-70.213;-395.627;, + -0.367;-70.593;-395.634;, + 1.384;-70.689;-396.018;, + -0.747;-71.513;-395.634;, + 0.103;-70.03;-346.029;, + 0.559;-70.347;-396.026;, + -0.367;-72.432;-395.627;, + 0.553;-72.812;-395.617;, + -0.816;-70.41;-346.036;, + 1.472;-72.432;-395.61;, + -0.266;-70.689;-396.033;, + 1.73;-71.513;-395.612;, + -1.197;-71.33;-346.036;, + -0.608;-71.514;-396.033;, + 1.386;-70.682;-395.618;, + -0.816;-72.249;-346.03;, + 0.555;-70.338;-395.627;, + -0.275;-70.682;-395.634;, + -0.266;-72.339;-396.027;, + -0.619;-71.513;-395.634;, + 0.103;-72.63;-346.02;, + -0.275;-72.343;-395.627;, + 0.559;-72.681;-396.018;, + 1.022;-72.249;-346.013;, + 0.555;-72.687;-395.619;, + 1.386;-72.343;-395.612;, + 1.306;-72.259;-396.013;, + 1.615;-71.514;-396.013;, + 1.306;-70.769;-396.018;, + 0.561;-70.46;-396.026;, + -0.184;-70.769;-396.032;, + -0.493;-71.514;-396.032;, + -0.184;-72.259;-396.026;, + 0.561;-72.568;-396.018;, + 1.056;-72.21;-359.206;, + 1.401;-71.378;-359.206;, + 1.056;-70.547;-359.212;, + 0.225;-70.203;-359.221;, + -0.606;-70.547;-359.227;, + -0.951;-71.378;-359.227;, + -0.606;-72.21;-359.221;, + 0.225;-72.554;-359.212;, + // Barrel_12 + -2.86;-64.196;-346.078;, + -1.579;-65.205;-396.065;, + -1.56;-64.196;-346.066;, + -1.11;-64.379;-395.664;, + -1.491;-63.46;-395.67;, + -1.237;-64.38;-396.065;, + -1.941;-63.277;-346.073;, + -2.41;-63.079;-395.68;, + -3.329;-63.46;-395.687;, + -1.579;-63.555;-396.071;, + -3.71;-64.379;-395.687;, + -2.86;-62.896;-346.083;, + -2.404;-63.214;-396.08;, + -3.329;-65.298;-395.68;, + -2.41;-65.679;-395.671;, + -3.779;-63.277;-346.089;, + -1.491;-65.298;-395.664;, + -3.229;-63.555;-396.086;, + -1.233;-64.379;-395.665;, + -4.16;-64.196;-346.09;, + -3.571;-64.38;-396.086;, + -1.577;-63.549;-395.672;, + -3.779;-65.115;-346.083;, + -2.408;-63.205;-395.68;, + -3.238;-63.549;-395.687;, + -3.229;-65.205;-396.08;, + -3.582;-64.379;-395.687;, + -2.86;-65.496;-346.073;, + -3.238;-65.209;-395.681;, + -2.404;-65.547;-396.071;, + -1.941;-65.115;-346.066;, + -2.408;-65.553;-395.672;, + -1.577;-65.209;-395.665;, + -1.656;-65.126;-396.066;, + -1.348;-64.38;-396.066;, + -1.656;-63.635;-396.071;, + -2.402;-63.326;-396.079;, + -3.147;-63.635;-396.085;, + -3.456;-64.38;-396.085;, + -3.147;-65.126;-396.079;, + -2.402;-65.435;-396.071;, + -1.906;-65.076;-359.259;, + -1.562;-64.245;-359.259;, + -1.906;-63.413;-359.265;, + -2.738;-63.069;-359.274;, + -3.569;-63.413;-359.281;, + -3.913;-64.245;-359.281;, + -3.569;-65.076;-359.274;, + -2.738;-65.42;-359.266;, + // Barrel_16 + 3.064;-64.196;-346.024;, + 4.345;-65.206;-396.011;, + 4.364;-64.196;-346.012;, + 4.814;-64.379;-395.61;, + 4.433;-63.46;-395.617;, + 4.687;-64.381;-396.011;, + 3.984;-63.277;-346.019;, + 3.514;-63.079;-395.626;, + 2.595;-63.46;-395.633;, + 4.345;-63.556;-396.017;, + 2.214;-64.379;-395.633;, + 3.064;-62.896;-346.029;, + 3.52;-63.214;-396.026;, + 2.595;-65.298;-395.627;, + 3.514;-65.679;-395.617;, + 2.145;-63.277;-346.036;, + 4.433;-65.298;-395.61;, + 2.695;-63.556;-396.032;, + 4.691;-64.379;-395.612;, + 1.764;-64.196;-346.036;, + 2.353;-64.381;-396.032;, + 4.347;-63.549;-395.618;, + 2.145;-65.115;-346.029;, + 3.517;-63.205;-395.627;, + 2.686;-63.549;-395.633;, + 2.695;-65.206;-396.026;, + 2.342;-64.379;-395.633;, + 3.064;-65.496;-346.019;, + 2.686;-65.21;-395.627;, + 3.52;-65.547;-396.017;, + 3.984;-65.115;-346.012;, + 3.517;-65.554;-395.618;, + 4.347;-65.21;-395.612;, + 4.268;-65.126;-396.012;, + 4.576;-64.381;-396.012;, + 4.268;-63.635;-396.018;, + 3.522;-63.326;-396.025;, + 2.777;-63.635;-396.031;, + 2.468;-64.381;-396.031;, + 2.777;-65.126;-396.026;, + 3.522;-65.435;-396.018;, + 4.018;-65.076;-359.206;, + 4.362;-64.245;-359.206;, + 4.018;-63.413;-359.212;, + 3.187;-63.069;-359.221;, + 2.355;-63.413;-359.227;, + 2.011;-64.245;-359.227;, + 2.355;-65.076;-359.221;, + 3.186;-65.42;-359.212;, + // Barrel_17 + -2.862;-70.115;-346.056;, + -1.582;-71.125;-396.043;, + -1.562;-70.115;-346.044;, + -1.113;-70.298;-395.642;, + -1.493;-69.379;-395.649;, + -1.24;-70.3;-396.043;, + -1.943;-69.196;-346.051;, + -2.413;-68.998;-395.658;, + -3.332;-69.379;-395.665;, + -1.582;-69.475;-396.049;, + -3.713;-70.298;-395.665;, + -2.862;-68.815;-346.061;, + -2.407;-69.133;-396.058;, + -3.332;-71.217;-395.659;, + -2.413;-71.598;-395.649;, + -3.782;-69.196;-346.068;, + -1.493;-71.217;-395.642;, + -3.232;-69.475;-396.064;, + -1.236;-70.298;-395.644;, + -4.162;-70.115;-346.068;, + -3.573;-70.3;-396.064;, + -1.58;-69.468;-395.65;, + -3.782;-71.034;-346.061;, + -2.41;-69.124;-395.659;, + -3.241;-69.468;-395.665;, + -3.232;-71.125;-396.058;, + -3.585;-70.298;-395.665;, + -2.862;-71.415;-346.051;, + -3.241;-71.129;-395.659;, + -2.407;-71.466;-396.049;, + -1.943;-71.034;-346.044;, + -2.41;-71.473;-395.65;, + -1.58;-71.129;-395.644;, + -1.659;-71.045;-396.044;, + -1.35;-70.3;-396.044;, + -1.659;-69.554;-396.049;, + -2.404;-69.245;-396.057;, + -3.15;-69.554;-396.063;, + -3.458;-70.3;-396.063;, + -3.15;-71.045;-396.057;, + -2.404;-71.354;-396.05;, + -1.909;-70.995;-359.238;, + -1.565;-70.164;-359.238;, + -1.909;-69.333;-359.244;, + -2.74;-68.988;-359.253;, + -3.572;-69.333;-359.259;, + -3.916;-70.164;-359.259;, + -3.572;-70.995;-359.253;, + -2.74;-71.34;-359.244;, + // Barrel_15 + 3.059;-70.127;-346.002;, + 4.34;-71.137;-395.989;, + 4.359;-70.127;-345.99;, + 4.809;-70.31;-395.588;, + 4.428;-69.391;-395.595;, + 4.681;-70.312;-395.989;, + 3.978;-69.208;-345.997;, + 3.509;-69.01;-395.605;, + 2.589;-69.391;-395.612;, + 4.34;-69.487;-395.995;, + 2.209;-70.31;-395.612;, + 3.059;-68.827;-346.007;, + 3.515;-69.145;-396.004;, + 2.589;-71.229;-395.605;, + 3.509;-71.61;-395.595;, + 2.14;-69.208;-346.014;, + 4.428;-71.229;-395.588;, + 2.69;-69.487;-396.01;, + 4.686;-70.31;-395.59;, + 1.759;-70.127;-346.014;, + 2.348;-70.312;-396.01;, + 4.342;-69.48;-395.596;, + 2.14;-71.047;-346.007;, + 3.511;-69.136;-395.605;, + 2.681;-69.48;-395.611;, + 2.69;-71.137;-396.004;, + 2.337;-70.31;-395.611;, + 3.059;-71.427;-345.997;, + 2.681;-71.141;-395.605;, + 3.515;-71.478;-395.995;, + 3.978;-71.047;-345.99;, + 3.511;-71.485;-395.596;, + 4.342;-71.141;-395.59;, + 4.262;-71.057;-395.99;, + 4.571;-70.312;-395.99;, + 4.262;-69.566;-395.996;, + 3.517;-69.258;-396.004;, + 2.772;-69.566;-396.009;, + 2.463;-70.312;-396.009;, + 2.772;-71.057;-396.004;, + 3.517;-71.366;-395.996;, + 4.012;-71.007;-359.184;, + 4.357;-70.176;-359.184;, + 4.012;-69.345;-359.19;, + 3.181;-69.0;-359.199;, + 2.35;-69.345;-359.205;, + 2.005;-70.176;-359.205;, + 2.35;-71.007;-359.199;, + 3.181;-71.352;-359.19;, + // Side_guns + -82.864;-46.848;-92.566;, + -90.864;-46.848;-92.566;, + -89.986;-46.848;-135.669;, + -83.708;-46.848;-135.669;, + -84.036;-44.02;-92.566;, + -89.693;-49.676;-92.566;, + -89.067;-49.068;-135.669;, + -84.627;-44.628;-135.669;, + -86.864;-50.848;-92.566;, + -86.864;-42.848;-92.566;, + -86.847;-49.987;-135.669;, + -86.847;-43.709;-135.669;, + -89.693;-44.02;-92.566;, + -84.036;-49.676;-92.566;, + -89.067;-44.628;-135.669;, + -84.627;-49.068;-135.669;, + -89.579;-46.848;-135.669;, + -84.116;-46.848;-135.669;, + -88.779;-48.779;-135.669;, + -84.916;-44.916;-135.669;, + -86.847;-49.579;-135.669;, + -86.847;-44.116;-135.669;, + -88.779;-44.916;-135.669;, + -84.916;-48.779;-135.669;, + -90.345;-46.848;-120.592;, + -83.384;-46.848;-120.592;, + -89.325;-49.309;-120.592;, + -84.403;-44.387;-120.592;, + -86.864;-50.328;-120.592;, + -86.864;-43.368;-120.592;, + -89.325;-44.387;-120.592;, + -84.403;-49.309;-120.592;, + -82.864;-46.848;-134.169;, + -84.036;-44.02;-134.169;, + -89.693;-49.676;-134.169;, + -86.864;-50.848;-134.169;, + -86.864;-42.848;-134.169;, + -89.693;-44.02;-134.169;, + -84.036;-49.676;-134.169;, + -90.864;-46.848;-134.169;, + -90.345;-46.848;-134.169;, + -89.325;-49.309;-134.169;, + -86.864;-50.328;-134.169;, + -84.403;-49.309;-134.169;, + -83.384;-46.848;-134.169;, + -84.403;-44.387;-134.169;, + -86.864;-43.368;-134.169;, + -89.325;-44.387;-134.169;, + 82.864;-46.848;-92.566;, + 90.864;-46.848;-92.566;, + 89.986;-46.848;-135.669;, + 83.708;-46.848;-135.669;, + 84.036;-44.02;-92.566;, + 89.693;-49.676;-92.566;, + 89.067;-49.068;-135.669;, + 84.627;-44.628;-135.669;, + 86.864;-50.848;-92.566;, + 86.864;-42.848;-92.566;, + 86.847;-49.987;-135.669;, + 86.847;-43.709;-135.669;, + 89.693;-44.02;-92.566;, + 84.036;-49.676;-92.566;, + 89.067;-44.628;-135.669;, + 84.627;-49.068;-135.669;, + 89.579;-46.848;-135.669;, + 84.116;-46.848;-135.669;, + 88.779;-48.779;-135.669;, + 84.916;-44.916;-135.669;, + 86.847;-49.579;-135.669;, + 86.847;-44.116;-135.669;, + 88.779;-44.916;-135.669;, + 84.916;-48.779;-135.669;, + 90.345;-46.848;-120.592;, + 83.384;-46.848;-120.592;, + 89.325;-49.309;-120.592;, + 84.403;-44.387;-120.592;, + 86.864;-50.328;-120.592;, + 86.864;-43.368;-120.592;, + 89.325;-44.387;-120.592;, + 84.403;-49.309;-120.592;, + 82.864;-46.848;-134.169;, + 84.036;-44.02;-134.169;, + 89.693;-49.676;-134.169;, + 86.864;-50.848;-134.169;, + 86.864;-42.848;-134.169;, + 89.693;-44.02;-134.169;, + 84.036;-49.676;-134.169;, + 90.864;-46.848;-134.169;, + 90.345;-46.848;-134.169;, + 89.325;-49.309;-134.169;, + 86.864;-50.328;-134.169;, + 84.403;-49.309;-134.169;, + 83.384;-46.848;-134.169;, + 84.403;-44.387;-134.169;, + 86.864;-43.368;-134.169;, + 89.325;-44.387;-134.169;, + // Frontal_aux_gun + -10.089;-40.509;-371.495;, + -18.089;-40.509;-371.495;, + -17.211;-40.509;-414.597;, + -10.932;-40.509;-414.597;, + -11.261;-37.68;-371.495;, + -16.917;-43.337;-371.495;, + -16.292;-42.728;-414.597;, + -11.852;-38.289;-414.597;, + -14.089;-44.509;-371.495;, + -14.089;-36.509;-371.495;, + -14.072;-43.648;-414.597;, + -14.072;-37.369;-414.597;, + -16.917;-37.68;-371.495;, + -11.261;-43.337;-371.495;, + -16.292;-38.289;-414.597;, + -11.852;-42.728;-414.597;, + -16.803;-40.509;-414.597;, + -11.34;-40.509;-414.597;, + -16.003;-42.44;-414.597;, + -12.14;-38.577;-414.597;, + -14.072;-43.24;-414.597;, + -14.072;-37.777;-414.597;, + -16.003;-38.577;-414.597;, + -12.14;-42.44;-414.597;, + -17.569;-40.509;-409.572;, + -10.609;-40.509;-409.572;, + -16.55;-42.97;-409.572;, + -11.628;-38.047;-409.572;, + -14.089;-43.989;-409.572;, + -14.089;-37.028;-409.572;, + -16.55;-38.048;-409.572;, + -11.628;-42.97;-409.572;, + -10.089;-40.509;-413.098;, + -11.261;-37.68;-413.098;, + -16.917;-43.337;-413.098;, + -14.089;-44.509;-413.098;, + -14.089;-36.509;-413.098;, + -16.917;-37.68;-413.098;, + -11.261;-43.337;-413.098;, + -18.089;-40.509;-413.098;, + -17.569;-40.509;-413.097;, + -16.55;-42.97;-413.097;, + -14.089;-43.989;-413.097;, + -11.628;-42.97;-413.097;, + -10.609;-40.509;-413.097;, + -11.628;-38.047;-413.097;, + -14.089;-37.028;-413.097;, + -16.55;-38.047;-413.097;, + 10.089;-40.509;-371.495;, + 18.089;-40.509;-371.495;, + 17.211;-40.509;-414.597;, + 10.932;-40.509;-414.597;, + 11.261;-37.68;-371.495;, + 16.917;-43.337;-371.495;, + 16.292;-42.728;-414.597;, + 11.852;-38.289;-414.597;, + 14.089;-44.509;-371.495;, + 14.089;-36.509;-371.495;, + 14.072;-43.648;-414.597;, + 14.072;-37.369;-414.597;, + 16.917;-37.68;-371.495;, + 11.261;-43.337;-371.495;, + 16.292;-38.289;-414.597;, + 11.852;-42.728;-414.597;, + 16.803;-40.509;-414.597;, + 11.34;-40.509;-414.597;, + 16.003;-42.44;-414.597;, + 12.14;-38.577;-414.597;, + 14.072;-43.24;-414.597;, + 14.072;-37.777;-414.597;, + 16.003;-38.577;-414.597;, + 12.14;-42.44;-414.597;, + 17.569;-40.509;-409.572;, + 10.609;-40.509;-409.572;, + 16.55;-42.97;-409.572;, + 11.628;-38.048;-409.572;, + 14.089;-43.989;-409.572;, + 14.089;-37.028;-409.572;, + 16.55;-38.048;-409.572;, + 11.628;-42.97;-409.572;, + 10.089;-40.509;-413.098;, + 11.261;-37.68;-413.098;, + 16.917;-43.337;-413.098;, + 14.089;-44.509;-413.098;, + 14.089;-36.509;-413.098;, + 16.917;-37.68;-413.098;, + 11.261;-43.337;-413.098;, + 18.089;-40.509;-413.098;, + 17.569;-40.509;-413.097;, + 16.55;-42.97;-413.097;, + 14.089;-43.989;-413.097;, + 11.628;-42.97;-413.097;, + 10.609;-40.509;-413.097;, + 11.628;-38.047;-413.097;, + 14.089;-37.028;-413.097;, + 16.55;-38.047;-413.097;, + // Jet + -57.115;-36.134;162.212;, + -31.095;-36.134;108.358;, + -31.095;-36.134;138.226;, + -23.048;-36.134;168.117;, + -23.048;-36.134;198.0;, + -32.366;-44.276;108.358;, + -32.366;-44.276;138.226;, + -24.715;-46.819;168.117;, + -24.715;-46.819;198.0;, + -36.055;-51.627;108.358;, + -36.055;-51.627;138.226;, + -29.554;-56.458;168.117;, + -29.554;-56.458;198.0;, + -41.808;-57.466;108.358;, + -41.808;-57.466;138.226;, + -37.091;-64.108;168.117;, + -37.091;-64.108;198.0;, + -49.065;-61.219;108.358;, + -49.065;-61.219;138.226;, + -46.588;-69.02;168.117;, + -46.588;-69.02;198.0;, + -57.115;-62.513;108.358;, + -57.115;-62.513;138.226;, + -57.115;-70.712;168.117;, + -57.115;-70.712;198.0;, + -65.165;-61.219;108.358;, + -65.165;-61.219;138.226;, + -67.642;-69.02;168.117;, + -67.642;-69.02;198.0;, + -72.421;-57.466;108.358;, + -72.421;-57.466;138.226;, + -77.139;-64.108;168.117;, + -77.139;-64.108;198.0;, + -78.174;-51.627;108.358;, + -78.174;-51.627;138.226;, + -84.676;-56.458;168.117;, + -84.676;-56.458;198.0;, + -81.864;-44.276;108.358;, + -81.864;-44.276;138.226;, + -89.515;-46.819;168.117;, + -89.515;-46.819;198.0;, + -83.135;-36.134;108.358;, + -83.135;-36.134;138.226;, + -91.182;-36.134;168.117;, + -91.182;-36.134;198.0;, + -81.864;-27.991;108.358;, + -81.864;-27.991;138.226;, + -89.515;-25.449;168.117;, + -89.515;-25.449;198.0;, + -78.174;-20.641;108.358;, + -78.174;-20.641;138.226;, + -84.676;-15.81;168.117;, + -84.676;-15.81;198.0;, + -72.421;-14.802;108.358;, + -72.421;-14.802;138.226;, + -77.139;-8.16;168.117;, + -77.139;-8.16;198.0;, + -65.165;-11.049;108.358;, + -65.165;-11.049;138.226;, + -67.642;-3.248;168.117;, + -67.642;-3.248;198.0;, + -57.115;-9.755;108.358;, + -57.115;-9.755;138.226;, + -57.115;-1.556;168.117;, + -57.115;-1.556;198.0;, + -49.065;-11.049;108.358;, + -49.065;-11.049;138.226;, + -46.588;-3.248;168.117;, + -46.588;-3.248;198.0;, + -41.808;-14.802;108.358;, + -41.808;-14.802;138.226;, + -37.091;-8.16;168.117;, + -37.091;-8.16;198.0;, + -36.055;-20.641;108.358;, + -36.055;-20.641;138.226;, + -29.554;-15.81;168.117;, + -29.554;-15.81;198.0;, + -32.366;-27.991;108.358;, + -32.366;-27.991;138.226;, + -24.715;-25.449;168.117;, + -24.715;-25.449;198.0;, + -26.366;-36.134;181.304;, + -27.908;-46.017;181.304;, + -32.354;-54.872;181.304;, + -39.201;-61.822;181.304;, + -47.73;-66.232;181.304;, + -57.115;-67.741;181.304;, + -66.5;-66.232;181.304;, + -75.029;-61.822;181.304;, + -81.876;-54.872;181.304;, + -86.321;-46.017;181.304;, + -87.863;-36.134;181.304;, + -86.321;-26.251;181.304;, + -81.876;-17.396;181.304;, + -75.029;-10.446;181.304;, + -66.5;-6.035;181.304;, + -57.115;-4.527;181.304;, + -47.73;-6.035;181.304;, + -39.201;-10.446;181.304;, + -32.354;-17.396;181.304;, + -27.908;-26.251;181.304;, + -41.345;-36.134;162.212;, + -42.174;-41.447;162.212;, + -44.534;-46.147;162.212;, + -48.091;-49.757;162.212;, + -52.421;-51.997;162.212;, + -57.115;-52.751;162.212;, + -61.809;-51.997;162.212;, + -66.139;-49.757;162.212;, + -69.696;-46.147;162.212;, + -72.055;-41.447;162.212;, + -72.884;-36.134;162.212;, + -72.055;-30.821;162.212;, + -69.696;-26.121;162.212;, + -66.139;-22.511;162.212;, + -61.809;-20.271;162.212;, + -57.115;-19.517;162.212;, + -52.421;-20.271;162.212;, + -48.091;-22.511;162.212;, + -44.534;-26.121;162.212;, + -42.174;-30.821;162.212;, + 57.115;-36.134;162.212;, + 31.095;-36.134;138.226;, + 23.048;-36.134;168.117;, + 23.048;-36.134;198.0;, + 32.366;-44.276;138.226;, + 24.715;-46.819;168.117;, + 24.715;-46.819;198.0;, + 36.055;-51.627;138.226;, + 29.554;-56.458;168.117;, + 29.554;-56.458;198.0;, + 41.808;-57.466;138.226;, + 37.091;-64.108;168.117;, + 37.091;-64.108;198.0;, + 49.065;-61.219;138.226;, + 46.588;-69.02;168.117;, + 46.588;-69.02;198.0;, + 57.115;-62.513;138.226;, + 57.115;-70.712;168.117;, + 57.115;-70.712;198.0;, + 65.165;-61.219;138.226;, + 67.642;-69.02;168.117;, + 67.642;-69.02;198.0;, + 72.421;-57.466;138.226;, + 77.139;-64.108;168.117;, + 77.139;-64.108;198.0;, + 78.174;-51.627;138.226;, + 84.676;-56.458;168.117;, + 84.676;-56.458;198.0;, + 81.864;-44.276;138.226;, + 89.515;-46.819;168.117;, + 89.515;-46.819;198.0;, + 83.135;-36.134;138.226;, + 91.182;-36.134;168.117;, + 91.182;-36.134;198.0;, + 81.864;-27.991;138.226;, + 89.515;-25.449;168.117;, + 89.515;-25.449;198.0;, + 78.174;-20.641;138.226;, + 84.676;-15.81;168.117;, + 84.676;-15.81;198.0;, + 72.421;-14.802;138.226;, + 77.139;-8.16;168.117;, + 77.139;-8.16;198.0;, + 65.165;-11.049;138.226;, + 67.642;-3.248;168.117;, + 67.642;-3.248;198.0;, + 57.115;-9.755;138.226;, + 57.115;-1.556;168.117;, + 57.115;-1.556;198.0;, + 49.065;-11.049;138.226;, + 46.588;-3.248;168.117;, + 46.588;-3.248;198.0;, + 41.808;-14.802;138.226;, + 37.091;-8.16;168.117;, + 37.091;-8.16;198.0;, + 36.055;-20.641;138.226;, + 29.554;-15.81;168.117;, + 29.554;-15.81;198.0;, + 32.366;-27.991;138.226;, + 24.715;-25.449;168.117;, + 24.715;-25.449;198.0;, + 26.366;-36.134;181.304;, + 27.908;-46.017;181.304;, + 32.354;-54.872;181.304;, + 39.201;-61.822;181.304;, + 47.73;-66.232;181.304;, + 57.115;-67.741;181.304;, + 66.5;-66.232;181.304;, + 75.029;-61.822;181.304;, + 81.876;-54.872;181.304;, + 86.321;-46.017;181.304;, + 87.863;-36.134;181.304;, + 86.321;-26.251;181.304;, + 81.876;-17.396;181.304;, + 75.029;-10.446;181.304;, + 66.5;-6.035;181.304;, + 57.115;-4.527;181.304;, + 47.73;-6.035;181.304;, + 39.201;-10.446;181.304;, + 32.354;-17.396;181.304;, + 27.908;-26.251;181.304;, + 41.345;-36.134;162.212;, + 42.174;-41.447;162.212;, + 44.534;-46.147;162.212;, + 48.091;-49.757;162.212;, + 52.421;-51.997;162.212;, + 57.115;-52.751;162.212;, + 61.809;-51.997;162.212;, + 66.139;-49.757;162.212;, + 69.696;-46.147;162.212;, + 72.055;-41.447;162.212;, + 72.884;-36.134;162.212;, + 72.055;-30.821;162.212;, + 69.696;-26.121;162.212;, + 66.139;-22.511;162.212;, + 61.809;-20.271;162.212;, + 57.115;-19.517;162.212;, + 52.421;-20.271;162.212;, + 48.091;-22.511;162.212;, + 44.534;-26.121;162.212;, + 42.174;-30.821;162.212;, + // Chassis + -26.947;-59.0;-362.944;, + -33.909;-54.669;-369.41;, + -40.975;-27.085;-378.696;, + -44.781;-1.174;-369.597;, + -19.427;-59.0;-374.238;, + -27.112;-55.116;-384.151;, + -22.776;-26.796;-411.854;, + -25.883;-6.224;-410.241;, + -21.03;7.53;-402.982;, + -9.824;-59.0;-377.821;, + -12.512;-56.097;-391.703;, + -8.726;-26.952;-418.684;, + -9.457;-6.75;-417.715;, + -11.312;6.687;-409.666;, + 0.0;-59.0;-377.733;, + 0.0;-27.123;-419.574;, + 0.0;-6.75;-418.86;, + 0.0;6.687;-410.383;, + -27.942;11.605;-390.815;, + 0.0;53.903;-275.446;, + 0.0;-55.437;-142.48;, + 0.0;66.854;-121.799;, + 0.0;-72.379;44.869;, + 0.0;69.52;1.923;, + 0.0;-74.631;96.1;, + -121.896;70.626;18.189;, + -16.373;77.212;17.03;, + 0.0;33.709;182.908;, + -59.005;-70.82;41.769;, + -44.5;-74.631;96.225;, + -136.288;-13.537;110.597;, + -137.548;20.398;112.398;, + -6.083;69.648;3.831;, + -37.87;-54.936;-146.054;, + -48.825;70.205;144.602;, + -137.196;26.687;107.081;, + -24.172;-75.856;163.724;, + -137.064;28.456;3.424;, + -91.903;70.816;144.602;, + -86.405;-75.133;143.461;, + -99.206;-72.834;181.656;, + -126.747;7.515;186.814;, + -96.463;-73.274;215.72;, + -6.083;48.029;152.92;, + -130.5;28.898;2.13;, + -120.507;58.961;4.286;, + -93.937;-38.661;-128.656;, + -130.5;-11.852;-89.538;, + -130.5;28.898;-95.354;, + -108.409;53.098;-112.728;, + 0.0;-78.487;-266.874;, + -56.332;-49.372;-275.22;, + -65.603;-16.121;-269.862;, + -63.974;10.227;-278.579;, + -52.65;36.467;-279.051;, + -16.586;-77.891;-266.899;, + -43.173;-53.086;-336.826;, + -51.187;-23.106;-340.973;, + -57.347;7.757;-309.764;, + -38.692;45.207;-280.493;, + -79.558;63.642;-121.799;, + -87.369;69.648;2.595;, + -14.383;53.267;-275.643;, + -32.471;66.34;-121.799;, + -44.5;69.648;4.244;, + -89.78;-70.82;42.607;, + -95.253;-52.659;-103.78;, + 0.0;-78.815;-332.259;, + -118.88;-49.64;-87.447;, + -104.517;-74.631;94.037;, + -136.63;-48.448;111.434;, + -22.373;-70.306;215.177;, + -194.557;-87.538;81.644;, + -174.312;13.325;12.722;, + -214.403;-96.243;58.884;, + -174.312;14.305;-77.322;, + -129.107;-77.677;57.19;, + -128.656;-79.667;-79.297;, + -223.548;-91.565;-67.248;, + -136.969;-68.03;92.946;, + -222.178;-92.131;62.289;, + -239.539;-55.251;65.96;, + -240.591;-54.514;-67.946;, + -166.706;-60.698;100.0;, + -179.549;-26.131;100.0;, + -12.444;-28.227;209.87;, + -38.734;-75.42;143.689;, + -90.528;78.154;14.397;, + -238.07;-46.27;63.346;, + -238.794;-45.461;-68.609;, + -225.281;-39.88;83.341;, + -208.142;-84.816;78.022;, + -174.312;13.325;88.487;, + -228.544;-36.345;76.858;, + -215.567;-95.711;-67.885;, + -175.25;6.254;95.5;, + -36.306;-46.98;139.708;, + -6.083;33.709;182.475;, + -47.528;77.346;14.397;, + -33.751;2.152;203.696;, + -88.225;-0.323;203.696;, + -56.65;6.747;203.696;, + -16.373;48.286;181.996;, + -16.423;78.593;95.771;, + -48.389;78.811;93.99;, + -49.278;48.589;181.092;, + -122.174;71.836;91.952;, + -122.461;46.637;164.993;, + -92.384;49.132;181.092;, + -90.852;77.888;93.647;, + 0.0;-40.375;189.906;, + -118.287;58.003;142.815;, + -16.373;69.945;145.953;, + 0.0;-66.261;169.684;, + -6.083;-41.099;189.365;, + 0.0;59.468;103.877;, + -6.083;60.782;102.729;, + 0.0;47.477;153.583;, + -140.348;-19.793;-87.381;, + -131.233;-49.259;-85.454;, + -172.535;-0.291;-76.608;, + -137.521;-69.2;-78.568;, + -214.208;-83.129;-69.165;, + -228.166;-52.396;-69.997;, + 0.0;-71.035;-19.344;, + -59.005;-70.82;-15.924;, + -139.607;-19.483;-75.603;, + -130.492;-48.948;-76.203;, + -171.794;0.02;-72.132;, + -136.78;-68.889;-74.732;, + -213.467;-82.818;-64.48;, + -227.425;-52.085;-63.443;, + -31.29;-56.485;-339.538;, + 0.0;-58.839;-197.245;, + -28.472;-75.599;168.11;, + -84.737;-74.938;147.722;, + -95.047;-73.609;180.137;, + -92.325;-73.522;214.308;, + -26.673;-70.305;215.171;, + -16.742;-28.652;209.876;, + -38.642;-75.198;147.983;, + -37.305;-2.107;203.752;, + -84.431;-4.656;203.539;, + -56.714;2.448;203.715;, + -96.448;2.586;138.553;, + -20.038;1.786;138.764;, + -50.091;2.176;138.754;, + -100.741;-47.189;138.278;, + -12.517;-36.977;139.038;, + -121.811;-40.481;180.398;, + -102.947;-34.351;210.309;, + -98.972;-34.934;210.417;, + 0.0;-53.509;-91.527;, + -16.062;-59.165;-333.973;, + -49.188;-53.282;-102.645;, + -96.808;-10.897;-159.207;, + -73.035;-39.288;-184.8;, + -54.114;-54.645;-196.135;, + -17.994;-57.198;-197.396;, + -81.411;45.341;-175.192;, + -56.142;58.385;-184.7;, + -26.502;61.281;-184.7;, + 0.0;62.177;-184.7;, + -89.78;-70.82;-15.924;, + -95.877;18.264;-162.115;, + -44.321;31.178;-316.178;, + -39.209;26.118;-341.648;, + -24.166;-75.835;-305.806;, + -50.197;-51.33;-306.023;, + -57.917;-21.096;-305.418;, + -34.393;19.865;-366.069;, + -50.732;3.04;-341.222;, + -37.776;-5.586;-391.493;, + 0.0;-80.534;-298.783;, + -18.299;23.315;-368.465;, + 0.0;51.233;-292.134;, + -12.467;17.672;-386.677;, + 0.0;17.744;-388.681;, + -22.575;32.507;-339.342;, + -17.954;45.106;-316.112;, + -7.59;51.067;-299.492;, + -17.398;24.221;-368.422;, + -21.72;33.321;-339.777;, + -17.002;45.857;-316.531;, + -6.86;51.573;-300.471;, + 0.0;51.587;-293.836;, + -11.783;18.828;-385.839;, + 0.0;18.824;-387.718;, + -18.03;24.032;-368.443;, + 0.0;51.692;-292.935;, + -12.266;18.5;-386.334;, + 0.0;18.544;-388.312;, + -22.331;33.115;-339.637;, + -17.604;45.695;-316.314;, + -7.383;51.539;-300.068;, + -66.039;-48.139;-139.344;, + 0.0;-58.784;-355.889;, + -13.474;-59.0;-359.417;, + -11.065;-79.839;-302.304;, + -30.011;-74.243;-275.047;, + -18.253;-68.43;-332.566;, + -20.751;-59.105;-335.006;, + -42.508;-53.861;-275.181;, + -34.827;-58.588;-305.915;, + 0.0;-56.307;-394.398;, + 0.0;-41.069;-405.871;, + -31.712;-26.918;-396.57;, + -17.315;-43.634;-398.056;, + 0.0;-58.835;-334.045;, + -4.83;-41.102;-405.137;, + -9.441;-77.255;-332.577;, + 26.947;-59.0;-362.944;, + 33.909;-54.669;-369.41;, + 40.975;-27.085;-378.696;, + 44.781;-1.174;-369.597;, + 19.427;-59.0;-374.238;, + 27.112;-55.116;-384.151;, + 22.776;-26.796;-411.854;, + 25.883;-6.224;-410.241;, + 21.03;7.53;-402.982;, + 9.824;-59.0;-377.821;, + 12.512;-56.097;-391.703;, + 8.726;-26.952;-418.684;, + 9.457;-6.75;-417.715;, + 11.312;6.687;-409.666;, + 27.942;11.605;-390.815;, + 121.896;70.626;18.189;, + 16.373;77.212;17.03;, + 59.005;-70.82;41.769;, + 44.5;-74.631;96.225;, + 136.288;-13.537;110.597;, + 137.548;20.398;112.398;, + 6.083;69.648;3.831;, + 37.87;-54.936;-146.054;, + 48.825;70.205;144.602;, + 137.196;26.687;107.081;, + 24.172;-75.856;163.724;, + 137.064;28.456;3.424;, + 91.903;70.816;144.602;, + 86.405;-75.133;143.461;, + 99.206;-72.834;181.656;, + 126.747;7.515;186.814;, + 96.463;-73.274;215.72;, + 6.083;48.029;152.92;, + 130.5;28.898;2.13;, + 120.507;58.961;4.286;, + 93.937;-38.661;-128.656;, + 130.5;-11.852;-89.538;, + 130.5;28.898;-95.354;, + 108.409;53.098;-112.728;, + 56.332;-49.372;-275.22;, + 65.603;-16.121;-269.862;, + 63.974;10.227;-278.579;, + 52.65;36.467;-279.051;, + 16.586;-77.891;-266.899;, + 43.173;-53.086;-336.826;, + 51.187;-23.106;-340.973;, + 57.347;7.757;-309.764;, + 38.692;45.207;-280.493;, + 79.558;63.642;-121.799;, + 87.369;69.648;2.595;, + 14.383;53.267;-275.643;, + 32.471;66.34;-121.799;, + 44.5;69.648;4.244;, + 89.78;-70.82;42.607;, + 95.253;-52.659;-103.78;, + 118.88;-49.64;-87.447;, + 104.517;-74.631;94.037;, + 136.63;-48.448;111.434;, + 22.373;-70.306;215.177;, + 194.557;-87.538;81.644;, + 174.312;13.325;12.722;, + 214.403;-96.243;58.884;, + 174.312;14.305;-77.322;, + 129.107;-77.677;57.19;, + 128.656;-79.667;-79.297;, + 223.548;-91.565;-67.248;, + 136.969;-68.03;92.946;, + 222.178;-92.131;62.289;, + 239.539;-55.251;65.96;, + 240.591;-54.514;-67.946;, + 166.706;-60.698;100.0;, + 179.549;-26.131;100.0;, + 12.444;-28.227;209.87;, + 38.734;-75.42;143.689;, + 90.528;78.154;14.397;, + 238.07;-46.27;63.346;, + 238.794;-45.461;-68.609;, + 225.281;-39.88;83.341;, + 208.142;-84.816;78.022;, + 174.312;13.325;88.487;, + 228.544;-36.345;76.858;, + 215.567;-95.711;-67.885;, + 175.25;6.254;95.5;, + 36.306;-46.98;139.708;, + 6.083;33.709;182.475;, + 47.528;77.346;14.397;, + 33.751;2.152;203.696;, + 88.225;-0.323;203.696;, + 56.65;6.747;203.696;, + 16.373;48.286;181.996;, + 16.423;78.593;95.771;, + 48.389;78.811;93.99;, + 49.278;48.589;181.092;, + 122.174;71.836;91.952;, + 122.461;46.637;164.993;, + 92.384;49.132;181.092;, + 90.852;77.888;93.647;, + 118.287;58.003;142.815;, + 16.373;69.945;145.953;, + 6.083;-41.099;189.365;, + 6.083;60.782;102.729;, + 140.348;-19.793;-87.381;, + 131.233;-49.259;-85.454;, + 172.535;-0.291;-76.608;, + 137.521;-69.2;-78.568;, + 214.208;-83.129;-69.165;, + 228.166;-52.396;-69.997;, + 59.005;-70.82;-15.924;, + 139.607;-19.483;-75.603;, + 130.492;-48.948;-76.203;, + 171.794;0.02;-72.132;, + 136.78;-68.889;-74.732;, + 213.467;-82.818;-64.48;, + 227.425;-52.085;-63.443;, + 31.29;-56.485;-339.538;, + 28.472;-75.599;168.11;, + 84.737;-74.938;147.722;, + 95.047;-73.609;180.137;, + 92.325;-73.522;214.308;, + 26.673;-70.305;215.171;, + 16.742;-28.652;209.876;, + 38.642;-75.198;147.983;, + 37.305;-2.107;203.752;, + 84.431;-4.656;203.539;, + 56.714;2.448;203.715;, + 96.448;2.586;138.553;, + 20.038;1.786;138.764;, + 50.091;2.176;138.754;, + 100.741;-47.189;138.278;, + 12.517;-36.977;139.038;, + 121.811;-40.481;180.398;, + 102.947;-34.351;210.309;, + 98.972;-34.934;210.417;, + 16.062;-59.165;-333.973;, + 49.188;-53.282;-102.645;, + 96.808;-10.897;-159.207;, + 73.035;-39.288;-184.8;, + 54.114;-54.645;-196.135;, + 17.994;-57.198;-197.396;, + 81.411;45.341;-175.192;, + 56.142;58.385;-184.7;, + 26.502;61.281;-184.7;, + 89.78;-70.82;-15.924;, + 95.877;18.264;-162.115;, + 44.321;31.178;-316.178;, + 39.209;26.118;-341.648;, + 24.166;-75.835;-305.806;, + 50.197;-51.33;-306.023;, + 57.917;-21.096;-305.418;, + 34.393;19.865;-366.069;, + 50.732;3.04;-341.222;, + 37.776;-5.586;-391.493;, + 18.299;23.315;-368.465;, + 12.467;17.672;-386.677;, + 22.575;32.507;-339.342;, + 17.954;45.106;-316.112;, + 7.59;51.067;-299.492;, + 17.398;24.221;-368.422;, + 21.72;33.321;-339.777;, + 17.002;45.857;-316.531;, + 6.86;51.573;-300.471;, + 11.783;18.828;-385.839;, + 18.03;24.032;-368.443;, + 12.266;18.5;-386.334;, + 22.331;33.115;-339.637;, + 17.604;45.695;-316.314;, + 7.383;51.539;-300.068;, + 66.039;-48.139;-139.344;, + 13.474;-59.0;-359.417;, + 11.065;-79.839;-302.304;, + 30.011;-74.243;-275.047;, + 18.253;-68.43;-332.566;, + 20.751;-59.105;-335.006;, + 42.508;-53.861;-275.181;, + 34.827;-58.588;-305.915;, + 31.712;-26.918;-396.57;, + 17.315;-43.634;-398.056;, + 4.83;-41.102;-405.137;, + 9.441;-77.255;-332.577;, + // Bubble + -17.398;24.221;-368.422;, + 0.0;36.181;-371.016;, + -21.72;33.321;-339.777;, + -7.334;34.239;-369.601;, + -17.002;45.857;-316.531;, + -6.86;51.573;-300.471;, + 0.0;51.587;-293.836;, + 0.0;49.493;-318.225;, + -11.783;18.828;-385.839;, + 0.0;18.824;-387.718;, + -9.141;47.407;-319.659;, + -10.318;41.586;-350.709;, + 0.0;44.103;-351.357;, + -17.328;23.031;-367.877;, + 0.0;35.072;-370.339;, + -21.462;32.159;-339.239;, + -7.94;35.271;-370.222;, + -16.7;44.713;-315.851;, + -6.884;50.284;-300.197;, + 0.0;50.32;-293.62;, + 0.0;48.209;-319.348;, + -11.739;17.564;-385.482;, + 0.0;17.586;-387.326;, + -9.45;48.673;-319.892;, + -10.871;42.789;-351.121;, + 0.0;42.876;-350.937;, + 17.398;24.221;-368.422;, + 21.72;33.321;-339.777;, + 17.002;45.857;-316.531;, + 6.86;51.573;-300.471;, + 11.783;18.828;-385.839;, + 7.94;35.271;-370.222;, + 9.45;48.673;-319.892;, + 10.871;42.789;-351.121;; + + 3000; + // Turret_base + 3;1,12,13;, + 3;2,13,14;, + 3;42,3,14;, + 3;4,38,44;, + 3;4,15,16;, + 3;5,16,17;, + 3;6,17,18;, + 3;7,18,19;, + 3;8,19,20;, + 3;9,20,21;, + 3;10,21,22;, + 3;11,22,12;, + 3;12,23,24;, + 3;37,14,13;, + 3;24,35,37;, + 3;14,37,32;, + 3;36,15,44;, + 3;39,25,36;, + 3;36,25,16;, + 3;16,25,26;, + 3;17,26,27;, + 3;18,27,28;, + 3;19,28,29;, + 3;20,29,30;, + 3;21,30,31;, + 3;22,31,23;, + 3;0,26,25;, + 3;40,35,43;, + 3;23,0,24;, + 3;0,43,35;, + 3;33,41,39;, + 3;0,25,39;, + 3;6,7,33;, + 3;33,36,44;, + 3;5,6,33;, + 3;41,40,43;, + 3;27,26,0;, + 3;40,41,33;, + 3;29,28,0;, + 3;34,37,35;, + 3;31,30,0;, + 3;33,7,8;, + 3;34,1,2;, + 3;34,42,32;, + 3;34,2,3;, + 3;9,10,34;, + 3;33,38,4;, + 3;34,10,11;, + 3;0,39,43;, + 3;0,35,24;, + 3;1,13,2;, + 3;2,14,3;, + 3;42,14,32;, + 3;4,44,15;, + 3;4,16,5;, + 3;5,17,6;, + 3;6,18,7;, + 3;7,19,8;, + 3;8,20,9;, + 3;9,21,10;, + 3;10,22,11;, + 3;11,12,1;, + 3;12,24,13;, + 3;37,13,24;, + 3;36,16,15;, + 3;16,26,17;, + 3;17,27,18;, + 3;18,28,19;, + 3;19,29,20;, + 3;20,30,21;, + 3;21,31,22;, + 3;22,23,12;, + 3;33,39,36;, + 3;33,44,38;, + 3;41,43,39;, + 3;27,0,28;, + 3;40,33,34;, + 3;29,0,30;, + 3;34,35,40;, + 3;31,0,23;, + 3;33,8,9;, + 3;34,32,37;, + 3;34,3,42;, + 3;9,34,33;, + 3;33,4,5;, + 3;34,11,1;, + // Gatling_base + 3;46,61,62;, + 3;45,63,64;, + 3;50,62,65;, + 3;58,66,63;, + 3;49,64,67;, + 3;55,52,48;, + 3;60,48,59;, + 3;54,67,68;, + 3;53,65,66;, + 3;56,51,47;, + 3;57,68,61;, + 3;53,57,46;, + 3;57,53,58;, + 3;54,57,45;, + 3;61,47,51;, + 3;63,48,52;, + 3;62,51,56;, + 3;66,59,48;, + 3;64,52,55;, + 3;67,55,60;, + 3;65,56,59;, + 3;68,60,47;, + 3;46,62,50;, + 3;45,64,49;, + 3;50,65,53;, + 3;58,63,45;, + 3;49,67,54;, + 3;55,48,60;, + 3;60,59,56;, + 3;54,68,57;, + 3;53,66,58;, + 3;56,47,60;, + 3;57,61,46;, + 3;53,46,50;, + 3;57,58,45;, + 3;54,45,49;, + 3;61,51,62;, + 3;63,52,64;, + 3;62,56,65;, + 3;66,48,63;, + 3;64,55,67;, + 3;67,60,68;, + 3;65,59,66;, + 3;68,47,61;, + // Gatling_base_2 + 3;69,70,74;, + 3;73,74,78;, + 3;77,78,82;, + 3;70,71,75;, + 3;74,75,79;, + 3;78,79,83;, + 3;71,72,76;, + 3;75,76,80;, + 3;79,80,84;, + 3;81,82,86;, + 3;85,86,90;, + 3;89,90,94;, + 3;82,83,87;, + 3;86,87,91;, + 3;90,91,95;, + 3;83,84,88;, + 3;87,88,92;, + 3;91,92,96;, + 3;93,94,98;, + 3;97,98,102;, + 3;101,102,106;, + 3;94,95,99;, + 3;98,99,103;, + 3;102,103,107;, + 3;95,96,100;, + 3;99,100,104;, + 3;103,104,108;, + 3;105,106,110;, + 3;109,110,114;, + 3;113,114,70;, + 3;106,107,111;, + 3;110,111,115;, + 3;114,115,71;, + 3;107,108,112;, + 3;111,112,116;, + 3;115,116,72;, + 3;72,116,117;, + 3;76,117,119;, + 3;80,119,88;, + 3;116,112,118;, + 3;117,118,120;, + 3;119,120,92;, + 3;112,108,104;, + 3;118,104,100;, + 3;120,100,96;, + 3;105,109,121;, + 3;101,121,123;, + 3;97,123,89;, + 3;109,113,122;, + 3;121,122,124;, + 3;123,124,85;, + 3;113,69,73;, + 3;122,73,77;, + 3;124,77,81;, + 3;69,74,73;, + 3;73,78,77;, + 3;77,82,81;, + 3;70,75,74;, + 3;74,79,78;, + 3;78,83,82;, + 3;71,76,75;, + 3;75,80,79;, + 3;79,84,83;, + 3;81,86,85;, + 3;85,90,89;, + 3;89,94,93;, + 3;82,87,86;, + 3;86,91,90;, + 3;90,95,94;, + 3;83,88,87;, + 3;87,92,91;, + 3;91,96,95;, + 3;93,98,97;, + 3;97,102,101;, + 3;101,106,105;, + 3;94,99,98;, + 3;98,103,102;, + 3;102,107,106;, + 3;95,100,99;, + 3;99,104,103;, + 3;103,108,107;, + 3;105,110,109;, + 3;109,114,113;, + 3;113,70,69;, + 3;106,111,110;, + 3;110,115,114;, + 3;114,71,70;, + 3;107,112,111;, + 3;111,116,115;, + 3;115,72,71;, + 3;72,117,76;, + 3;76,119,80;, + 3;80,88,84;, + 3;116,118,117;, + 3;117,120,119;, + 3;119,92,88;, + 3;112,104,118;, + 3;118,100,120;, + 3;120,96,92;, + 3;105,121,101;, + 3;101,123,97;, + 3;97,89,93;, + 3;109,122,121;, + 3;121,124,123;, + 3;123,85,89;, + 3;113,73,122;, + 3;122,77,124;, + 3;124,81,85;, + // Gatling_mid + 3;126,149,150;, + 3;125,151,152;, + 3;130,150,153;, + 3;138,154,151;, + 3;129,152,155;, + 3;153,145,146;, + 3;161,185,184;, + 3;163,187,186;, + 3;159,183,182;, + 3;141,127,131;, + 3;143,128,132;, + 3;160,184,183;, + 3;164,188,187;, + 3;142,131,136;, + 3;178,137,126;, + 3;175,126,130;, + 3;177,173,130;, + 3;167,179,178;, + 3;157,181,188;, + 3;171,177,180;, + 3;133,138,180;, + 3;168,160,159;, + 3;160,168,169;, + 3;137,156,149;, + 3;150,142,145;, + 3;152,144,147;, + 3;171,172,164;, + 3;154,146,143;, + 3;167,159,158;, + 3;149,141,142;, + 3;151,143,144;, + 3;162,170,171;, + 3;168,178,175;, + 3;172,180,176;, + 3;166,174,179;, + 3;158,182,181;, + 3;179,134,137;, + 3;146,139,128;, + 3;144,132,135;, + 3;170,173,177;, + 3;147,135,140;, + 3;145,136,139;, + 3;148,140,127;, + 3;162,186,185;, + 3;125,129,174;, + 3;162,161,169;, + 3;138,125,176;, + 3;174,129,134;, + 3;156,148,141;, + 3;172,165,157;, + 3;169,175,173;, + 3;165,176,174;, + 3;155,147,148;, + 3;134,155,156;, + 3;133,153,154;, + 3;165,166,158;, + 3;131,127,185;, + 3;131,186,187;, + 3;127,140,184;, + 3;140,135,183;, + 3;135,132,182;, + 3;182,132,128;, + 3;181,128,139;, + 3;188,139,136;, + 3;126,150,130;, + 3;125,152,129;, + 3;130,153,133;, + 3;138,151,125;, + 3;129,155,134;, + 3;153,146,154;, + 3;161,184,160;, + 3;163,186,162;, + 3;159,182,158;, + 3;141,131,142;, + 3;143,132,144;, + 3;160,183,159;, + 3;164,187,163;, + 3;142,136,145;, + 3;178,126,175;, + 3;175,130,173;, + 3;177,130,133;, + 3;167,178,168;, + 3;157,188,164;, + 3;171,180,172;, + 3;133,180,177;, + 3;168,159,167;, + 3;160,169,161;, + 3;137,149,126;, + 3;150,145,153;, + 3;152,147,155;, + 3;171,164,163;, + 3;154,143,151;, + 3;167,158,166;, + 3;149,142,150;, + 3;151,144,152;, + 3;162,171,163;, + 3;168,175,169;, + 3;172,176,165;, + 3;166,179,167;, + 3;158,181,157;, + 3;179,137,178;, + 3;146,128,143;, + 3;144,135,147;, + 3;170,177,171;, + 3;147,140,148;, + 3;145,139,146;, + 3;148,127,141;, + 3;162,185,161;, + 3;125,174,176;, + 3;162,169,170;, + 3;138,176,180;, + 3;174,134,179;, + 3;156,141,149;, + 3;172,157,164;, + 3;169,173,170;, + 3;165,174,166;, + 3;155,148,156;, + 3;134,156,137;, + 3;133,154,138;, + 3;165,158,157;, + 3;131,185,186;, + 3;131,187,136;, + 3;127,184,185;, + 3;140,183,184;, + 3;135,182,183;, + 3;182,128,181;, + 3;181,139,188;, + 3;188,136,187;, + // Gatling_fin_1 + 3;190,213,214;, + 3;189,215,216;, + 3;194,214,217;, + 3;202,218,215;, + 3;193,216,219;, + 3;217,209,210;, + 3;200,251,252;, + 3;195,191,249;, + 3;191,204,248;, + 3;204,199,247;, + 3;199,196,246;, + 3;224,248,247;, + 3;228,252,251;, + 3;212,204,191;, + 3;246,196,192;, + 3;235,236,228;, + 3;218,210,207;, + 3;231,243,242;, + 3;221,245,252;, + 3;235,241,244;, + 3;245,192,203;, + 3;211,199,204;, + 3;227,251,250;, + 3;208,196,199;, + 3;223,247,246;, + 3;251,200,195;, + 3;222,246,245;, + 3;209,200,203;, + 3;224,232,233;, + 3;213,205,206;, + 3;215,207,208;, + 3;232,242,239;, + 3;234,237,241;, + 3;201,220,213;, + 3;226,234,235;, + 3;232,224,223;, + 3;214,206,209;, + 3;216,208,211;, + 3;226,225,233;, + 3;233,239,237;, + 3;236,229,221;, + 3;229,230,222;, + 3;236,244,240;, + 3;230,238,243;, + 3;197,217,218;, + 3;229,240,238;, + 3;210,203,192;, + 3;226,250,249;, + 3;220,212,205;, + 3;205,191,195;, + 3;225,249,248;, + 3;231,223,222;, + 3;219,211,212;, + 3;198,219,220;, + 3;207,192,196;, + 3;206,195,200;, + 3;189,193,238;, + 3;202,189,240;, + 3;238,193,198;, + 3;243,198,201;, + 3;242,201,190;, + 3;239,190,194;, + 3;241,237,194;, + 3;197,202,244;, + 3;190,214,194;, + 3;189,216,193;, + 3;194,217,197;, + 3;202,215,189;, + 3;193,219,198;, + 3;217,210,218;, + 3;200,252,203;, + 3;195,249,250;, + 3;191,248,249;, + 3;204,247,248;, + 3;199,246,247;, + 3;224,247,223;, + 3;228,251,227;, + 3;212,191,205;, + 3;246,192,245;, + 3;235,228,227;, + 3;218,207,215;, + 3;231,242,232;, + 3;221,252,228;, + 3;235,244,236;, + 3;245,203,252;, + 3;211,204,212;, + 3;227,250,226;, + 3;208,199,211;, + 3;223,246,222;, + 3;251,195,250;, + 3;222,245,221;, + 3;209,203,210;, + 3;224,233,225;, + 3;213,206,214;, + 3;215,208,216;, + 3;232,239,233;, + 3;234,241,235;, + 3;201,213,190;, + 3;226,235,227;, + 3;232,223,231;, + 3;214,209,217;, + 3;216,211,219;, + 3;226,233,234;, + 3;233,237,234;, + 3;236,221,228;, + 3;229,222,221;, + 3;236,240,229;, + 3;230,243,231;, + 3;197,218,202;, + 3;229,238,230;, + 3;210,192,207;, + 3;226,249,225;, + 3;220,205,213;, + 3;205,195,206;, + 3;225,248,224;, + 3;231,222,230;, + 3;219,212,220;, + 3;198,220,201;, + 3;207,196,208;, + 3;206,200,209;, + 3;189,238,240;, + 3;202,240,244;, + 3;238,198,243;, + 3;243,201,242;, + 3;242,190,239;, + 3;239,194,237;, + 3;241,194,197;, + 3;197,244,241;, + // Gatling_fin_2 + 3;254,277,278;, + 3;253,279,280;, + 3;258,278,281;, + 3;266,282,279;, + 3;257,280,283;, + 3;281,273,274;, + 3;276,268,255;, + 3;259,255,313;, + 3;286,310,309;, + 3;268,263,311;, + 3;263,260,310;, + 3;288,312,311;, + 3;292,316,315;, + 3;310,260,256;, + 3;309,256,267;, + 3;316,267,264;, + 3;315,264,259;, + 3;295,307,306;, + 3;285,309,316;, + 3;299,305,308;, + 3;297,303,301;, + 3;262,283,284;, + 3;261,281,282;, + 3;280,272,275;, + 3;255,268,312;, + 3;289,313,312;, + 3;291,315,314;, + 3;265,284,277;, + 3;295,287,286;, + 3;277,269,270;, + 3;279,271,272;, + 3;290,298,299;, + 3;253,257,302;, + 3;307,262,265;, + 3;306,265,254;, + 3;300,308,304;, + 3;296,288,287;, + 3;288,296,297;, + 3;293,294,286;, + 3;299,300,292;, + 3;302,257,262;, + 3;282,274,271;, + 3;296,306,303;, + 3;274,267,256;, + 3;303,254,258;, + 3;272,260,263;, + 3;305,301,258;, + 3;261,266,308;, + 3;284,276,269;, + 3;278,270,273;, + 3;275,263,268;, + 3;290,289,297;, + 3;269,255,259;, + 3;273,264,267;, + 3;290,314,313;, + 3;287,311,310;, + 3;293,304,302;, + 3;271,256,260;, + 3;266,253,304;, + 3;294,302,307;, + 3;270,259,264;, + 3;300,293,285;, + 3;283,275,276;, + 3;298,301,305;, + 3;254,278,258;, + 3;253,280,257;, + 3;258,281,261;, + 3;266,279,253;, + 3;257,283,262;, + 3;281,274,282;, + 3;276,255,269;, + 3;259,313,314;, + 3;286,309,285;, + 3;268,311,312;, + 3;263,310,311;, + 3;288,311,287;, + 3;292,315,291;, + 3;310,256,309;, + 3;309,267,316;, + 3;316,264,315;, + 3;315,259,314;, + 3;295,306,296;, + 3;285,316,292;, + 3;299,308,300;, + 3;297,301,298;, + 3;262,284,265;, + 3;261,282,266;, + 3;280,275,283;, + 3;255,312,313;, + 3;289,312,288;, + 3;291,314,290;, + 3;265,277,254;, + 3;295,286,294;, + 3;277,270,278;, + 3;279,272,280;, + 3;290,299,291;, + 3;253,302,304;, + 3;307,265,306;, + 3;306,254,303;, + 3;300,304,293;, + 3;296,287,295;, + 3;288,297,289;, + 3;293,286,285;, + 3;299,292,291;, + 3;302,262,307;, + 3;282,271,279;, + 3;296,303,297;, + 3;274,256,271;, + 3;303,258,301;, + 3;272,263,275;, + 3;305,258,261;, + 3;261,308,305;, + 3;284,269,277;, + 3;278,273,281;, + 3;275,268,276;, + 3;290,297,298;, + 3;269,259,270;, + 3;273,267,274;, + 3;290,313,289;, + 3;287,310,286;, + 3;293,302,294;, + 3;271,260,272;, + 3;266,304,308;, + 3;294,307,295;, + 3;270,264,273;, + 3;300,285,292;, + 3;283,276,284;, + 3;298,305,299;, + // Gatling_fin_3 + 3;319,342,343;, + 3;318,344,345;, + 3;323,343,346;, + 3;331,347,344;, + 3;322,345,348;, + 3;346,338,339;, + 3;324,320,378;, + 3;333,328,376;, + 3;328,325,375;, + 3;375,325,321;, + 3;374,321,332;, + 3;353,377,376;, + 3;357,381,380;, + 3;381,332,329;, + 3;380,329,324;, + 3;351,375,374;, + 3;359,367,372;, + 3;360,372,371;, + 3;350,374,381;, + 3;364,370,373;, + 3;323,326,370;, + 3;331,318,369;, + 3;318,322,367;, + 3;367,322,327;, + 3;372,327,330;, + 3;358,369,367;, + 3;371,330,319;, + 3;355,363,364;, + 3;368,319,323;, + 3;342,334,335;, + 3;344,336,337;, + 3;334,320,324;, + 3;326,331,373;, + 3;355,354,362;, + 3;341,333,320;, + 3;336,321,325;, + 3;365,373,369;, + 3;362,368,366;, + 3;335,324,329;, + 3;355,379,378;, + 3;338,329,332;, + 3;361,371,368;, + 3;353,361,362;, + 3;327,348,349;, + 3;343,335,338;, + 3;365,358,350;, + 3;326,346,347;, + 3;345,337,340;, + 3;349,341,334;, + 3;360,352,351;, + 3;339,332,321;, + 3;340,328,333;, + 3;337,325,328;, + 3;354,378,377;, + 3;320,333,377;, + 3;347,339,336;, + 3;356,380,379;, + 3;352,376,375;, + 3;358,359,351;, + 3;363,366,370;, + 3;330,349,342;, + 3;364,365,357;, + 3;361,353,352;, + 3;348,340,341;, + 3;319,343,323;, + 3;318,345,322;, + 3;323,346,326;, + 3;331,344,318;, + 3;322,348,327;, + 3;346,339,347;, + 3;324,378,379;, + 3;333,376,377;, + 3;328,375,376;, + 3;375,321,374;, + 3;374,332,381;, + 3;353,376,352;, + 3;357,380,356;, + 3;381,329,380;, + 3;380,324,379;, + 3;351,374,350;, + 3;359,372,360;, + 3;360,371,361;, + 3;350,381,357;, + 3;364,373,365;, + 3;323,370,366;, + 3;331,369,373;, + 3;318,367,369;, + 3;367,327,372;, + 3;372,330,371;, + 3;358,367,359;, + 3;371,319,368;, + 3;355,364,356;, + 3;368,323,366;, + 3;342,335,343;, + 3;344,337,345;, + 3;334,324,335;, + 3;326,373,370;, + 3;355,362,363;, + 3;341,320,334;, + 3;336,325,337;, + 3;365,369,358;, + 3;362,366,363;, + 3;335,329,338;, + 3;355,378,354;, + 3;338,332,339;, + 3;361,368,362;, + 3;353,362,354;, + 3;327,349,330;, + 3;343,338,346;, + 3;365,350,357;, + 3;326,347,331;, + 3;345,340,348;, + 3;349,334,342;, + 3;360,351,359;, + 3;339,321,336;, + 3;340,333,341;, + 3;337,328,340;, + 3;354,377,353;, + 3;320,377,378;, + 3;347,336,344;, + 3;356,379,355;, + 3;352,375,351;, + 3;358,351,350;, + 3;363,370,364;, + 3;330,342,319;, + 3;364,357,356;, + 3;361,352,360;, + 3;348,341,349;, + // Barrel_11 + 3;385,387,391;, + 3;387,388,389;, + 3;427,426,433;, + 3;385,391,396;, + 3;391,389,392;, + 3;419,403,406;, + 3;385,396,400;, + 3;396,392,393;, + 3;432,431,430;, + 3;385,400,404;, + 3;400,393,395;, + 3;427,432,430;, + 3;385,404,407;, + 3;404,395,398;, + 3;385,415,387;, + 3;385,407,412;, + 3;407,398,399;, + 3;415,401,388;, + 3;385,412,415;, + 3;412,399,401;, + 3;427,429,428;, + 3;403,427,428;, + 3;406,428,429;, + 3;408,429,430;, + 3;409,430,431;, + 3;411,431,432;, + 3;413,432,433;, + 3;416,433,426;, + 3;417,426,427;, + 3;420,406,408;, + 3;421,408,409;, + 3;422,409,411;, + 3;423,411,413;, + 3;424,413,416;, + 3;425,416,417;, + 3;418,417,403;, + 3;388,390,394;, + 3;389,394,397;, + 3;392,397,402;, + 3;393,402,405;, + 3;395,405,410;, + 3;398,410,414;, + 3;401,386,390;, + 3;399,414,386;, + 3;402,397,421;, + 3;397,394,420;, + 3;394,390,419;, + 3;418,419,390;, + 3;425,418,386;, + 3;424,425,414;, + 3;423,424,410;, + 3;422,423,405;, + 3;387,389,391;, + 3;427,433,432;, + 3;391,392,396;, + 3;419,406,420;, + 3;396,393,400;, + 3;400,395,404;, + 3;427,430,429;, + 3;404,398,407;, + 3;407,399,412;, + 3;415,388,387;, + 3;412,401,415;, + 3;403,428,406;, + 3;406,429,408;, + 3;408,430,409;, + 3;409,431,411;, + 3;411,432,413;, + 3;413,433,416;, + 3;416,426,417;, + 3;417,427,403;, + 3;420,408,421;, + 3;421,409,422;, + 3;422,411,423;, + 3;423,413,424;, + 3;424,416,425;, + 3;425,417,418;, + 3;418,403,419;, + 3;388,394,389;, + 3;389,397,392;, + 3;392,402,393;, + 3;393,405,395;, + 3;395,410,398;, + 3;398,414,399;, + 3;401,390,388;, + 3;399,386,401;, + 3;402,421,422;, + 3;397,420,421;, + 3;394,419,420;, + 3;418,390,386;, + 3;425,386,414;, + 3;424,414,410;, + 3;423,410,405;, + 3;422,405,402;, + // Barrel_1 + 3;434,436,440;, + 3;436,437,438;, + 3;476,475,482;, + 3;434,440,445;, + 3;440,438,441;, + 3;468,452,455;, + 3;434,445,449;, + 3;445,441,442;, + 3;481,480,479;, + 3;434,449,453;, + 3;449,442,444;, + 3;476,481,479;, + 3;434,453,456;, + 3;453,444,447;, + 3;434,464,436;, + 3;434,456,461;, + 3;456,447,448;, + 3;464,450,437;, + 3;434,461,464;, + 3;461,448,450;, + 3;476,478,477;, + 3;452,476,477;, + 3;455,477,478;, + 3;457,478,479;, + 3;458,479,480;, + 3;460,480,481;, + 3;462,481,482;, + 3;465,482,475;, + 3;466,475,476;, + 3;469,455,457;, + 3;470,457,458;, + 3;471,458,460;, + 3;472,460,462;, + 3;473,462,465;, + 3;474,465,466;, + 3;467,466,452;, + 3;437,439,443;, + 3;438,443,446;, + 3;441,446,451;, + 3;442,451,454;, + 3;444,454,459;, + 3;447,459,463;, + 3;450,435,439;, + 3;448,463,435;, + 3;451,446,470;, + 3;446,443,469;, + 3;443,439,468;, + 3;467,468,439;, + 3;474,467,435;, + 3;473,474,463;, + 3;472,473,459;, + 3;471,472,454;, + 3;436,438,440;, + 3;476,482,481;, + 3;440,441,445;, + 3;468,455,469;, + 3;445,442,449;, + 3;449,444,453;, + 3;476,479,478;, + 3;453,447,456;, + 3;456,448,461;, + 3;464,437,436;, + 3;461,450,464;, + 3;452,477,455;, + 3;455,478,457;, + 3;457,479,458;, + 3;458,480,460;, + 3;460,481,462;, + 3;462,482,465;, + 3;465,475,466;, + 3;466,476,452;, + 3;469,457,470;, + 3;470,458,471;, + 3;471,460,472;, + 3;472,462,473;, + 3;473,465,474;, + 3;474,466,467;, + 3;467,452,468;, + 3;437,443,438;, + 3;438,446,441;, + 3;441,451,442;, + 3;442,454,444;, + 3;444,459,447;, + 3;447,463,448;, + 3;450,439,437;, + 3;448,435,450;, + 3;451,470,471;, + 3;446,469,470;, + 3;443,468,469;, + 3;467,439,435;, + 3;474,435,463;, + 3;473,463,459;, + 3;472,459,454;, + 3;471,454,451;, + // Barrel_13 + 3;483,485,489;, + 3;485,486,487;, + 3;525,524,531;, + 3;483,489,494;, + 3;489,487,490;, + 3;517,501,504;, + 3;483,494,498;, + 3;494,490,491;, + 3;530,529,528;, + 3;483,498,502;, + 3;498,491,493;, + 3;525,530,528;, + 3;483,502,505;, + 3;502,493,496;, + 3;483,513,485;, + 3;483,505,510;, + 3;505,496,497;, + 3;513,499,486;, + 3;483,510,513;, + 3;510,497,499;, + 3;525,527,526;, + 3;501,525,526;, + 3;504,526,527;, + 3;506,527,528;, + 3;507,528,529;, + 3;509,529,530;, + 3;511,530,531;, + 3;514,531,524;, + 3;515,524,525;, + 3;518,504,506;, + 3;519,506,507;, + 3;520,507,509;, + 3;521,509,511;, + 3;522,511,514;, + 3;523,514,515;, + 3;516,515,501;, + 3;486,488,492;, + 3;487,492,495;, + 3;490,495,500;, + 3;491,500,503;, + 3;493,503,508;, + 3;496,508,512;, + 3;499,484,488;, + 3;497,512,484;, + 3;500,495,519;, + 3;495,492,518;, + 3;492,488,517;, + 3;516,517,488;, + 3;523,516,484;, + 3;522,523,512;, + 3;521,522,508;, + 3;520,521,503;, + 3;485,487,489;, + 3;525,531,530;, + 3;489,490,494;, + 3;517,504,518;, + 3;494,491,498;, + 3;498,493,502;, + 3;525,528,527;, + 3;502,496,505;, + 3;505,497,510;, + 3;513,486,485;, + 3;510,499,513;, + 3;501,526,504;, + 3;504,527,506;, + 3;506,528,507;, + 3;507,529,509;, + 3;509,530,511;, + 3;511,531,514;, + 3;514,524,515;, + 3;515,525,501;, + 3;518,506,519;, + 3;519,507,520;, + 3;520,509,521;, + 3;521,511,522;, + 3;522,514,523;, + 3;523,515,516;, + 3;516,501,517;, + 3;486,492,487;, + 3;487,495,490;, + 3;490,500,491;, + 3;491,503,493;, + 3;493,508,496;, + 3;496,512,497;, + 3;499,488,486;, + 3;497,484,499;, + 3;500,519,520;, + 3;495,518,519;, + 3;492,517,518;, + 3;516,488,484;, + 3;523,484,512;, + 3;522,512,508;, + 3;521,508,503;, + 3;520,503,500;, + // Barrel_14 + 3;532,534,538;, + 3;534,535,536;, + 3;574,573,580;, + 3;532,538,543;, + 3;538,536,539;, + 3;566,550,553;, + 3;532,543,547;, + 3;543,539,540;, + 3;579,578,577;, + 3;532,547,551;, + 3;547,540,542;, + 3;574,579,577;, + 3;532,551,554;, + 3;551,542,545;, + 3;532,562,534;, + 3;532,554,559;, + 3;554,545,546;, + 3;562,548,535;, + 3;532,559,562;, + 3;559,546,548;, + 3;574,576,575;, + 3;550,574,575;, + 3;553,575,576;, + 3;555,576,577;, + 3;556,577,578;, + 3;558,578,579;, + 3;560,579,580;, + 3;563,580,573;, + 3;564,573,574;, + 3;567,553,555;, + 3;568,555,556;, + 3;569,556,558;, + 3;570,558,560;, + 3;571,560,563;, + 3;572,563,564;, + 3;565,564,550;, + 3;535,537,541;, + 3;536,541,544;, + 3;539,544,549;, + 3;540,549,552;, + 3;542,552,557;, + 3;545,557,561;, + 3;548,533,537;, + 3;546,561,533;, + 3;549,544,568;, + 3;544,541,567;, + 3;541,537,566;, + 3;565,566,537;, + 3;572,565,533;, + 3;571,572,561;, + 3;570,571,557;, + 3;569,570,552;, + 3;534,536,538;, + 3;574,580,579;, + 3;538,539,543;, + 3;566,553,567;, + 3;543,540,547;, + 3;547,542,551;, + 3;574,577,576;, + 3;551,545,554;, + 3;554,546,559;, + 3;562,535,534;, + 3;559,548,562;, + 3;550,575,553;, + 3;553,576,555;, + 3;555,577,556;, + 3;556,578,558;, + 3;558,579,560;, + 3;560,580,563;, + 3;563,573,564;, + 3;564,574,550;, + 3;567,555,568;, + 3;568,556,569;, + 3;569,558,570;, + 3;570,560,571;, + 3;571,563,572;, + 3;572,564,565;, + 3;565,550,566;, + 3;535,541,536;, + 3;536,544,539;, + 3;539,549,540;, + 3;540,552,542;, + 3;542,557,545;, + 3;545,561,546;, + 3;548,537,535;, + 3;546,533,548;, + 3;549,568,569;, + 3;544,567,568;, + 3;541,566,567;, + 3;565,537,533;, + 3;572,533,561;, + 3;571,561,557;, + 3;570,557,552;, + 3;569,552,549;, + // Barrel_12 + 3;581,583,587;, + 3;583,584,585;, + 3;623,622,629;, + 3;581,587,592;, + 3;587,585,588;, + 3;615,599,602;, + 3;581,592,596;, + 3;592,588,589;, + 3;628,627,626;, + 3;581,596,600;, + 3;596,589,591;, + 3;623,628,626;, + 3;581,600,603;, + 3;600,591,594;, + 3;581,611,583;, + 3;581,603,608;, + 3;603,594,595;, + 3;611,597,584;, + 3;581,608,611;, + 3;608,595,597;, + 3;623,625,624;, + 3;599,623,624;, + 3;602,624,625;, + 3;604,625,626;, + 3;605,626,627;, + 3;607,627,628;, + 3;609,628,629;, + 3;612,629,622;, + 3;613,622,623;, + 3;616,602,604;, + 3;617,604,605;, + 3;618,605,607;, + 3;619,607,609;, + 3;620,609,612;, + 3;621,612,613;, + 3;614,613,599;, + 3;584,586,590;, + 3;585,590,593;, + 3;588,593,598;, + 3;589,598,601;, + 3;591,601,606;, + 3;594,606,610;, + 3;597,582,586;, + 3;595,610,582;, + 3;598,593,617;, + 3;593,590,616;, + 3;590,586,615;, + 3;614,615,586;, + 3;621,614,582;, + 3;620,621,610;, + 3;619,620,606;, + 3;618,619,601;, + 3;583,585,587;, + 3;623,629,628;, + 3;587,588,592;, + 3;615,602,616;, + 3;592,589,596;, + 3;596,591,600;, + 3;623,626,625;, + 3;600,594,603;, + 3;603,595,608;, + 3;611,584,583;, + 3;608,597,611;, + 3;599,624,602;, + 3;602,625,604;, + 3;604,626,605;, + 3;605,627,607;, + 3;607,628,609;, + 3;609,629,612;, + 3;612,622,613;, + 3;613,623,599;, + 3;616,604,617;, + 3;617,605,618;, + 3;618,607,619;, + 3;619,609,620;, + 3;620,612,621;, + 3;621,613,614;, + 3;614,599,615;, + 3;584,590,585;, + 3;585,593,588;, + 3;588,598,589;, + 3;589,601,591;, + 3;591,606,594;, + 3;594,610,595;, + 3;597,586,584;, + 3;595,582,597;, + 3;598,617,618;, + 3;593,616,617;, + 3;590,615,616;, + 3;614,586,582;, + 3;621,582,610;, + 3;620,610,606;, + 3;619,606,601;, + 3;618,601,598;, + // Barrel_16 + 3;630,632,636;, + 3;632,633,634;, + 3;672,671,678;, + 3;630,636,641;, + 3;636,634,637;, + 3;664,648,651;, + 3;630,641,645;, + 3;641,637,638;, + 3;677,676,675;, + 3;630,645,649;, + 3;645,638,640;, + 3;672,677,675;, + 3;630,649,652;, + 3;649,640,643;, + 3;630,660,632;, + 3;630,652,657;, + 3;652,643,644;, + 3;660,646,633;, + 3;630,657,660;, + 3;657,644,646;, + 3;672,674,673;, + 3;648,672,673;, + 3;651,673,674;, + 3;653,674,675;, + 3;654,675,676;, + 3;656,676,677;, + 3;658,677,678;, + 3;661,678,671;, + 3;662,671,672;, + 3;665,651,653;, + 3;666,653,654;, + 3;667,654,656;, + 3;668,656,658;, + 3;669,658,661;, + 3;670,661,662;, + 3;663,662,648;, + 3;633,635,639;, + 3;634,639,642;, + 3;637,642,647;, + 3;638,647,650;, + 3;640,650,655;, + 3;643,655,659;, + 3;646,631,635;, + 3;644,659,631;, + 3;647,642,666;, + 3;642,639,665;, + 3;639,635,664;, + 3;663,664,635;, + 3;670,663,631;, + 3;669,670,659;, + 3;668,669,655;, + 3;667,668,650;, + 3;632,634,636;, + 3;672,678,677;, + 3;636,637,641;, + 3;664,651,665;, + 3;641,638,645;, + 3;645,640,649;, + 3;672,675,674;, + 3;649,643,652;, + 3;652,644,657;, + 3;660,633,632;, + 3;657,646,660;, + 3;648,673,651;, + 3;651,674,653;, + 3;653,675,654;, + 3;654,676,656;, + 3;656,677,658;, + 3;658,678,661;, + 3;661,671,662;, + 3;662,672,648;, + 3;665,653,666;, + 3;666,654,667;, + 3;667,656,668;, + 3;668,658,669;, + 3;669,661,670;, + 3;670,662,663;, + 3;663,648,664;, + 3;633,639,634;, + 3;634,642,637;, + 3;637,647,638;, + 3;638,650,640;, + 3;640,655,643;, + 3;643,659,644;, + 3;646,635,633;, + 3;644,631,646;, + 3;647,666,667;, + 3;642,665,666;, + 3;639,664,665;, + 3;663,635,631;, + 3;670,631,659;, + 3;669,659,655;, + 3;668,655,650;, + 3;667,650,647;, + // Barrel_17 + 3;679,681,685;, + 3;681,682,683;, + 3;721,720,727;, + 3;679,685,690;, + 3;685,683,686;, + 3;713,697,700;, + 3;679,690,694;, + 3;690,686,687;, + 3;726,725,724;, + 3;679,694,698;, + 3;694,687,689;, + 3;721,726,724;, + 3;679,698,701;, + 3;698,689,692;, + 3;679,709,681;, + 3;679,701,706;, + 3;701,692,693;, + 3;709,695,682;, + 3;679,706,709;, + 3;706,693,695;, + 3;721,723,722;, + 3;697,721,722;, + 3;700,722,723;, + 3;702,723,724;, + 3;703,724,725;, + 3;705,725,726;, + 3;707,726,727;, + 3;710,727,720;, + 3;711,720,721;, + 3;714,700,702;, + 3;715,702,703;, + 3;716,703,705;, + 3;717,705,707;, + 3;718,707,710;, + 3;719,710,711;, + 3;712,711,697;, + 3;682,684,688;, + 3;683,688,691;, + 3;686,691,696;, + 3;687,696,699;, + 3;689,699,704;, + 3;692,704,708;, + 3;695,680,684;, + 3;693,708,680;, + 3;696,691,715;, + 3;691,688,714;, + 3;688,684,713;, + 3;712,713,684;, + 3;719,712,680;, + 3;718,719,708;, + 3;717,718,704;, + 3;716,717,699;, + 3;681,683,685;, + 3;721,727,726;, + 3;685,686,690;, + 3;713,700,714;, + 3;690,687,694;, + 3;694,689,698;, + 3;721,724,723;, + 3;698,692,701;, + 3;701,693,706;, + 3;709,682,681;, + 3;706,695,709;, + 3;697,722,700;, + 3;700,723,702;, + 3;702,724,703;, + 3;703,725,705;, + 3;705,726,707;, + 3;707,727,710;, + 3;710,720,711;, + 3;711,721,697;, + 3;714,702,715;, + 3;715,703,716;, + 3;716,705,717;, + 3;717,707,718;, + 3;718,710,719;, + 3;719,711,712;, + 3;712,697,713;, + 3;682,688,683;, + 3;683,691,686;, + 3;686,696,687;, + 3;687,699,689;, + 3;689,704,692;, + 3;692,708,693;, + 3;695,684,682;, + 3;693,680,695;, + 3;696,715,716;, + 3;691,714,715;, + 3;688,713,714;, + 3;712,684,680;, + 3;719,680,708;, + 3;718,708,704;, + 3;717,704,699;, + 3;716,699,696;, + // Barrel_15 + 3;728,730,734;, + 3;730,731,732;, + 3;770,769,776;, + 3;728,734,739;, + 3;734,732,735;, + 3;762,746,749;, + 3;728,739,743;, + 3;739,735,736;, + 3;775,774,773;, + 3;728,743,747;, + 3;743,736,738;, + 3;770,775,773;, + 3;728,747,750;, + 3;747,738,741;, + 3;728,758,730;, + 3;728,750,755;, + 3;750,741,742;, + 3;758,744,731;, + 3;728,755,758;, + 3;755,742,744;, + 3;770,772,771;, + 3;746,770,771;, + 3;749,771,772;, + 3;751,772,773;, + 3;752,773,774;, + 3;754,774,775;, + 3;756,775,776;, + 3;759,776,769;, + 3;760,769,770;, + 3;763,749,751;, + 3;764,751,752;, + 3;765,752,754;, + 3;766,754,756;, + 3;767,756,759;, + 3;768,759,760;, + 3;761,760,746;, + 3;731,733,737;, + 3;732,737,740;, + 3;735,740,745;, + 3;736,745,748;, + 3;738,748,753;, + 3;741,753,757;, + 3;744,729,733;, + 3;742,757,729;, + 3;745,740,764;, + 3;740,737,763;, + 3;737,733,762;, + 3;761,762,733;, + 3;768,761,729;, + 3;767,768,757;, + 3;766,767,753;, + 3;765,766,748;, + 3;730,732,734;, + 3;770,776,775;, + 3;734,735,739;, + 3;762,749,763;, + 3;739,736,743;, + 3;743,738,747;, + 3;770,773,772;, + 3;747,741,750;, + 3;750,742,755;, + 3;758,731,730;, + 3;755,744,758;, + 3;746,771,749;, + 3;749,772,751;, + 3;751,773,752;, + 3;752,774,754;, + 3;754,775,756;, + 3;756,776,759;, + 3;759,769,760;, + 3;760,770,746;, + 3;763,751,764;, + 3;764,752,765;, + 3;765,754,766;, + 3;766,756,767;, + 3;767,759,768;, + 3;768,760,761;, + 3;761,746,762;, + 3;731,737,732;, + 3;732,740,735;, + 3;735,745,736;, + 3;736,748,738;, + 3;738,753,741;, + 3;741,757,742;, + 3;744,733,731;, + 3;742,729,744;, + 3;745,764,765;, + 3;740,763,764;, + 3;737,762,763;, + 3;761,733,729;, + 3;768,729,757;, + 3;767,757,753;, + 3;766,753,748;, + 3;765,748,745;, + // Side_guns + 3;817,801,803;, + 3;777,809,810;, + 3;782,811,812;, + 3;818,803,805;, + 3;781,810,813;, + 3;819,805,808;, + 3;820,808,802;, + 3;786,813,814;, + 3;785,812,815;, + 3;821,802,804;, + 3;789,814,816;, + 3;822,804,806;, + 3;823,806,807;, + 3;778,816,811;, + 3;790,815,809;, + 3;824,807,801;, + 3;801,807,803;, + 3;807,806,804;, + 3;803,807,804;, + 3;804,802,808;, + 3;808,805,803;, + 3;779,793,795;, + 3;783,795,797;, + 3;787,797,800;, + 3;792,800,794;, + 3;780,794,796;, + 3;784,796,798;, + 3;788,798,799;, + 3;791,799,793;, + 3;793,817,818;, + 3;795,818,819;, + 3;797,819,820;, + 3;800,820,821;, + 3;794,821,822;, + 3;796,822,823;, + 3;798,823,824;, + 3;799,824,817;, + 3;809,780,784;, + 3;811,783,787;, + 3;810,784,788;, + 3;813,788,791;, + 3;812,787,792;, + 3;814,791,779;, + 3;816,779,783;, + 3;815,792,780;, + 3;817,803,818;, + 3;777,810,781;, + 3;782,812,785;, + 3;818,805,819;, + 3;781,813,786;, + 3;819,808,820;, + 3;820,802,821;, + 3;786,814,789;, + 3;785,815,790;, + 3;821,804,822;, + 3;789,816,778;, + 3;822,806,823;, + 3;823,807,824;, + 3;778,811,782;, + 3;790,809,777;, + 3;824,801,817;, + 3;803,804,808;, + 3;779,795,783;, + 3;783,797,787;, + 3;787,800,792;, + 3;792,794,780;, + 3;780,796,784;, + 3;784,798,788;, + 3;788,799,791;, + 3;791,793,779;, + 3;793,818,795;, + 3;795,819,797;, + 3;797,820,800;, + 3;800,821,794;, + 3;794,822,796;, + 3;796,823,798;, + 3;798,824,799;, + 3;799,817,793;, + 3;809,784,810;, + 3;811,787,812;, + 3;810,788,813;, + 3;813,791,814;, + 3;812,792,815;, + 3;814,779,816;, + 3;816,783,811;, + 3;815,780,809;, + 3;865,851,849;, + 3;825,858,857;, + 3;830,860,859;, + 3;866,853,851;, + 3;829,861,858;, + 3;867,856,853;, + 3;868,850,856;, + 3;834,862,861;, + 3;833,863,860;, + 3;869,852,850;, + 3;837,864,862;, + 3;870,854,852;, + 3;871,855,854;, + 3;826,859,864;, + 3;838,857,863;, + 3;872,849,855;, + 3;849,851,855;, + 3;855,852,854;, + 3;851,852,855;, + 3;852,856,850;, + 3;856,851,853;, + 3;827,843,841;, + 3;831,845,843;, + 3;835,848,845;, + 3;840,842,848;, + 3;828,844,842;, + 3;832,846,844;, + 3;836,847,846;, + 3;839,841,847;, + 3;841,866,865;, + 3;843,867,866;, + 3;845,868,867;, + 3;848,869,868;, + 3;842,870,869;, + 3;844,871,870;, + 3;846,872,871;, + 3;847,865,872;, + 3;857,832,828;, + 3;859,835,831;, + 3;858,836,832;, + 3;861,839,836;, + 3;860,840,835;, + 3;862,827,839;, + 3;864,831,827;, + 3;863,828,840;, + 3;865,866,851;, + 3;825,829,858;, + 3;830,833,860;, + 3;866,867,853;, + 3;829,834,861;, + 3;867,868,856;, + 3;868,869,850;, + 3;834,837,862;, + 3;833,838,863;, + 3;869,870,852;, + 3;837,826,864;, + 3;870,871,854;, + 3;871,872,855;, + 3;826,830,859;, + 3;838,825,857;, + 3;872,865,849;, + 3;851,856,852;, + 3;827,831,843;, + 3;831,835,845;, + 3;835,840,848;, + 3;840,828,842;, + 3;828,832,844;, + 3;832,836,846;, + 3;836,839,847;, + 3;839,827,841;, + 3;841,843,866;, + 3;843,845,867;, + 3;845,848,868;, + 3;848,842,869;, + 3;842,844,870;, + 3;844,846,871;, + 3;846,847,872;, + 3;847,841,865;, + 3;857,858,832;, + 3;859,860,835;, + 3;858,861,836;, + 3;861,862,839;, + 3;860,863,840;, + 3;862,864,827;, + 3;864,859,831;, + 3;863,857,828;, + // Frontal_aux_gun + 3;913,897,899;, + 3;873,905,906;, + 3;878,907,908;, + 3;914,899,901;, + 3;877,906,909;, + 3;915,901,904;, + 3;916,904,898;, + 3;882,909,910;, + 3;881,908,911;, + 3;917,898,900;, + 3;885,910,912;, + 3;918,900,902;, + 3;919,902,903;, + 3;874,912,907;, + 3;886,911,905;, + 3;920,903,897;, + 3;897,903,899;, + 3;903,902,900;, + 3;899,903,900;, + 3;900,898,904;, + 3;904,901,899;, + 3;875,889,891;, + 3;879,891,893;, + 3;883,893,896;, + 3;888,896,890;, + 3;876,890,892;, + 3;880,892,894;, + 3;884,894,895;, + 3;887,895,889;, + 3;889,913,914;, + 3;891,914,915;, + 3;893,915,916;, + 3;896,916,917;, + 3;890,917,918;, + 3;892,918,919;, + 3;894,919,920;, + 3;895,920,913;, + 3;905,876,880;, + 3;907,879,883;, + 3;906,880,884;, + 3;909,884,887;, + 3;908,883,888;, + 3;910,887,875;, + 3;912,875,879;, + 3;911,888,876;, + 3;913,899,914;, + 3;873,906,877;, + 3;878,908,881;, + 3;914,901,915;, + 3;877,909,882;, + 3;915,904,916;, + 3;916,898,917;, + 3;882,910,885;, + 3;881,911,886;, + 3;917,900,918;, + 3;885,912,874;, + 3;918,902,919;, + 3;919,903,920;, + 3;874,907,878;, + 3;886,905,873;, + 3;920,897,913;, + 3;899,900,904;, + 3;875,891,879;, + 3;879,893,883;, + 3;883,896,888;, + 3;888,890,876;, + 3;876,892,880;, + 3;880,894,884;, + 3;884,895,887;, + 3;887,889,875;, + 3;889,914,891;, + 3;891,915,893;, + 3;893,916,896;, + 3;896,917,890;, + 3;890,918,892;, + 3;892,919,894;, + 3;894,920,895;, + 3;895,913,889;, + 3;905,880,906;, + 3;907,883,908;, + 3;906,884,909;, + 3;909,887,910;, + 3;908,888,911;, + 3;910,875,912;, + 3;912,879,907;, + 3;911,876,905;, + 3;961,947,945;, + 3;921,954,953;, + 3;926,956,955;, + 3;962,949,947;, + 3;925,957,954;, + 3;963,952,949;, + 3;964,946,952;, + 3;930,958,957;, + 3;929,959,956;, + 3;965,948,946;, + 3;933,960,958;, + 3;966,950,948;, + 3;967,951,950;, + 3;922,955,960;, + 3;934,953,959;, + 3;968,945,951;, + 3;945,947,951;, + 3;951,948,950;, + 3;947,948,951;, + 3;948,952,946;, + 3;952,947,949;, + 3;923,939,937;, + 3;927,941,939;, + 3;931,944,941;, + 3;936,938,944;, + 3;924,940,938;, + 3;928,942,940;, + 3;932,943,942;, + 3;935,937,943;, + 3;937,962,961;, + 3;939,963,962;, + 3;941,964,963;, + 3;944,965,964;, + 3;938,966,965;, + 3;940,967,966;, + 3;942,968,967;, + 3;943,961,968;, + 3;953,928,924;, + 3;955,931,927;, + 3;954,932,928;, + 3;957,935,932;, + 3;956,936,931;, + 3;958,923,935;, + 3;960,927,923;, + 3;959,924,936;, + 3;961,962,947;, + 3;921,925,954;, + 3;926,929,956;, + 3;962,963,949;, + 3;925,930,957;, + 3;963,964,952;, + 3;964,965,946;, + 3;930,933,958;, + 3;929,934,959;, + 3;965,966,948;, + 3;933,922,960;, + 3;966,967,950;, + 3;967,968,951;, + 3;922,926,955;, + 3;934,921,953;, + 3;968,961,945;, + 3;947,952,948;, + 3;923,927,939;, + 3;927,931,941;, + 3;931,936,944;, + 3;936,924,938;, + 3;924,928,940;, + 3;928,932,942;, + 3;932,935,943;, + 3;935,923,937;, + 3;937,939,962;, + 3;939,941,963;, + 3;941,944,964;, + 3;944,938,965;, + 3;938,940,966;, + 3;940,942,967;, + 3;942,943,968;, + 3;943,937,961;, + 3;953,954,928;, + 3;955,956,931;, + 3;954,957,932;, + 3;957,958,935;, + 3;956,959,936;, + 3;958,960,923;, + 3;960,955,927;, + 3;959,953,924;, + // Jet + 3;1050,1070,1071;, + 3;1051,1071,1072;, + 3;971,972,976;, + 3;972,973,977;, + 3;1070,969,1071;, + 3;1035,1036,1040;, + 3;1052,1072,1073;, + 3;975,976,980;, + 3;976,977,981;, + 3;1071,969,1072;, + 3;1036,1037,1041;, + 3;1066,1086,1087;, + 3;979,980,984;, + 3;980,981,985;, + 3;1072,969,1073;, + 3;1086,969,1087;, + 3;1053,1073,1074;, + 3;983,984,988;, + 3;984,985,989;, + 3;1073,969,1074;, + 3;1054,1074,1075;, + 3;1055,1075,1076;, + 3;987,988,992;, + 3;988,989,993;, + 3;1074,969,1075;, + 3;1039,1040,1044;, + 3;1056,1076,1077;, + 3;991,992,996;, + 3;992,993,997;, + 3;1075,969,1076;, + 3;1040,1041,1045;, + 3;1067,1087,1088;, + 3;995,996,1000;, + 3;996,997,1001;, + 3;1076,969,1077;, + 3;1087,969,1088;, + 3;1057,1077,1078;, + 3;999,1000,1004;, + 3;1000,1001,1005;, + 3;1077,969,1078;, + 3;1058,1078,1079;, + 3;1059,1079,1080;, + 3;1003,1004,1008;, + 3;1004,1005,1009;, + 3;1078,969,1079;, + 3;1043,1044,1048;, + 3;1060,1080,1081;, + 3;1007,1008,1012;, + 3;1008,1009,1013;, + 3;1079,969,1080;, + 3;1044,1045,1049;, + 3;1068,1088,1089;, + 3;1011,1012,1016;, + 3;1012,1013,1017;, + 3;1080,969,1081;, + 3;1088,969,1089;, + 3;1061,1081,1082;, + 3;1015,1016,1020;, + 3;1016,1017,1021;, + 3;1081,969,1082;, + 3;1062,1082,1083;, + 3;1063,1083,1084;, + 3;1019,1020,1024;, + 3;1020,1021,1025;, + 3;1082,969,1083;, + 3;1047,1048,972;, + 3;1064,1084,1085;, + 3;1023,1024,1028;, + 3;1024,1025,1029;, + 3;1083,969,1084;, + 3;1048,1049,973;, + 3;1069,1089,1070;, + 3;1027,1028,1032;, + 3;1028,1029,1033;, + 3;1084,969,1085;, + 3;1089,969,1070;, + 3;1065,1085,1086;, + 3;1031,1032,1036;, + 3;1032,1033,1037;, + 3;1085,969,1086;, + 3;973,1050,1051;, + 3;977,1051,1052;, + 3;981,1052,1053;, + 3;1037,1066,1067;, + 3;985,1053,1054;, + 3;989,1054,1055;, + 3;993,1055,1056;, + 3;997,1056,1057;, + 3;1041,1067,1068;, + 3;1001,1057,1058;, + 3;1005,1058,1059;, + 3;1009,1059,1060;, + 3;1013,1060,1061;, + 3;1045,1068,1069;, + 3;1017,1061,1062;, + 3;1021,1062,1063;, + 3;1025,1063,1064;, + 3;1029,1064,1065;, + 3;1049,1069,1050;, + 3;1033,1065,1066;, + 3;1050,1071,1051;, + 3;1051,1072,1052;, + 3;971,976,975;, + 3;972,977,976;, + 3;1035,1040,1039;, + 3;1052,1073,1053;, + 3;975,980,979;, + 3;976,981,980;, + 3;1036,1041,1040;, + 3;1066,1087,1067;, + 3;979,984,983;, + 3;980,985,984;, + 3;1053,1074,1054;, + 3;983,988,987;, + 3;984,989,988;, + 3;1054,1075,1055;, + 3;1055,1076,1056;, + 3;987,992,991;, + 3;988,993,992;, + 3;1039,1044,1043;, + 3;1056,1077,1057;, + 3;991,996,995;, + 3;992,997,996;, + 3;1040,1045,1044;, + 3;1067,1088,1068;, + 3;995,1000,999;, + 3;996,1001,1000;, + 3;1057,1078,1058;, + 3;999,1004,1003;, + 3;1000,1005,1004;, + 3;1058,1079,1059;, + 3;1059,1080,1060;, + 3;1003,1008,1007;, + 3;1004,1009,1008;, + 3;1043,1048,1047;, + 3;1060,1081,1061;, + 3;1007,1012,1011;, + 3;1008,1013,1012;, + 3;1044,1049,1048;, + 3;1068,1089,1069;, + 3;1011,1016,1015;, + 3;1012,1017,1016;, + 3;1061,1082,1062;, + 3;1015,1020,1019;, + 3;1016,1021,1020;, + 3;1062,1083,1063;, + 3;1063,1084,1064;, + 3;1019,1024,1023;, + 3;1020,1025,1024;, + 3;1047,972,971;, + 3;1064,1085,1065;, + 3;1023,1028,1027;, + 3;1024,1029,1028;, + 3;1048,973,972;, + 3;1069,1070,1050;, + 3;1027,1032,1031;, + 3;1028,1033,1032;, + 3;1065,1086,1066;, + 3;1031,1036,1035;, + 3;1032,1037,1036;, + 3;973,1051,977;, + 3;977,1052,981;, + 3;981,1053,985;, + 3;1037,1067,1041;, + 3;985,1054,989;, + 3;989,1055,993;, + 3;993,1056,997;, + 3;997,1057,1001;, + 3;1041,1068,1045;, + 3;1001,1058,1005;, + 3;1005,1059,1009;, + 3;1009,1060,1013;, + 3;1013,1061,1017;, + 3;1045,1069,1049;, + 3;1017,1062,1021;, + 3;1021,1063,1025;, + 3;1025,1064,1029;, + 3;1029,1065,1033;, + 3;1049,1050,973;, + 3;1033,1066,1037;, + 3;1151,1172,1171;, + 3;1152,1173,1172;, + 3;1091,1095,1092;, + 3;1092,1096,1093;, + 3;1171,1172,1090;, + 3;1139,1143,1140;, + 3;1153,1174,1173;, + 3;1094,1098,1095;, + 3;1095,1099,1096;, + 3;1172,1173,1090;, + 3;1140,1144,1141;, + 3;1167,1188,1187;, + 3;1097,1101,1098;, + 3;1098,1102,1099;, + 3;1173,1174,1090;, + 3;1187,1188,1090;, + 3;1154,1175,1174;, + 3;1100,1104,1101;, + 3;1101,1105,1102;, + 3;1174,1175,1090;, + 3;1155,1176,1175;, + 3;1156,1177,1176;, + 3;1103,1107,1104;, + 3;1104,1108,1105;, + 3;1175,1176,1090;, + 3;1142,1146,1143;, + 3;1157,1178,1177;, + 3;1106,1110,1107;, + 3;1107,1111,1108;, + 3;1176,1177,1090;, + 3;1143,1147,1144;, + 3;1168,1189,1188;, + 3;1109,1113,1110;, + 3;1110,1114,1111;, + 3;1177,1178,1090;, + 3;1188,1189,1090;, + 3;1158,1179,1178;, + 3;1112,1116,1113;, + 3;1113,1117,1114;, + 3;1178,1179,1090;, + 3;1159,1180,1179;, + 3;1160,1181,1180;, + 3;1115,1119,1116;, + 3;1116,1120,1117;, + 3;1179,1180,1090;, + 3;1145,1149,1146;, + 3;1161,1182,1181;, + 3;1118,1122,1119;, + 3;1119,1123,1120;, + 3;1180,1181,1090;, + 3;1146,1150,1147;, + 3;1169,1190,1189;, + 3;1121,1125,1122;, + 3;1122,1126,1123;, + 3;1181,1182,1090;, + 3;1189,1190,1090;, + 3;1162,1183,1182;, + 3;1124,1128,1125;, + 3;1125,1129,1126;, + 3;1182,1183,1090;, + 3;1163,1184,1183;, + 3;1164,1185,1184;, + 3;1127,1131,1128;, + 3;1128,1132,1129;, + 3;1183,1184,1090;, + 3;1148,1092,1149;, + 3;1165,1186,1185;, + 3;1130,1134,1131;, + 3;1131,1135,1132;, + 3;1184,1185,1090;, + 3;1149,1093,1150;, + 3;1170,1171,1190;, + 3;1133,1137,1134;, + 3;1134,1138,1135;, + 3;1185,1186,1090;, + 3;1190,1171,1090;, + 3;1166,1187,1186;, + 3;1136,1140,1137;, + 3;1137,1141,1138;, + 3;1186,1187,1090;, + 3;1093,1152,1151;, + 3;1096,1153,1152;, + 3;1099,1154,1153;, + 3;1141,1168,1167;, + 3;1102,1155,1154;, + 3;1105,1156,1155;, + 3;1108,1157,1156;, + 3;1111,1158,1157;, + 3;1144,1169,1168;, + 3;1114,1159,1158;, + 3;1117,1160,1159;, + 3;1120,1161,1160;, + 3;1123,1162,1161;, + 3;1147,1170,1169;, + 3;1126,1163,1162;, + 3;1129,1164,1163;, + 3;1132,1165,1164;, + 3;1135,1166,1165;, + 3;1150,1151,1170;, + 3;1138,1167,1166;, + 3;1151,1152,1172;, + 3;1152,1153,1173;, + 3;1091,1094,1095;, + 3;1092,1095,1096;, + 3;1139,1142,1143;, + 3;1153,1154,1174;, + 3;1094,1097,1098;, + 3;1095,1098,1099;, + 3;1140,1143,1144;, + 3;1167,1168,1188;, + 3;1097,1100,1101;, + 3;1098,1101,1102;, + 3;1154,1155,1175;, + 3;1100,1103,1104;, + 3;1101,1104,1105;, + 3;1155,1156,1176;, + 3;1156,1157,1177;, + 3;1103,1106,1107;, + 3;1104,1107,1108;, + 3;1142,1145,1146;, + 3;1157,1158,1178;, + 3;1106,1109,1110;, + 3;1107,1110,1111;, + 3;1143,1146,1147;, + 3;1168,1169,1189;, + 3;1109,1112,1113;, + 3;1110,1113,1114;, + 3;1158,1159,1179;, + 3;1112,1115,1116;, + 3;1113,1116,1117;, + 3;1159,1160,1180;, + 3;1160,1161,1181;, + 3;1115,1118,1119;, + 3;1116,1119,1120;, + 3;1145,1148,1149;, + 3;1161,1162,1182;, + 3;1118,1121,1122;, + 3;1119,1122,1123;, + 3;1146,1149,1150;, + 3;1169,1170,1190;, + 3;1121,1124,1125;, + 3;1122,1125,1126;, + 3;1162,1163,1183;, + 3;1124,1127,1128;, + 3;1125,1128,1129;, + 3;1163,1164,1184;, + 3;1164,1165,1185;, + 3;1127,1130,1131;, + 3;1128,1131,1132;, + 3;1148,1091,1092;, + 3;1165,1166,1186;, + 3;1130,1133,1134;, + 3;1131,1134,1135;, + 3;1149,1092,1093;, + 3;1170,1151,1171;, + 3;1133,1136,1137;, + 3;1134,1137,1138;, + 3;1166,1167,1187;, + 3;1136,1139,1140;, + 3;1137,1140,1141;, + 3;1093,1096,1152;, + 3;1096,1099,1153;, + 3;1099,1102,1154;, + 3;1141,1144,1168;, + 3;1102,1105,1155;, + 3;1105,1108,1156;, + 3;1108,1111,1157;, + 3;1111,1114,1158;, + 3;1144,1147,1169;, + 3;1114,1117,1159;, + 3;1117,1120,1160;, + 3;1120,1123,1161;, + 3;1123,1126,1162;, + 3;1147,1150,1170;, + 3;1126,1129,1163;, + 3;1129,1132,1164;, + 3;1132,1135,1165;, + 3;1135,1138,1166;, + 3;1150,1093,1151;, + 3;1138,1141,1167;, + // Chassis + 3;1195,1191,1192;, + 3;1200,1195,1196;, + 3;1371,1366,1380;, + 3;1365,1369,1383;, + 3;1200,1201,1395;, + 3;1398,1196,1397;, + 3;1400,1398,1197;, + 3;1376,1375,1385;, + 3;1400,1201,1398;, + 3;1348,1386,1237;, + 3;1196,1398,1201;, + 3;1368,1367,1381;, + 3;1400,1396,1395;, + 3;1288,1293,1290;, + 3;1345,1386,1224;, + 3;1399,1258,1401;, + 3;1388,1344,1392;, + 3;1202,1206,1396;, + 3;1237,1259,1238;, + 3;1388,1387,1399;, + 3;1367,1365,1379;, + 3;1387,1388,1200;, + 3;1397,1193,1194;, + 3;1202,1197,1198;, + 3;1206,1202,1203;, + 3;1371,1253,1210;, + 3;1203,1198,1199;, + 3;1207,1203,1204;, + 3;1255,1254,1251;, + 3;1265,1267,1270;, + 3;1292,1290,1293;, + 3;1278,1216,1297;, + 3;1225,1296,1293;, + 3;1357,1369,1365;, + 3;1362,1194,1193;, + 3;1372,1377,1381;, + 3;1237,1238,1346;, + 3;1345,1316,1354;, + 3;1316,1345,1343;, + 3;1224,1211,1343;, + 3;1345,1257,1237;, + 3;1224,1349,1324;, + 3;1373,1372,1379;, + 3;1370,1371,1385;, + 3;1369,1370,1384;, + 3;1246,1390,1358;, + 3;1246,1389,1364;, + 3;1195,1200,1388;, + 3;1250,1245,1350;, + 3;1253,1250,1351;, + 3;1253,1352,1353;, + 3;1304,1277,1220;, + 3;1277,1304,1227;, + 3;1223,1255,1289;, + 3;1254,1255,1223;, + 3;1235,1239,1266;, + 3;1222,1226,1283;, + 3;1227,1304,1301;, + 3;1261,1221,1275;, + 3;1294,1307,1223;, + 3;1251,1240,1236;, + 3;1358,1391,1401;, + 3;1390,1393,1394;, + 3;1323,1191,1388;, + 3;1230,1231,1261;, + 3;1273,1269,1271;, + 3;1268,1259,1257;, + 3;1242,1243,1360;, + 3;1192,1247,1248;, + 3;1319,1317,1318;, + 3;1280,1279,1264;, + 3;1238,1239,1355;, + 3;1362,1248,1360;, + 3;1358,1394,1392;, + 3;1282,1281,1272;, + 3;1239,1235,1236;, + 3;1239,1240,1350;, + 3;1245,1356,1249;, + 3;1359,1360,1248;, + 3;1249,1360,1243;, + 3;1204,1199,1209;, + 3;1204,1367,1368;, + 3;1219,1213,1215;, + 3;1284,1283,1264;, + 3;1212,1254,1214;, + 3;1393,1242,1359;, + 3;1268,1267,1265;, + 3;1293,1288,1234;, + 3;1219,1220,1260;, + 3;1252,1236,1216;, + 3;1231,1340,1261;, + 3;1225,1229,1299;, + 3;1260,1261,1274;, + 3;1260,1270,1267;, + 3;1237,1257,1259;, + 3;1319,1320,1321;, + 3;1266,1264,1228;, + 3;1230,1326,1327;, + 3;1255,1252,1278;, + 3;1236,1235,1228;, + 3;1257,1354,1268;, + 3;1300,1295,1289;, + 3;1270,1274,1282;, + 3;1283,1284,1281;, + 3;1275,1286,1281;, + 3;1238,1266,1239;, + 3;1330,1339,1325;, + 3;1332,1334,1337;, + 3;1341,1342,1333;, + 3;1282,1274,1275;, + 3;1277,1230,1260;, + 3;1261,1340,1232;, + 3;1285,1265,1271;, + 3;1265,1263,1282;, + 3;1273,1272,1279;, + 3;1284,1279,1272;, + 3;1338,1326,1331;, + 3;1288,1218,1308;, + 3;1221,1222,1286;, + 3;1339,1336,1337;, + 3;1287,1337,1335;, + 3;1342,1338,1335;, + 3;1226,1228,1264;, + 3;1288,1276,1305;, + 3;1330,1332,1336;, + 3;1394,1247,1323;, + 3;1294,1295,1225;, + 3;1295,1294,1217;, + 3;1300,1297,1302;, + 3;1299,1298,1232;, + 3;1225,1295,1300;, + 3;1296,1299,1291;, + 3;1303,1234,1307;, + 3;1227,1305,1262;, + 3;1226,1297,1216;, + 3;1305,1301,1218;, + 3;1291,1232,1341;, + 3;1354,1316,1219;, + 3;1276,1262,1305;, + 3;1307,1306,1214;, + 3;1234,1308,1306;, + 3;1266,1238,1309;, + 3;1280,1266,1311;, + 3;1273,1280,1314;, + 3;1269,1273,1314;, + 3;1285,1269,1313;, + 3;1268,1285,1313;, + 3;1259,1268,1312;, + 3;1238,1259,1310;, + 3;1311,1309,1317;, + 3;1314,1311,1319;, + 3;1246,1241,1324;, + 3;1313,1314,1322;, + 3;1213,1219,1316;, + 3;1312,1313,1321;, + 3;1310,1312,1320;, + 3;1309,1310,1318;, + 3;1277,1331,1326;, + 3;1287,1331,1325;, + 3;1233,1231,1327;, + 3;1262,1276,1330;, + 3;1290,1292,1334;, + 3;1276,1290,1332;, + 3;1233,1328,1342;, + 3;1292,1291,1333;, + 3;1227,1262,1329;, + 3;1277,1227,1325;, + 3;1342,1328,1338;, + 3;1334,1333,1335;, + 3;1328,1327,1326;, + 3;1232,1298,1222;, + 3;1298,1299,1229;, + 3;1297,1226,1302;, + 3;1222,1298,1302;, + 3;1357,1361,1194;, + 3;1394,1359,1247;, + 3;1340,1341,1232;, + 3;1348,1347,1242;, + 3;1199,1198,1363;, + 3;1371,1370,1250;, + 3;1361,1365,1367;, + 3;1249,1356,1357;, + 3;1191,1323,1247;, + 3;1341,1340,1233;, + 3;1340,1231,1233;, + 3;1374,1373,1383;, + 3;1196,1192,1193;, + 3;1377,1378,1382;, + 3;1375,1374,1384;, + 3;1224,1386,1348;, + 3;1393,1390,1348;, + 3;1197,1397,1363;, + 3;1347,1346,1243;, + 3;1349,1348,1390;, + 3;1351,1350,1240;, + 3;1352,1351,1251;, + 3;1353,1352,1254;, + 3;1346,1355,1244;, + 3;1355,1350,1245;, + 3;1209,1363,1194;, + 3;1268,1354,1256;, + 3;1356,1370,1369;, + 3;1370,1356,1245;, + 3;1344,1401,1391;, + 3;1258,1364,1389;, + 3;1348,1237,1347;, + 3;1195,1192,1196;, + 3;1200,1196,1201;, + 3;1371,1380,1385;, + 3;1365,1383,1379;, + 3;1200,1395,1205;, + 3;1398,1397,1197;, + 3;1400,1197,1202;, + 3;1376,1385,1380;, + 3;1368,1381,1382;, + 3;1400,1395,1201;, + 3;1288,1290,1276;, + 3;1399,1401,1344;, + 3;1202,1396,1400;, + 3;1388,1399,1344;, + 3;1367,1379,1381;, + 3;1387,1200,1205;, + 3;1397,1194,1363;, + 3;1202,1198,1203;, + 3;1206,1203,1207;, + 3;1371,1210,1366;, + 3;1203,1199,1204;, + 3;1207,1204,1208;, + 3;1255,1251,1252;, + 3;1265,1270,1263;, + 3;1292,1293,1296;, + 3;1278,1297,1300;, + 3;1225,1293,1303;, + 3;1357,1365,1361;, + 3;1362,1193,1248;, + 3;1372,1381,1379;, + 3;1237,1346,1347;, + 3;1345,1354,1257;, + 3;1316,1343,1315;, + 3;1224,1343,1345;, + 3;1345,1237,1386;, + 3;1224,1324,1211;, + 3;1373,1379,1383;, + 3;1370,1385,1384;, + 3;1369,1384,1383;, + 3;1246,1358,1389;, + 3;1246,1364,1241;, + 3;1195,1388,1191;, + 3;1250,1350,1351;, + 3;1253,1351,1352;, + 3;1253,1353,1210;, + 3;1304,1220,1215;, + 3;1223,1289,1217;, + 3;1254,1223,1214;, + 3;1235,1266,1228;, + 3;1222,1283,1286;, + 3;1227,1301,1305;, + 3;1261,1275,1274;, + 3;1294,1223,1217;, + 3;1251,1236,1252;, + 3;1358,1401,1389;, + 3;1390,1394,1358;, + 3;1323,1388,1392;, + 3;1230,1261,1260;, + 3;1273,1271,1272;, + 3;1242,1360,1359;, + 3;1192,1248,1193;, + 3;1319,1318,1320;, + 3;1280,1264,1266;, + 3;1238,1355,1346;, + 3;1362,1360,1249;, + 3;1358,1392,1391;, + 3;1282,1272,1271;, + 3;1239,1236,1240;, + 3;1239,1350,1355;, + 3;1245,1249,1244;, + 3;1359,1248,1247;, + 3;1249,1243,1244;, + 3;1204,1209,1367;, + 3;1204,1368,1208;, + 3;1219,1215,1220;, + 3;1284,1264,1279;, + 3;1393,1359,1394;, + 3;1268,1265,1285;, + 3;1293,1234,1303;, + 3;1219,1260,1256;, + 3;1252,1216,1278;, + 3;1225,1299,1296;, + 3;1260,1274,1270;, + 3;1260,1267,1256;, + 3;1319,1321,1322;, + 3;1230,1327,1231;, + 3;1255,1278,1289;, + 3;1236,1228,1216;, + 3;1300,1289,1278;, + 3;1270,1282,1263;, + 3;1283,1281,1286;, + 3;1330,1325,1329;, + 3;1332,1337,1336;, + 3;1341,1333,1291;, + 3;1282,1275,1281;, + 3;1277,1260,1220;, + 3;1261,1232,1221;, + 3;1285,1271,1269;, + 3;1265,1282,1271;, + 3;1273,1279,1280;, + 3;1284,1272,1281;, + 3;1338,1331,1287;, + 3;1288,1308,1234;, + 3;1221,1286,1275;, + 3;1339,1337,1287;, + 3;1287,1335,1338;, + 3;1342,1335,1333;, + 3;1226,1264,1283;, + 3;1330,1336,1339;, + 3;1394,1323,1392;, + 3;1294,1225,1303;, + 3;1295,1217,1289;, + 3;1300,1302,1229;, + 3;1299,1232,1291;, + 3;1225,1300,1229;, + 3;1296,1291,1292;, + 3;1303,1307,1294;, + 3;1226,1216,1228;, + 3;1305,1218,1288;, + 3;1354,1219,1256;, + 3;1307,1214,1223;, + 3;1234,1306,1307;, + 3;1266,1309,1311;, + 3;1280,1311,1314;, + 3;1269,1314,1313;, + 3;1268,1313,1312;, + 3;1259,1312,1310;, + 3;1238,1310,1309;, + 3;1311,1317,1319;, + 3;1314,1319,1322;, + 3;1246,1324,1349;, + 3;1313,1322,1321;, + 3;1213,1316,1315;, + 3;1312,1321,1320;, + 3;1310,1320,1318;, + 3;1309,1318,1317;, + 3;1277,1326,1230;, + 3;1287,1325,1339;, + 3;1233,1327,1328;, + 3;1262,1330,1329;, + 3;1290,1334,1332;, + 3;1276,1332,1330;, + 3;1233,1342,1341;, + 3;1292,1333,1334;, + 3;1227,1329,1325;, + 3;1277,1325,1331;, + 3;1334,1335,1337;, + 3;1328,1326,1338;, + 3;1232,1222,1221;, + 3;1298,1229,1302;, + 3;1222,1302,1226;, + 3;1357,1194,1362;, + 3;1348,1242,1393;, + 3;1199,1363,1209;, + 3;1371,1250,1253;, + 3;1361,1367,1209;, + 3;1249,1357,1362;, + 3;1191,1247,1192;, + 3;1374,1383,1384;, + 3;1196,1193,1397;, + 3;1377,1382,1381;, + 3;1375,1384,1385;, + 3;1224,1348,1349;, + 3;1197,1363,1198;, + 3;1347,1243,1242;, + 3;1349,1390,1246;, + 3;1351,1240,1251;, + 3;1352,1251,1254;, + 3;1353,1254,1212;, + 3;1346,1244,1243;, + 3;1355,1245,1244;, + 3;1209,1194,1361;, + 3;1268,1256,1267;, + 3;1356,1369,1357;, + 3;1370,1245,1250;, + 3;1344,1391,1392;, + 3;1258,1389,1401;, + 3;1406,1403,1402;, + 3;1411,1407,1406;, + 3;1558,1380,1366;, + 3;1554,1566,1556;, + 3;1411,1395,1412;, + 3;1578,1577,1407;, + 3;1579,1408,1578;, + 3;1376,1568,1562;, + 3;1579,1578,1412;, + 3;1539,1437,1569;, + 3;1407,1412,1578;, + 3;1368,1565,1555;, + 3;1579,1395,1396;, + 3;1486,1488,1491;, + 3;1536,1424,1569;, + 3;1399,1580,1258;, + 3;1570,1574,1535;, + 3;1413,1396,1206;, + 3;1437,1438,1457;, + 3;1570,1399,1387;, + 3;1555,1564,1554;, + 3;1387,1411,1570;, + 3;1577,1405,1404;, + 3;1413,1409,1408;, + 3;1206,1414,1413;, + 3;1558,1210,1452;, + 3;1414,1410,1409;, + 3;1207,1415,1414;, + 3;1454,1450,1453;, + 3;1463,1468,1465;, + 3;1490,1491,1488;, + 3;1476,1495,1417;, + 3;1425,1491,1494;, + 3;1547,1554,1556;, + 3;1552,1404,1405;, + 3;1559,1565,1563;, + 3;1437,1537,1438;, + 3;1536,1544,1509;, + 3;1509,1343,1536;, + 3;1424,1343,1211;, + 3;1536,1437,1456;, + 3;1424,1324,1540;, + 3;1560,1564,1559;, + 3;1557,1568,1558;, + 3;1556,1567,1557;, + 3;1445,1548,1572;, + 3;1445,1364,1571;, + 3;1406,1570,1411;, + 3;1449,1541,1444;, + 3;1452,1542,1449;, + 3;1452,1353,1543;, + 3;1304,1420,1475;, + 3;1475,1427,1304;, + 3;1423,1487,1454;, + 3;1453,1423,1454;, + 3;1435,1464,1439;, + 3;1422,1481,1426;, + 3;1427,1301,1304;, + 3;1459,1473,1421;, + 3;1492,1423,1502;, + 3;1450,1436,1440;, + 3;1548,1580,1573;, + 3;1572,1576,1575;, + 3;1516,1570,1402;, + 3;1430,1459,1431;, + 3;1471,1469,1467;, + 3;1466,1456,1457;, + 3;1441,1550,1442;, + 3;1403,1447,1446;, + 3;1512,1511,1510;, + 3;1478,1462,1477;, + 3;1438,1545,1439;, + 3;1552,1550,1447;, + 3;1548,1574,1576;, + 3;1480,1470,1479;, + 3;1439,1436,1435;, + 3;1439,1541,1440;, + 3;1444,1448,1546;, + 3;1549,1447,1550;, + 3;1448,1442,1550;, + 3;1415,1416,1410;, + 3;1415,1368,1555;, + 3;1419,1215,1213;, + 3;1482,1462,1481;, + 3;1212,1214,1453;, + 3;1575,1549,1441;, + 3;1466,1463,1465;, + 3;1491,1434,1486;, + 3;1419,1458,1420;, + 3;1451,1417,1436;, + 3;1431,1459,1532;, + 3;1425,1497,1429;, + 3;1458,1472,1459;, + 3;1458,1465,1468;, + 3;1437,1457,1456;, + 3;1512,1514,1513;, + 3;1464,1428,1462;, + 3;1430,1519,1518;, + 3;1454,1476,1451;, + 3;1436,1428,1435;, + 3;1456,1466,1544;, + 3;1498,1487,1493;, + 3;1468,1480,1472;, + 3;1481,1479,1482;, + 3;1473,1479,1484;, + 3;1438,1439,1464;, + 3;1522,1517,1531;, + 3;1524,1529,1526;, + 3;1533,1525,1534;, + 3;1480,1473,1472;, + 3;1475,1458,1430;, + 3;1459,1432,1532;, + 3;1483,1469,1463;, + 3;1463,1480,1461;, + 3;1471,1477,1470;, + 3;1482,1470,1477;, + 3;1530,1523,1518;, + 3;1486,1308,1218;, + 3;1421,1484,1422;, + 3;1531,1529,1528;, + 3;1485,1527,1529;, + 3;1534,1527,1530;, + 3;1426,1462,1428;, + 3;1486,1501,1474;, + 3;1522,1528,1524;, + 3;1576,1516,1446;, + 3;1492,1425,1493;, + 3;1493,1418,1492;, + 3;1498,1499,1495;, + 3;1497,1432,1496;, + 3;1425,1498,1493;, + 3;1494,1489,1497;, + 3;1500,1502,1434;, + 3;1427,1460,1501;, + 3;1426,1417,1495;, + 3;1501,1218,1301;, + 3;1489,1533,1432;, + 3;1544,1419,1509;, + 3;1474,1501,1460;, + 3;1502,1214,1306;, + 3;1434,1306,1308;, + 3;1464,1503,1438;, + 3;1478,1505,1464;, + 3;1471,1508,1478;, + 3;1467,1508,1471;, + 3;1483,1507,1467;, + 3;1466,1507,1483;, + 3;1457,1506,1466;, + 3;1438,1504,1457;, + 3;1505,1510,1503;, + 3;1508,1512,1505;, + 3;1445,1324,1241;, + 3;1507,1515,1508;, + 3;1213,1509,1419;, + 3;1506,1514,1507;, + 3;1504,1513,1506;, + 3;1503,1511,1504;, + 3;1475,1518,1523;, + 3;1485,1517,1523;, + 3;1433,1519,1431;, + 3;1460,1522,1474;, + 3;1488,1526,1490;, + 3;1474,1524,1488;, + 3;1433,1534,1520;, + 3;1490,1525,1489;, + 3;1427,1521,1460;, + 3;1475,1517,1427;, + 3;1534,1530,1520;, + 3;1526,1527,1525;, + 3;1520,1518,1519;, + 3;1432,1422,1496;, + 3;1496,1429,1497;, + 3;1495,1499,1426;, + 3;1422,1499,1496;, + 3;1547,1405,1551;, + 3;1576,1446,1549;, + 3;1532,1432,1533;, + 3;1539,1441,1538;, + 3;1410,1553,1409;, + 3;1558,1449,1557;, + 3;1551,1555,1554;, + 3;1448,1547,1546;, + 3;1402,1446,1516;, + 3;1533,1433,1532;, + 3;1532,1433,1431;, + 3;1561,1566,1560;, + 3;1407,1404,1403;, + 3;1563,1382,1378;, + 3;1562,1567,1561;, + 3;1424,1539,1569;, + 3;1575,1539,1572;, + 3;1408,1553,1577;, + 3;1538,1442,1537;, + 3;1540,1572,1539;, + 3;1542,1440,1541;, + 3;1543,1450,1542;, + 3;1353,1453,1543;, + 3;1537,1443,1545;, + 3;1545,1444,1541;, + 3;1416,1405,1553;, + 3;1466,1455,1544;, + 3;1546,1556,1557;, + 3;1557,1444,1546;, + 3;1535,1573,1580;, + 3;1258,1571,1364;, + 3;1539,1538,1437;, + 3;1406,1407,1403;, + 3;1411,1412,1407;, + 3;1558,1568,1380;, + 3;1554,1564,1566;, + 3;1411,1205,1395;, + 3;1578,1408,1577;, + 3;1579,1413,1408;, + 3;1376,1380,1568;, + 3;1368,1382,1565;, + 3;1579,1412,1395;, + 3;1486,1474,1488;, + 3;1399,1535,1580;, + 3;1413,1579,1396;, + 3;1570,1535,1399;, + 3;1555,1565,1564;, + 3;1387,1205,1411;, + 3;1577,1553,1405;, + 3;1413,1414,1409;, + 3;1206,1207,1414;, + 3;1558,1366,1210;, + 3;1414,1415,1410;, + 3;1207,1208,1415;, + 3;1454,1451,1450;, + 3;1463,1461,1468;, + 3;1490,1494,1491;, + 3;1476,1498,1495;, + 3;1425,1500,1491;, + 3;1547,1551,1554;, + 3;1552,1447,1404;, + 3;1559,1564,1565;, + 3;1437,1538,1537;, + 3;1536,1456,1544;, + 3;1509,1315,1343;, + 3;1424,1536,1343;, + 3;1536,1569,1437;, + 3;1424,1211,1324;, + 3;1560,1566,1564;, + 3;1557,1567,1568;, + 3;1556,1566,1567;, + 3;1445,1571,1548;, + 3;1445,1241,1364;, + 3;1406,1402,1570;, + 3;1449,1542,1541;, + 3;1452,1543,1542;, + 3;1452,1210,1353;, + 3;1304,1215,1420;, + 3;1423,1418,1487;, + 3;1453,1214,1423;, + 3;1435,1428,1464;, + 3;1422,1484,1481;, + 3;1427,1501,1301;, + 3;1459,1472,1473;, + 3;1492,1418,1423;, + 3;1450,1451,1436;, + 3;1548,1571,1580;, + 3;1572,1548,1576;, + 3;1516,1574,1570;, + 3;1430,1458,1459;, + 3;1471,1470,1469;, + 3;1441,1549,1550;, + 3;1403,1404,1447;, + 3;1512,1513,1511;, + 3;1478,1464,1462;, + 3;1438,1537,1545;, + 3;1552,1448,1550;, + 3;1548,1573,1574;, + 3;1480,1469,1470;, + 3;1439,1440,1436;, + 3;1439,1545,1541;, + 3;1444,1443,1448;, + 3;1549,1446,1447;, + 3;1448,1443,1442;, + 3;1415,1555,1416;, + 3;1415,1208,1368;, + 3;1419,1420,1215;, + 3;1482,1477,1462;, + 3;1575,1576,1549;, + 3;1466,1483,1463;, + 3;1491,1500,1434;, + 3;1419,1455,1458;, + 3;1451,1476,1417;, + 3;1425,1494,1497;, + 3;1458,1468,1472;, + 3;1458,1455,1465;, + 3;1512,1515,1514;, + 3;1430,1431,1519;, + 3;1454,1487,1476;, + 3;1436,1417,1428;, + 3;1498,1476,1487;, + 3;1468,1461,1480;, + 3;1481,1484,1479;, + 3;1522,1521,1517;, + 3;1524,1528,1529;, + 3;1533,1489,1525;, + 3;1480,1479,1473;, + 3;1475,1420,1458;, + 3;1459,1421,1432;, + 3;1483,1467,1469;, + 3;1463,1469,1480;, + 3;1471,1478,1477;, + 3;1482,1479,1470;, + 3;1530,1485,1523;, + 3;1486,1434,1308;, + 3;1421,1473,1484;, + 3;1531,1485,1529;, + 3;1485,1530,1527;, + 3;1534,1525,1527;, + 3;1426,1481,1462;, + 3;1522,1531,1528;, + 3;1576,1574,1516;, + 3;1492,1500,1425;, + 3;1493,1487,1418;, + 3;1498,1429,1499;, + 3;1497,1489,1432;, + 3;1425,1429,1498;, + 3;1494,1490,1489;, + 3;1500,1492,1502;, + 3;1426,1428,1417;, + 3;1501,1486,1218;, + 3;1544,1455,1419;, + 3;1502,1423,1214;, + 3;1434,1502,1306;, + 3;1464,1505,1503;, + 3;1478,1508,1505;, + 3;1467,1507,1508;, + 3;1466,1506,1507;, + 3;1457,1504,1506;, + 3;1438,1503,1504;, + 3;1505,1512,1510;, + 3;1508,1515,1512;, + 3;1445,1540,1324;, + 3;1507,1514,1515;, + 3;1213,1315,1509;, + 3;1506,1513,1514;, + 3;1504,1511,1513;, + 3;1503,1510,1511;, + 3;1475,1430,1518;, + 3;1485,1531,1517;, + 3;1433,1520,1519;, + 3;1460,1521,1522;, + 3;1488,1524,1526;, + 3;1474,1522,1524;, + 3;1433,1533,1534;, + 3;1490,1526,1525;, + 3;1427,1517,1521;, + 3;1475,1523,1517;, + 3;1526,1529,1527;, + 3;1520,1530,1518;, + 3;1432,1421,1422;, + 3;1496,1499,1429;, + 3;1422,1426,1499;, + 3;1547,1552,1405;, + 3;1539,1575,1441;, + 3;1410,1416,1553;, + 3;1558,1452,1449;, + 3;1551,1416,1555;, + 3;1448,1552,1547;, + 3;1402,1403,1446;, + 3;1561,1567,1566;, + 3;1407,1577,1404;, + 3;1563,1565,1382;, + 3;1562,1568,1567;, + 3;1424,1540,1539;, + 3;1408,1409,1553;, + 3;1538,1441,1442;, + 3;1540,1445,1572;, + 3;1542,1450,1440;, + 3;1543,1453,1450;, + 3;1353,1212,1453;, + 3;1537,1442,1443;, + 3;1545,1443,1444;, + 3;1416,1551,1405;, + 3;1466,1465,1455;, + 3;1546,1547,1556;, + 3;1557,1449,1444;, + 3;1535,1574,1573;, + 3;1258,1580,1571;, + // Bubble + 3;1581,1597,1589;, + 3;1605,1604,1588;, + 3;1597,1605,1593;, + 3;1583,1585,1604;, + 3;1587,1588,1604;, + 3;1589,1597,1582;, + 3;1585,1586,1604;, + 3;1597,1581,1583;, + 3;1605,1588,1593;, + 3;1597,1593,1582;, + 3;1583,1604,1605;, + 3;1587,1604,1586;, + 3;1589,1582,1590;, + 3;1597,1583,1605;, + 3;1607,1611,1612;, + 3;1614,1588,1613;, + 3;1612,1593,1614;, + 3;1608,1613,1609;, + 3;1587,1613,1588;, + 3;1611,1582,1612;, + 3;1609,1613,1610;, + 3;1612,1608,1607;, + 3;1614,1593,1588;, + 3;1612,1582,1593;, + 3;1608,1614,1613;, + 3;1587,1610,1613;, + 3;1611,1590,1582;, + 3;1612,1614,1608;; + + MeshNormals { + 1615; + // Turret_base + -0.01;-1.0;0.025;, + 0.877;0.474;-0.079;, + 0.697;0.522;-0.491;, + 0.416;0.47;-0.779;, + -0.521;0.164;-0.837;, + -0.761;0.544;-0.352;, + -0.761;0.645;0.069;, + -0.649;0.608;0.457;, + -0.353;0.542;0.763;, + 0.047;0.851;0.522;, + 0.418;0.688;0.593;, + 0.817;0.436;0.378;, + 0.881;-0.472;0.03;, + 0.758;-0.495;-0.425;, + 0.524;-0.39;-0.757;, + -0.565;-0.434;-0.702;, + -0.722;-0.503;-0.475;, + -0.881;-0.472;-0.03;, + -0.778;-0.472;0.414;, + -0.467;-0.472;0.748;, + -0.03;-0.472;0.881;, + 0.414;-0.472;0.778;, + 0.748;-0.472;0.467;, + 0.559;-0.827;0.057;, + 0.541;-0.783;-0.306;, + -0.485;-0.799;-0.356;, + -0.515;-0.856;-0.038;, + -0.476;-0.855;0.206;, + -0.29;-0.856;0.428;, + -0.06;-0.855;0.515;, + 0.225;-0.856;0.465;, + 0.416;-0.855;0.309;, + -0.973;-0.112;-0.2;, + 0.323;0.882;-0.344;, + -0.334;0.932;-0.142;, + -0.687;-0.477;-0.547;, + 0.068;-0.797;-0.6;, + 0.017;-0.8;-0.6;, + 0.598;0.035;-0.801;, + 0.69;-0.564;-0.454;, + -0.141;0.381;-0.914;, + 0.252;0.443;-0.861;, + -0.521;0.007;-0.853;, + 0.008;0.653;-0.757;, + 0.65;-0.245;-0.719;, + // Gatling_base + 0.659;0.097;0.745;, + -0.923;-0.128;0.362;, + -0.394;0.001;-0.919;, + 0.328;-0.006;-0.945;, + 0.594;0.792;0.141;, + -0.597;-0.791;0.136;, + -0.376;-0.379;-0.845;, + 0.398;0.379;-0.836;, + 0.106;-0.785;0.61;, + -0.117;0.79;0.602;, + 0.013;0.404;-0.915;, + 0.006;-0.324;-0.946;, + -0.434;0.324;0.84;, + 0.649;-0.49;0.582;, + 0.273;-0.273;-0.923;, + -0.165;0.175;-0.971;, + -0.977;0.031;-0.212;, + -0.713;-0.67;-0.206;, + 0.981;-0.031;-0.19;, + 0.716;0.67;-0.197;, + -0.029;-0.98;-0.197;, + 0.673;-0.715;-0.19;, + 0.033;0.978;-0.206;, + -0.668;0.714;-0.212;, + // Gatling_base_2 + -0.329;-0.479;-0.814;, + -0.659;-0.003;-0.752;, + -0.659;-0.003;-0.752;, + -0.65;0.652;-0.391;, + 0.006;-0.749;-0.663;, + 0.009;-0.004;-1.0;, + 0.009;-0.004;-1.0;, + 0.007;0.663;-0.749;, + 0.006;-0.749;-0.663;, + 0.009;-0.004;-1.0;, + 0.009;-0.004;-1.0;, + 0.007;0.663;-0.749;, + 0.681;-0.68;-0.273;, + 0.752;-0.002;-0.659;, + 0.752;-0.002;-0.659;, + 0.483;0.334;-0.81;, + 0.707;-0.707;0.009;, + 1.0;0.0;0.009;, + 1.0;0.0;0.009;, + 0.746;0.666;0.004;, + 0.707;-0.707;0.009;, + 1.0;0.0;0.009;, + 1.0;0.0;0.009;, + 0.746;0.666;0.004;, + 0.35;-0.354;0.867;, + 0.659;0.003;0.752;, + 0.659;0.003;0.752;, + 0.65;0.655;0.386;, + -0.006;-0.704;0.71;, + -0.009;0.004;1.0;, + -0.009;0.004;1.0;, + -0.006;0.71;0.704;, + -0.006;-0.704;0.71;, + -0.009;0.004;1.0;, + -0.009;0.004;1.0;, + -0.006;0.71;0.704;, + -0.681;-0.678;0.278;, + -0.752;0.002;0.659;, + -0.752;0.002;0.659;, + -0.458;0.454;0.764;, + -0.666;-0.746;-0.003;, + -1.0;0.0;-0.009;, + -1.0;0.0;-0.009;, + -0.707;0.707;-0.009;, + -0.666;-0.746;-0.003;, + -1.0;0.0;-0.009;, + -1.0;0.0;-0.009;, + -0.707;0.707;-0.009;, + 0.0;1.0;-0.004;, + 0.0;1.0;-0.004;, + 0.0;1.0;-0.004;, + 0.0;1.0;-0.004;, + 0.0;-1.0;0.004;, + 0.0;-1.0;0.004;, + 0.0;-1.0;0.004;, + 0.0;-1.0;0.004;, + // Gatling_mid + 0.261;-0.004;0.996;, + -0.237;0.01;1.004;, + -0.319;0.136;-0.966;, + 0.308;-0.13;-0.972;, + 0.192;0.194;0.993;, + -0.153;-0.132;1.012;, + -0.29;-0.124;-0.978;, + 0.353;0.135;-0.953;, + -0.016;-0.265;0.995;, + -0.003;0.233;1.005;, + 0.15;0.328;-0.96;, + -0.123;-0.316;-0.969;, + -0.166;0.169;1.004;, + 0.177;-0.193;0.996;, + 0.13;-0.303;-0.973;, + -0.125;0.329;-0.964;, + -0.878;0.302;-0.285;, + -0.835;-0.41;-0.28;, + 0.885;-0.304;-0.261;, + 0.84;0.409;-0.266;, + -0.301;-0.883;-0.271;, + 0.412;-0.839;-0.263;, + 0.305;0.88;-0.275;, + -0.406;0.836;-0.283;, + -0.821;0.208;0.501;, + -0.728;-0.431;0.502;, + 0.817;-0.206;0.506;, + 0.722;0.435;0.505;, + -0.211;-0.817;0.504;, + 0.43;-0.725;0.506;, + 0.203;0.82;0.503;, + -0.436;0.725;0.501;, + -0.741;0.52;-0.362;, + -0.874;-0.326;-0.271;, + -0.382;-0.852;-0.268;, + 0.332;-0.874;-0.262;, + 0.759;-0.45;-0.424;, + 0.878;0.324;-0.257;, + 0.465;0.739;-0.444;, + -0.154;0.893;-0.358;, + -0.891;0.175;0.355;, + -0.752;-0.438;0.451;, + -0.389;-0.831;0.326;, + 0.377;-0.848;0.288;, + 0.869;-0.326;0.286;, + 0.736;0.514;0.384;, + 0.325;0.873;0.277;, + -0.508;0.752;0.356;, + 0.281;0.117;0.982;, + -0.179;-0.063;1.015;, + 0.212;-0.093;1.005;, + -0.253;0.111;0.992;, + 0.08;0.207;1.008;, + 0.079;-0.221;1.004;, + -0.106;-0.217;1.002;, + -0.106;0.252;0.993;, + -0.229;0.089;-1.001;, + -0.168;-0.082;-1.015;, + -0.094;-0.267;-0.99;, + 0.123;-0.263;-0.988;, + 0.273;-0.107;-0.987;, + 0.377;0.158;-0.939;, + 0.108;0.249;-0.994;, + -0.094;0.231;-1.0;, + // Gatling_fin_1 + 0.125;0.001;1.026;, + -0.122;0.006;1.027;, + -0.154;0.065;-1.019;, + 0.159;-0.067;-1.019;, + 0.09;0.099;1.025;, + -0.08;-0.064;1.029;, + -0.135;-0.062;-1.023;, + 0.181;0.066;-1.014;, + -0.012;-0.129;1.026;, + -0.007;0.118;1.027;, + 0.08;0.162;-1.017;, + -0.055;-0.156;-1.02;, + -0.087;0.085;1.027;, + 0.084;-0.093;1.026;, + 0.074;-0.162;-1.018;, + -0.057;0.161;-1.019;, + -0.838;0.307;-0.395;, + -0.811;-0.379;-0.39;, + 0.847;-0.309;-0.373;, + 0.817;0.377;-0.378;, + -0.305;-0.845;-0.381;, + 0.382;-0.816;-0.375;, + 0.312;0.841;-0.387;, + -0.374;0.812;-0.393;, + -0.677;0.122;0.728;, + -0.566;-0.388;0.729;, + 0.67;-0.119;0.734;, + 0.556;0.393;0.734;, + -0.127;-0.672;0.731;, + 0.386;-0.561;0.734;, + 0.115;0.675;0.731;, + -0.395;0.562;0.729;, + -0.565;0.404;-0.719;, + -0.763;-0.382;-0.485;, + -0.36;-0.815;-0.402;, + 0.322;-0.834;-0.395;, + 0.531;-0.338;-0.786;, + 0.772;0.378;-0.474;, + 0.343;0.518;-0.793;, + -0.111;0.689;-0.716;, + -0.684;0.123;0.72;, + -0.517;-0.318;0.806;, + -0.422;-0.714;0.532;, + 0.355;-0.81;0.416;, + 0.755;-0.382;0.499;, + 0.626;0.503;0.576;, + 0.379;0.762;0.491;, + -0.401;0.567;0.721;, + 0.136;0.061;1.023;, + -0.095;-0.03;1.03;, + 0.102;-0.044;1.028;, + -0.132;0.057;1.024;, + 0.035;0.106;1.028;, + 0.035;-0.109;1.028;, + -0.057;-0.107;1.027;, + -0.059;0.128;1.024;, + -0.113;0.045;-1.027;, + -0.083;-0.044;-1.03;, + -0.044;-0.139;-1.023;, + 0.067;-0.137;-1.022;, + 0.145;-0.057;-1.022;, + 0.211;0.084;-1.006;, + 0.056;0.114;-1.026;, + -0.046;0.124;-1.025;, + // Gatling_fin_2 + 0.125;0.001;1.026;, + -0.122;0.006;1.027;, + -0.154;0.065;-1.019;, + 0.159;-0.067;-1.019;, + 0.09;0.099;1.025;, + -0.08;-0.064;1.029;, + -0.135;-0.062;-1.023;, + 0.181;0.066;-1.014;, + -0.012;-0.129;1.026;, + -0.007;0.118;1.027;, + 0.08;0.162;-1.017;, + -0.053;-0.151;-1.021;, + -0.087;0.085;1.027;, + 0.084;-0.093;1.026;, + 0.07;-0.153;-1.019;, + -0.057;0.161;-1.019;, + -0.838;0.307;-0.395;, + -0.811;-0.379;-0.39;, + 0.847;-0.309;-0.373;, + 0.817;0.377;-0.378;, + -0.305;-0.845;-0.381;, + 0.382;-0.816;-0.375;, + 0.312;0.841;-0.387;, + -0.374;0.812;-0.393;, + -0.677;0.122;0.728;, + -0.566;-0.388;0.729;, + 0.67;-0.119;0.734;, + 0.556;0.393;0.733;, + -0.127;-0.672;0.731;, + 0.386;-0.561;0.734;, + 0.115;0.675;0.731;, + -0.395;0.562;0.729;, + -0.565;0.404;-0.719;, + -0.763;-0.382;-0.485;, + -0.36;-0.815;-0.402;, + 0.322;-0.834;-0.395;, + 0.531;-0.338;-0.786;, + 0.772;0.378;-0.474;, + 0.343;0.518;-0.793;, + -0.111;0.689;-0.716;, + -0.684;0.123;0.72;, + -0.517;-0.318;0.806;, + -0.422;-0.714;0.532;, + 0.355;-0.81;0.416;, + 0.755;-0.382;0.499;, + 0.626;0.503;0.576;, + 0.379;0.762;0.491;, + -0.401;0.567;0.721;, + 0.136;0.061;1.023;, + -0.095;-0.03;1.03;, + 0.102;-0.044;1.028;, + -0.132;0.057;1.024;, + 0.035;0.106;1.028;, + 0.035;-0.109;1.028;, + -0.057;-0.107;1.027;, + -0.059;0.128;1.024;, + -0.113;0.045;-1.027;, + -0.083;-0.044;-1.03;, + -0.044;-0.139;-1.023;, + 0.067;-0.137;-1.022;, + 0.145;-0.057;-1.022;, + 0.211;0.084;-1.006;, + 0.058;0.119;-1.025;, + -0.043;0.117;-1.026;, + 0.0;0.0;0.0;, + // Gatling_fin_3 + 0.125;0.001;1.026;, + -0.122;0.006;1.027;, + -0.154;0.065;-1.019;, + 0.159;-0.067;-1.019;, + 0.09;0.099;1.025;, + -0.089;-0.073;1.028;, + -0.135;-0.062;-1.023;, + 0.181;0.066;-1.014;, + -0.012;-0.129;1.026;, + -0.007;0.118;1.027;, + 0.08;0.162;-1.017;, + -0.053;-0.151;-1.021;, + -0.087;0.085;1.027;, + 0.084;-0.093;1.026;, + 0.07;-0.153;-1.019;, + -0.057;0.161;-1.019;, + -0.838;0.307;-0.395;, + -0.811;-0.379;-0.39;, + 0.847;-0.309;-0.373;, + 0.817;0.377;-0.378;, + -0.305;-0.845;-0.381;, + 0.382;-0.816;-0.375;, + 0.312;0.841;-0.387;, + -0.374;0.812;-0.393;, + -0.677;0.122;0.728;, + -0.566;-0.388;0.729;, + 0.67;-0.119;0.734;, + 0.556;0.393;0.734;, + -0.127;-0.672;0.731;, + 0.386;-0.561;0.734;, + 0.115;0.675;0.731;, + -0.395;0.562;0.729;, + -0.565;0.404;-0.719;, + -0.763;-0.382;-0.485;, + -0.36;-0.815;-0.402;, + 0.322;-0.834;-0.395;, + 0.531;-0.338;-0.786;, + 0.772;0.378;-0.474;, + 0.343;0.518;-0.793;, + -0.111;0.689;-0.716;, + -0.684;0.123;0.72;, + -0.517;-0.318;0.806;, + -0.422;-0.714;0.532;, + 0.355;-0.81;0.416;, + 0.755;-0.382;0.499;, + 0.626;0.503;0.576;, + 0.379;0.762;0.491;, + -0.401;0.567;0.721;, + 0.179;0.078;1.014;, + -0.095;-0.03;1.03;, + 0.102;-0.044;1.028;, + -0.132;0.057;1.024;, + 0.044;0.127;1.025;, + 0.035;-0.109;1.028;, + -0.057;-0.107;1.027;, + -0.059;0.128;1.024;, + -0.113;0.045;-1.027;, + -0.083;-0.044;-1.03;, + -0.044;-0.139;-1.023;, + 0.067;-0.137;-1.022;, + 0.145;-0.057;-1.022;, + 0.211;0.084;-1.006;, + 0.058;0.119;-1.025;, + -0.043;0.117;-1.026;, + 0.0;0.0;0.0;, + 0.0;0.0;0.0;, + 0.0;0.0;0.0;, + // Barrel_11 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_1 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_13 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_14 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_12 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_16 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_17 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Barrel_15 + -0.009;0.004;1.0;, + 0.588;-0.682;-0.434;, + 0.822;0.116;0.558;, + 0.994;-0.013;-0.105;, + 0.713;0.693;-0.111;, + 0.9;-0.07;-0.43;, + 0.499;0.667;0.553;, + 0.014;0.993;-0.12;, + -0.692;0.711;-0.127;, + 0.687;0.584;-0.431;, + -0.992;0.013;-0.127;, + -0.119;0.829;0.547;, + 0.073;0.894;-0.443;, + -0.711;-0.693;-0.121;, + -0.012;-0.994;-0.112;, + -0.67;0.506;0.543;, + 0.694;-0.712;-0.106;, + -0.578;0.678;-0.454;, + -0.992;-0.048;0.118;, + -0.832;-0.112;0.544;, + -0.885;0.067;-0.461;, + -0.668;-0.734;0.124;, + -0.509;-0.663;0.549;, + 0.047;-0.99;0.133;, + 0.733;-0.666;0.14;, + -0.673;-0.582;-0.456;, + 0.989;0.049;0.14;, + 0.109;-0.825;0.555;, + 0.665;0.735;0.134;, + -0.064;-0.893;-0.445;, + 0.66;-0.502;0.559;, + -0.049;0.991;0.125;, + -0.736;0.667;0.119;, + -0.846;0.528;0.066;, + -0.972;-0.224;0.075;, + -0.528;-0.845;0.086;, + 0.224;-0.97;0.094;, + 0.845;-0.527;0.092;, + 0.971;0.225;0.085;, + 0.527;0.846;0.079;, + -0.225;0.972;0.071;, + -0.583;0.772;-0.253;, + -0.521;0.07;-0.85;, + -0.789;-0.599;-0.14;, + -0.124;-0.924;-0.361;, + 0.41;-0.535;-0.739;, + 0.963;-0.133;-0.236;, + 0.519;0.385;-0.763;, + 0.123;0.854;-0.506;, + // Side_guns + 0.991;0.137;0.0;, + -0.991;-0.137;0.0;, + -0.666;0.071;-0.742;, + 0.675;-0.071;-0.734;, + 0.604;0.797;0.0;, + -0.604;-0.797;0.0;, + -0.521;-0.422;-0.742;, + 0.527;0.426;-0.735;, + 0.137;-0.991;0.0;, + -0.137;0.991;0.0;, + -0.07;-0.67;-0.739;, + 0.071;0.671;-0.738;, + -0.797;0.604;0.0;, + 0.797;-0.604;0.0;, + -0.422;0.523;-0.741;, + 0.426;-0.526;-0.736;, + 0.876;0.19;-0.443;, + -0.87;-0.189;-0.455;, + 0.485;0.753;-0.445;, + -0.482;-0.75;-0.453;, + -0.189;0.873;-0.449;, + 0.19;-0.873;-0.449;, + 0.753;-0.484;-0.445;, + -0.749;0.482;-0.453;, + 0.96;-0.131;-0.247;, + -0.96;0.131;-0.247;, + 0.414;0.315;-0.854;, + -0.414;-0.315;-0.854;, + 0.131;0.96;-0.247;, + -0.131;-0.96;-0.247;, + 0.392;-0.516;-0.761;, + -0.432;0.569;-0.699;, + 0.981;-0.027;-0.193;, + 0.713;0.674;-0.195;, + -0.713;-0.673;-0.199;, + -0.028;-0.98;-0.196;, + 0.028;0.98;-0.198;, + -0.673;0.712;-0.2;, + 0.674;-0.713;-0.194;, + -0.979;0.028;-0.2;, + 0.976;0.047;0.212;, + 0.657;0.723;0.211;, + -0.047;0.977;0.208;, + -0.724;0.658;0.205;, + -0.978;-0.047;0.204;, + -0.659;-0.724;0.205;, + 0.046;-0.977;0.207;, + 0.723;-0.658;0.21;, + -1.0;0.015;0.0;, + 1.0;-0.015;0.0;, + 0.736;0.123;-0.665;, + -0.745;-0.123;-0.656;, + -0.697;0.717;0.0;, + 0.697;-0.717;0.0;, + 0.608;-0.434;-0.665;, + -0.613;0.439;-0.656;, + -0.015;-1.0;0.0;, + 0.015;1.0;0.0;, + 0.123;-0.74;-0.662;, + -0.123;0.742;-0.66;, + 0.717;0.697;0.0;, + -0.717;-0.697;0.0;, + 0.435;0.609;-0.663;, + -0.438;-0.612;-0.658;, + -0.963;0.126;0.238;, + 0.968;-0.126;0.217;, + -0.592;0.771;0.234;, + 0.595;-0.773;0.22;, + 0.127;0.966;0.226;, + -0.126;-0.965;0.228;, + -0.77;-0.593;0.235;, + 0.774;0.595;0.219;, + -0.953;-0.285;-0.103;, + 0.957;0.286;-0.056;, + -0.747;0.403;-0.529;, + 0.763;-0.412;-0.499;, + -0.286;0.957;-0.056;, + 0.286;-0.957;-0.056;, + -0.448;-0.83;-0.332;, + 0.443;0.822;-0.358;, + -0.951;-0.308;-0.043;, + -0.89;0.455;-0.043;, + 0.89;-0.455;-0.044;, + 0.308;-0.951;-0.043;, + -0.307;0.951;-0.044;, + 0.455;0.89;-0.044;, + -0.455;-0.89;-0.043;, + 0.95;0.308;-0.044;, + -0.998;0.014;0.064;, + -0.696;0.715;0.064;, + 0.014;0.998;0.063;, + 0.715;0.696;0.062;, + 0.998;-0.013;0.061;, + 0.696;-0.715;0.061;, + -0.014;-0.998;0.062;, + -0.715;-0.696;0.063;, + // Frontal_aux_gun + 0.991;0.137;0.0;, + -0.991;-0.137;0.0;, + -0.666;0.071;-0.742;, + 0.675;-0.071;-0.734;, + 0.604;0.797;0.0;, + -0.604;-0.797;0.0;, + -0.521;-0.422;-0.742;, + 0.527;0.426;-0.735;, + 0.137;-0.991;0.0;, + -0.137;0.991;0.0;, + -0.07;-0.67;-0.739;, + 0.071;0.671;-0.738;, + -0.797;0.604;0.0;, + 0.797;-0.604;0.0;, + -0.422;0.523;-0.741;, + 0.426;-0.526;-0.736;, + 0.876;0.19;-0.443;, + -0.87;-0.189;-0.455;, + 0.485;0.753;-0.445;, + -0.482;-0.75;-0.453;, + -0.189;0.873;-0.449;, + 0.19;-0.873;-0.449;, + 0.753;-0.484;-0.445;, + -0.749;0.482;-0.453;, + 0.958;-0.113;-0.262;, + -0.958;0.113;-0.262;, + 0.389;0.307;-0.869;, + -0.389;-0.307;-0.869;, + 0.113;0.958;-0.262;, + -0.113;-0.958;-0.262;, + 0.386;-0.49;-0.782;, + -0.428;0.543;-0.723;, + 0.981;-0.027;-0.193;, + 0.713;0.674;-0.195;, + -0.713;-0.673;-0.199;, + -0.028;-0.98;-0.196;, + 0.028;0.98;-0.198;, + -0.673;0.712;-0.2;, + 0.674;-0.713;-0.194;, + -0.979;0.028;-0.2;, + 0.973;0.05;0.227;, + 0.652;0.723;0.226;, + -0.05;0.974;0.223;, + -0.724;0.654;0.22;, + -0.975;-0.05;0.218;, + -0.654;-0.724;0.219;, + 0.05;-0.974;0.222;, + 0.723;-0.653;0.226;, + -1.0;0.015;0.0;, + 1.0;-0.015;0.0;, + 0.736;0.123;-0.665;, + -0.745;-0.123;-0.656;, + -0.697;0.717;0.0;, + 0.697;-0.717;0.0;, + 0.608;-0.434;-0.665;, + -0.613;0.439;-0.656;, + -0.015;-1.0;0.0;, + 0.015;1.0;0.0;, + 0.123;-0.74;-0.662;, + -0.123;0.742;-0.66;, + 0.717;0.697;0.0;, + -0.717;-0.697;0.0;, + 0.435;0.609;-0.663;, + -0.438;-0.612;-0.658;, + -0.963;0.126;0.238;, + 0.968;-0.126;0.217;, + -0.592;0.771;0.234;, + 0.595;-0.773;0.22;, + 0.127;0.966;0.226;, + -0.126;-0.965;0.228;, + -0.77;-0.593;0.235;, + 0.774;0.595;0.219;, + -0.952;-0.179;-0.25;, + 0.973;0.183;-0.138;, + -0.448;0.306;-0.84;, + 0.473;-0.324;-0.819;, + -0.183;0.973;-0.138;, + 0.183;-0.973;-0.138;, + -0.425;-0.622;-0.658;, + 0.409;0.598;-0.69;, + -0.951;-0.308;-0.043;, + -0.89;0.455;-0.043;, + 0.89;-0.455;-0.044;, + 0.308;-0.951;-0.043;, + -0.307;0.951;-0.044;, + 0.455;0.89;-0.044;, + -0.455;-0.89;-0.043;, + 0.95;0.308;-0.044;, + -0.987;0.019;0.16;, + -0.684;0.711;0.159;, + 0.019;0.987;0.157;, + 0.712;0.685;0.154;, + 0.988;-0.019;0.153;, + 0.685;-0.712;0.153;, + -0.019;-0.988;0.156;, + -0.712;-0.685;0.158;, + // Jet + 0.0;0.0;1.0;, + 0.0;0.0;0.0;, + 0.964;-0.061;-0.259;, + 0.992;-0.008;-0.128;, + 0.521;0.417;0.745;, + 0.0;0.0;0.0;, + 0.899;-0.352;-0.26;, + 0.942;-0.31;-0.128;, + 0.643;0.232;0.73;, + 0.0;0.0;0.0;, + 0.747;-0.611;-0.261;, + 0.802;-0.584;-0.128;, + 0.703;0.016;0.711;, + 0.0;0.0;0.0;, + 0.521;-0.812;-0.263;, + 0.582;-0.803;-0.129;, + 0.688;-0.208;0.695;, + 0.0;0.0;0.0;, + 0.242;-0.934;-0.264;, + 0.302;-0.944;-0.13;, + 0.598;-0.41;0.689;, + 0.0;0.0;0.0;, + -0.063;-0.962;-0.264;, + -0.008;-0.991;-0.13;, + 0.446;-0.564;0.695;, + 0.0;0.0;0.0;, + -0.361;-0.895;-0.263;, + -0.319;-0.939;-0.13;, + 0.254;-0.655;0.712;, + 0.0;0.0;0.0;, + -0.622;-0.738;-0.262;, + -0.595;-0.793;-0.129;, + 0.046;-0.681;0.731;, + 0.0;0.0;0.0;, + -0.819;-0.511;-0.261;, + -0.811;-0.57;-0.128;, + -0.161;-0.646;0.746;, + 0.0;0.0;0.0;, + -0.937;-0.236;-0.26;, + -0.947;-0.294;-0.128;, + -0.355;-0.557;0.751;, + 0.0;0.0;0.0;, + -0.964;0.061;-0.259;, + -0.992;0.008;-0.128;, + -0.521;-0.417;0.745;, + 0.0;0.0;0.0;, + -0.899;0.352;-0.26;, + -0.942;0.31;-0.128;, + -0.643;-0.232;0.73;, + 0.0;0.0;0.0;, + -0.747;0.611;-0.261;, + -0.802;0.584;-0.128;, + -0.703;-0.016;0.711;, + 0.0;0.0;0.0;, + -0.521;0.812;-0.263;, + -0.582;0.803;-0.129;, + -0.688;0.208;0.695;, + 0.0;0.0;0.0;, + -0.242;0.934;-0.264;, + -0.302;0.944;-0.13;, + -0.598;0.41;0.689;, + 0.0;0.0;0.0;, + 0.063;0.962;-0.264;, + 0.008;0.991;-0.13;, + -0.446;0.564;0.695;, + 0.0;0.0;0.0;, + 0.361;0.895;-0.263;, + 0.319;0.939;-0.13;, + -0.254;0.655;0.712;, + 0.0;0.0;0.0;, + 0.622;0.738;-0.262;, + 0.595;0.793;-0.129;, + -0.046;0.681;0.731;, + 0.0;0.0;0.0;, + 0.819;0.511;-0.261;, + 0.811;0.57;-0.128;, + 0.161;0.646;0.746;, + 0.0;0.0;0.0;, + 0.937;0.236;-0.26;, + 0.947;0.294;-0.128;, + 0.355;0.557;0.751;, + -0.917;-0.014;0.398;, + -0.878;0.265;0.397;, + -0.756;0.522;0.394;, + -0.56;0.731;0.391;, + -0.305;0.87;0.387;, + -0.017;0.922;0.386;, + 0.273;0.881;0.387;, + 0.534;0.75;0.39;, + 0.739;0.547;0.394;, + 0.87;0.294;0.397;, + 0.917;0.014;0.398;, + 0.878;-0.265;0.397;, + 0.756;-0.522;0.394;, + 0.56;-0.731;0.391;, + 0.305;-0.87;0.387;, + 0.017;-0.922;0.386;, + -0.273;-0.881;0.387;, + -0.534;-0.75;0.39;, + -0.739;-0.547;0.394;, + -0.87;-0.294;0.397;, + -0.566;-0.042;0.823;, + -0.552;0.132;0.823;, + -0.486;0.295;0.823;, + -0.374;0.431;0.821;, + -0.222;0.528;0.82;, + -0.045;0.571;0.819;, + 0.137;0.556;0.82;, + 0.304;0.484;0.82;, + 0.438;0.365;0.822;, + 0.527;0.212;0.823;, + 0.566;0.042;0.823;, + 0.552;-0.132;0.823;, + 0.486;-0.295;0.823;, + 0.374;-0.431;0.821;, + 0.222;-0.528;0.82;, + 0.045;-0.571;0.819;, + -0.137;-0.556;0.82;, + -0.304;-0.484;0.82;, + -0.438;-0.365;0.822;, + -0.527;-0.212;0.823;, + 0.0;0.0;1.0;, + -0.965;-0.022;-0.26;, + -0.993;0.026;-0.111;, + -0.639;0.449;0.625;, + -0.913;-0.315;-0.26;, + -0.954;-0.279;-0.111;, + -0.752;0.232;0.617;, + -0.772;-0.579;-0.262;, + -0.823;-0.557;-0.112;, + -0.797;-0.01;0.603;, + -0.555;-0.789;-0.263;, + -0.61;-0.784;-0.112;, + -0.767;-0.257;0.588;, + -0.281;-0.923;-0.264;, + -0.336;-0.935;-0.113;, + -0.657;-0.485;0.578;, + 0.022;-0.964;-0.264;, + -0.027;-0.993;-0.113;, + -0.476;-0.664;0.576;, + 0.323;-0.909;-0.264;, + 0.286;-0.952;-0.113;, + -0.246;-0.773;0.585;, + 0.59;-0.764;-0.263;, + 0.568;-0.815;-0.113;, + 0.007;-0.8;0.599;, + 0.797;-0.544;-0.261;, + 0.793;-0.599;-0.112;, + 0.252;-0.748;0.614;, + 0.926;-0.274;-0.26;, + 0.938;-0.327;-0.112;, + 0.468;-0.626;0.624;, + 0.965;0.022;-0.26;, + 0.993;-0.026;-0.111;, + 0.639;-0.449;0.625;, + 0.913;0.315;-0.26;, + 0.954;0.279;-0.111;, + 0.752;-0.232;0.617;, + 0.772;0.579;-0.262;, + 0.823;0.557;-0.112;, + 0.797;0.01;0.603;, + 0.555;0.789;-0.263;, + 0.61;0.784;-0.112;, + 0.767;0.257;0.588;, + 0.281;0.923;-0.264;, + 0.336;0.935;-0.113;, + 0.657;0.485;0.578;, + -0.022;0.964;-0.264;, + 0.027;0.993;-0.113;, + 0.476;0.664;0.576;, + -0.323;0.909;-0.264;, + -0.286;0.952;-0.113;, + 0.246;0.773;0.585;, + -0.59;0.764;-0.263;, + -0.568;0.815;-0.113;, + -0.007;0.8;0.599;, + -0.797;0.544;-0.261;, + -0.793;0.599;-0.112;, + -0.252;0.748;0.614;, + -0.926;0.274;-0.26;, + -0.938;0.327;-0.112;, + -0.468;0.626;0.624;, + 0.885;-0.023;0.465;, + 0.85;0.248;0.465;, + 0.734;0.496;0.464;, + 0.546;0.699;0.463;, + 0.301;0.835;0.461;, + 0.025;0.888;0.46;, + -0.254;0.851;0.46;, + -0.507;0.728;0.461;, + -0.707;0.535;0.463;, + -0.836;0.292;0.464;, + -0.885;0.023;0.465;, + -0.85;-0.248;0.465;, + -0.734;-0.496;0.464;, + -0.546;-0.699;0.463;, + -0.301;-0.835;0.461;, + -0.025;-0.888;0.46;, + 0.254;-0.851;0.46;, + 0.507;-0.728;0.461;, + 0.707;-0.535;0.463;, + 0.836;-0.292;0.464;, + 0.457;-0.05;0.888;, + 0.449;0.091;0.889;, + 0.396;0.221;0.891;, + 0.305;0.328;0.894;, + 0.186;0.402;0.897;, + 0.051;0.438;0.898;, + -0.089;0.434;0.897;, + -0.223;0.388;0.894;, + -0.337;0.303;0.891;, + -0.418;0.186;0.889;, + -0.457;0.05;0.888;, + -0.449;-0.091;0.889;, + -0.396;-0.221;0.891;, + -0.305;-0.328;0.894;, + -0.186;-0.402;0.897;, + -0.051;-0.438;0.898;, + 0.089;-0.434;0.897;, + 0.223;-0.388;0.894;, + 0.337;-0.303;0.891;, + 0.418;-0.186;0.889;, + // Chassis + -0.212;-0.977;-0.023;, + -0.815;-0.515;-0.266;, + -0.926;-0.177;-0.333;, + -0.91;0.252;-0.329;, + -0.145;-0.982;-0.123;, + -0.611;-0.628;-0.482;, + -0.621;-0.376;-0.688;, + -0.596;0.238;-0.767;, + -0.564;0.548;-0.618;, + -0.042;-0.993;-0.106;, + -0.239;-0.793;-0.561;, + -0.273;-0.297;-0.915;, + -0.247;0.269;-0.931;, + -0.162;0.76;-0.629;, + 0.0;-0.996;-0.088;, + -0.031;-0.257;-0.966;, + -0.01;0.386;-0.922;, + 0.01;0.785;-0.619;, + -0.601;0.676;-0.427;, + 0.016;0.995;-0.101;, + 0.0;-0.999;0.05;, + -0.006;0.999;-0.036;, + -0.002;-1.0;-0.021;, + 0.058;0.998;0.027;, + -0.001;-1.0;0.001;, + -0.724;0.676;-0.135;, + 0.059;0.997;-0.058;, + -0.065;0.373;0.926;, + -0.009;-0.999;-0.033;, + 0.05;-0.999;-0.021;, + -0.635;0.017;0.772;, + -0.845;0.263;0.467;, + 0.558;0.828;-0.063;, + -0.098;-0.995;0.034;, + -0.001;0.945;0.327;, + -0.81;0.568;0.147;, + 0.513;-0.793;0.328;, + -0.642;0.762;-0.091;, + -0.198;0.913;0.356;, + -0.278;-0.961;0.012;, + -0.672;-0.736;0.078;, + -0.836;0.152;0.527;, + -0.59;-0.285;0.756;, + 0.608;0.753;0.251;, + -0.604;0.792;-0.09;, + -0.553;0.815;-0.174;, + -0.625;-0.693;-0.36;, + -0.742;-0.186;-0.644;, + -0.835;0.371;-0.407;, + -0.565;0.795;-0.219;, + -0.01;-0.98;0.201;, + -0.773;-0.628;-0.096;, + -0.942;-0.263;-0.207;, + -0.962;0.087;-0.26;, + -0.749;0.61;-0.259;, + -0.132;-0.976;0.175;, + -0.697;-0.703;-0.141;, + -0.961;-0.18;-0.212;, + -0.945;0.228;-0.235;, + -0.402;0.893;-0.2;, + -0.2;0.976;-0.087;, + -0.158;0.946;-0.283;, + -0.188;0.971;-0.146;, + -0.027;0.999;-0.046;, + -0.014;0.985;-0.173;, + 0.128;-0.992;-0.013;, + -0.038;-0.88;-0.474;, + 0.051;-0.937;-0.346;, + -0.558;-0.325;-0.763;, + -0.08;-0.99;0.115;, + -0.708;-0.546;0.447;, + 0.87;-0.401;0.287;, + -0.02;-0.837;0.547;, + -0.592;0.806;0.005;, + 0.15;-0.983;0.105;, + -0.545;0.747;-0.38;, + 0.138;-0.987;0.082;, + 0.164;-0.959;-0.231;, + -0.866;-0.445;-0.227;, + 0.018;-0.891;0.455;, + -0.862;-0.497;0.101;, + -0.869;-0.27;0.415;, + -0.923;-0.365;-0.119;, + -0.185;-0.463;0.867;, + -0.322;-0.006;0.947;, + 0.656;0.144;0.74;, + 0.068;-0.998;-0.017;, + -0.145;0.98;-0.139;, + -0.762;0.647;0.03;, + -0.705;0.679;-0.203;, + -0.482;0.029;0.876;, + -0.326;-0.415;0.849;, + -0.604;0.753;0.26;, + -0.73;0.676;0.104;, + 0.015;-0.962;-0.273;, + -0.4;0.166;0.901;, + -0.159;0.178;0.971;, + 0.47;0.514;0.718;, + -0.001;0.992;-0.123;, + 0.202;0.328;0.923;, + -0.158;0.375;0.913;, + 0.012;0.392;0.92;, + 0.304;0.594;0.744;, + 0.418;0.906;0.073;, + -0.007;0.999;0.044;, + -0.016;0.63;0.776;, + -0.599;0.796;0.085;, + -0.721;0.542;0.431;, + -0.186;0.649;0.737;, + -0.097;0.991;0.093;, + -0.048;-0.21;0.976;, + -0.635;0.741;0.219;, + 0.625;0.738;0.255;, + 0.006;-0.985;0.173;, + 0.581;-0.141;0.802;, + 0.12;0.981;0.152;, + 0.637;0.765;0.094;, + 0.019;0.945;0.327;, + -0.709;-0.372;-0.6;, + -0.663;-0.095;-0.742;, + -0.286;-0.487;-0.825;, + -0.34;0.151;-0.928;, + 0.082;0.127;-0.988;, + 0.146;-0.161;-0.976;, + 0.003;-0.991;-0.137;, + -0.002;-0.995;-0.096;, + -0.64;-0.528;-0.559;, + -0.665;-0.088;-0.741;, + -0.09;-0.111;-0.99;, + -0.257;0.054;-0.965;, + -0.102;0.075;-0.992;, + 0.37;-0.029;-0.929;, + -0.197;-0.98;-0.013;, + -0.007;-0.986;0.165;, + -0.927;0.29;0.236;, + 0.348;-0.727;0.592;, + -0.061;-0.998;0.023;, + 0.942;0.152;0.299;, + -0.985;-0.011;0.175;, + -0.985;-0.161;-0.057;, + -0.247;-0.272;0.93;, + -0.442;-0.896;-0.04;, + 0.482;-0.798;0.361;, + 0.006;-1.0;0.008;, + 0.537;-0.728;0.427;, + -0.735;-0.672;0.09;, + -0.095;-0.805;0.586;, + 0.791;0.244;0.561;, + -0.761;0.225;0.609;, + -0.884;-0.325;0.335;, + -0.562;0.068;0.824;, + 0.929;0.051;0.366;, + 0.001;-0.994;-0.108;, + 0.017;-0.67;-0.742;, + -0.057;-0.985;-0.161;, + -0.922;-0.249;-0.296;, + -0.811;-0.559;-0.175;, + -0.45;-0.893;0.016;, + -0.097;-0.981;0.167;, + -0.724;0.616;-0.309;, + -0.303;0.933;-0.196;, + -0.064;0.993;-0.097;, + 0.007;0.996;-0.086;, + 0.125;-0.987;-0.103;, + -0.933;0.123;-0.339;, + -0.638;0.717;-0.28;, + -0.685;0.667;-0.295;, + -0.607;-0.772;-0.187;, + -0.753;-0.649;-0.108;, + -0.975;-0.121;-0.187;, + -0.567;0.742;-0.357;, + -0.968;0.113;-0.223;, + -0.856;0.212;-0.471;, + 0.007;-1.0;0.031;, + -0.297;0.896;-0.331;, + -0.05;0.993;-0.112;, + -0.227;0.885;-0.406;, + 0.029;0.829;-0.559;, + -0.372;0.872;-0.319;, + -0.412;0.879;-0.24;, + -0.22;0.965;-0.14;, + -0.254;0.902;-0.349;, + -0.335;0.876;-0.347;, + -0.351;0.885;-0.307;, + -0.188;0.977;-0.105;, + -0.065;0.993;-0.095;, + -0.132;0.894;-0.428;, + 0.0;0.905;-0.426;, + -0.658;0.657;-0.369;, + 0.195;0.948;0.251;, + -0.316;0.679;-0.662;, + 0.102;0.67;-0.735;, + -0.721;0.633;-0.281;, + -0.648;0.755;-0.096;, + -0.408;0.902;0.141;, + -0.259;-0.965;0.032;, + 0.004;-1.0;0.003;, + -0.017;-1.0;0.005;, + -0.178;-0.983;-0.037;, + -0.565;-0.825;0.02;, + -0.591;-0.489;-0.641;, + -0.581;-0.744;-0.331;, + -0.702;-0.707;-0.09;, + -0.648;-0.747;-0.148;, + -0.024;-0.855;-0.518;, + -0.043;-0.664;-0.747;, + -0.822;-0.258;-0.508;, + -0.472;-0.556;-0.684;, + 0.002;-0.79;-0.613;, + -0.226;-0.634;-0.74;, + -0.278;-0.659;-0.699;, + 0.279;-0.959;-0.043;, + 0.766;-0.604;-0.22;, + 0.937;-0.173;-0.305;, + 0.913;0.258;-0.315;, + 0.162;-0.981;-0.11;, + 0.568;-0.665;-0.485;, + 0.647;-0.392;-0.654;, + 0.629;0.175;-0.758;, + 0.592;0.502;-0.63;, + 0.045;-0.992;-0.115;, + 0.262;-0.77;-0.582;, + 0.322;-0.317;-0.892;, + 0.311;0.249;-0.917;, + 0.156;0.783;-0.602;, + 0.606;0.661;-0.442;, + 0.726;0.633;-0.269;, + -0.092;0.985;-0.145;, + 0.007;-0.999;-0.043;, + -0.026;-1.0;-0.015;, + 0.804;0.021;0.594;, + 0.903;0.225;0.366;, + -0.248;0.953;-0.177;, + 0.079;-0.996;0.035;, + 0.0;0.941;0.339;, + 0.781;0.617;0.099;, + -0.417;-0.895;0.156;, + 0.478;0.868;-0.131;, + 0.208;0.928;0.309;, + 0.357;-0.933;0.045;, + 0.652;-0.756;0.059;, + 0.859;0.134;0.494;, + 0.652;-0.664;0.367;, + -0.72;0.646;0.253;, + 0.344;0.932;-0.111;, + 0.692;0.694;-0.2;, + 0.641;-0.69;-0.335;, + 0.666;-0.221;-0.713;, + 0.803;0.479;-0.354;, + 0.668;0.722;-0.181;, + 0.85;-0.511;-0.127;, + 0.956;-0.211;-0.206;, + 0.955;0.159;-0.251;, + 0.797;0.544;-0.262;, + 0.149;-0.979;0.136;, + 0.703;-0.696;-0.145;, + 0.958;-0.183;-0.22;, + 0.945;0.229;-0.232;, + 0.389;0.899;-0.202;, + 0.118;0.99;-0.076;, + 0.108;0.97;-0.218;, + 0.107;0.988;-0.114;, + 0.031;0.998;-0.052;, + 0.006;0.983;-0.181;, + -0.095;-0.995;-0.024;, + -0.111;-0.933;-0.342;, + 0.496;-0.293;-0.817;, + 0.091;-0.992;0.082;, + 0.782;-0.435;0.446;, + -0.719;-0.233;0.655;, + -0.111;-0.92;0.375;, + 0.594;0.805;-0.002;, + -0.146;-0.983;0.113;, + 0.463;0.799;-0.383;, + -0.146;-0.986;0.084;, + -0.186;-0.918;-0.35;, + 0.574;-0.764;-0.295;, + -0.081;-0.936;0.344;, + 0.649;-0.743;0.164;, + 0.841;-0.243;0.484;, + 0.995;-0.036;-0.092;, + 0.24;-0.405;0.883;, + 0.315;-0.038;0.948;, + -0.611;0.098;0.785;, + -0.076;-0.996;-0.049;, + 0.107;0.95;-0.293;, + 0.853;0.521;0.004;, + 0.82;0.496;-0.285;, + 0.589;0.171;0.79;, + 0.386;-0.401;0.831;, + 0.578;0.782;0.231;, + 0.744;0.662;0.091;, + 0.172;-0.982;-0.085;, + 0.509;0.334;0.793;, + 0.125;0.198;0.972;, + -0.564;0.425;0.709;, + -0.01;0.968;-0.249;, + -0.157;0.262;0.952;, + 0.181;0.374;0.91;, + 0.021;0.328;0.944;, + -0.229;0.682;0.695;, + -0.328;0.94;0.095;, + 0.008;0.999;0.053;, + 0.022;0.649;0.76;, + 0.628;0.772;0.098;, + 0.691;0.601;0.402;, + 0.173;0.672;0.72;, + 0.098;0.991;0.092;, + 0.75;0.621;0.226;, + -0.452;0.835;0.315;, + -0.887;-0.25;0.388;, + -0.757;0.645;0.105;, + 0.654;-0.286;-0.701;, + 0.576;-0.07;-0.814;, + 0.341;-0.38;-0.86;, + 0.258;0.557;-0.79;, + -0.161;0.114;-0.98;, + -0.295;-0.401;-0.867;, + 0.003;-0.993;-0.122;, + 0.732;-0.68;-0.051;, + 0.935;-0.091;-0.343;, + -0.135;-0.619;-0.774;, + 0.387;0.669;-0.634;, + -0.02;0.67;-0.742;, + -0.823;-0.396;-0.406;, + 0.201;-0.979;-0.029;, + 0.952;0.056;0.3;, + -0.717;0.084;0.691;, + 0.079;-0.997;0.008;, + -0.954;-0.292;0.073;, + 0.653;-0.326;0.684;, + 0.925;0.076;0.372;, + 0.28;0.066;0.958;, + 0.357;-0.761;0.542;, + -0.737;-0.613;0.286;, + -0.01;-0.888;0.46;, + -0.657;-0.648;0.385;, + 0.735;-0.664;0.135;, + 0.033;-0.681;0.732;, + -0.717;0.214;0.663;, + 0.679;0.259;0.686;, + 0.89;-0.285;0.355;, + 0.626;0.065;0.777;, + -0.984;-0.178;-0.033;, + -0.02;-0.555;-0.831;, + 0.054;-0.987;-0.148;, + 0.892;-0.312;-0.328;, + 0.818;-0.537;-0.208;, + 0.423;-0.906;-0.023;, + 0.115;-0.982;0.153;, + 0.745;0.572;-0.344;, + 0.315;0.93;-0.19;, + 0.063;0.994;-0.094;, + -0.163;-0.975;-0.15;, + 0.916;0.136;-0.377;, + 0.628;0.724;-0.286;, + 0.702;0.652;-0.285;, + 0.591;-0.787;-0.177;, + 0.834;-0.536;-0.132;, + 0.974;-0.131;-0.187;, + 0.552;0.753;-0.358;, + 0.961;0.148;-0.235;, + 0.868;0.16;-0.471;, + 0.59;0.742;-0.319;, + 0.383;0.818;-0.43;, + 0.595;0.769;-0.236;, + 0.518;0.84;-0.162;, + 0.217;0.973;-0.076;, + 0.256;0.897;-0.359;, + 0.367;0.87;-0.33;, + 0.364;0.851;-0.378;, + 0.217;0.956;-0.196;, + 0.091;0.871;-0.483;, + 0.647;0.679;-0.347;, + 0.407;0.715;-0.569;, + 0.7;0.663;-0.267;, + 0.65;0.752;-0.11;, + 0.459;0.882;0.102;, + 0.269;-0.963;0.024;, + 0.05;-0.999;-0.005;, + 0.189;-0.98;-0.059;, + 0.577;-0.816;0.028;, + 0.459;-0.414;-0.786;, + 0.441;-0.836;-0.326;, + 0.635;-0.769;-0.072;, + 0.636;-0.76;-0.135;, + 0.821;-0.3;-0.486;, + 0.481;-0.543;-0.688;, + 0.257;-0.633;-0.73;, + 0.25;-0.801;-0.544;, + // Bubble + -0.741;0.578;-0.342;, + 0.043;0.797;-0.603;, + -0.717;0.647;-0.259;, + 0.0;0.0;0.0;, + -0.426;0.877;-0.221;, + -0.208;0.971;-0.117;, + -0.04;0.991;-0.126;, + 0.034;0.988;-0.149;, + -0.455;0.664;-0.593;, + 0.042;0.693;-0.72;, + 0.0;0.0;0.0;, + 0.0;0.0;0.0;, + 0.05;0.96;-0.277;, + 0.0;0.0;0.0;, + 0.0;0.0;0.0;, + 0.0;0.0;0.0;, + -0.594;0.696;-0.403;, + 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.0;0.0;, + -0.375;0.913;-0.159;, + -0.44;0.868;-0.231;, + 0.0;0.0;0.0;, + 0.738;0.573;-0.356;, + 0.718;0.657;-0.231;, + 0.409;0.897;-0.167;, + 0.176;0.977;-0.122;, + 0.333;0.684;-0.649;, + 0.504;0.757;-0.415;, + 0.378;0.914;-0.147;, + 0.43;0.878;-0.21;; + + 3000; + // Turret_base + 3;1,12,13;, + 3;2,13,14;, + 3;42,3,14;, + 3;4,38,44;, + 3;4,15,16;, + 3;5,16,17;, + 3;6,17,18;, + 3;7,18,19;, + 3;8,19,20;, + 3;9,20,21;, + 3;10,21,22;, + 3;11,22,12;, + 3;12,23,24;, + 3;37,14,13;, + 3;24,35,37;, + 3;14,37,32;, + 3;36,15,44;, + 3;39,25,36;, + 3;36,25,16;, + 3;16,25,26;, + 3;17,26,27;, + 3;18,27,28;, + 3;19,28,29;, + 3;20,29,30;, + 3;21,30,31;, + 3;22,31,23;, + 3;0,26,25;, + 3;40,35,43;, + 3;23,0,24;, + 3;0,43,35;, + 3;33,41,39;, + 3;0,25,39;, + 3;6,7,33;, + 3;33,36,44;, + 3;5,6,33;, + 3;41,40,43;, + 3;27,26,0;, + 3;40,41,33;, + 3;29,28,0;, + 3;34,37,35;, + 3;31,30,0;, + 3;33,7,8;, + 3;34,1,2;, + 3;34,42,32;, + 3;34,2,3;, + 3;9,10,34;, + 3;33,38,4;, + 3;34,10,11;, + 3;0,39,43;, + 3;0,35,24;, + 3;1,13,2;, + 3;2,14,3;, + 3;42,14,32;, + 3;4,44,15;, + 3;4,16,5;, + 3;5,17,6;, + 3;6,18,7;, + 3;7,19,8;, + 3;8,20,9;, + 3;9,21,10;, + 3;10,22,11;, + 3;11,12,1;, + 3;12,24,13;, + 3;37,13,24;, + 3;36,16,15;, + 3;16,26,17;, + 3;17,27,18;, + 3;18,28,19;, + 3;19,29,20;, + 3;20,30,21;, + 3;21,31,22;, + 3;22,23,12;, + 3;33,39,36;, + 3;33,44,38;, + 3;41,43,39;, + 3;27,0,28;, + 3;40,33,34;, + 3;29,0,30;, + 3;34,35,40;, + 3;31,0,23;, + 3;33,8,9;, + 3;34,32,37;, + 3;34,3,42;, + 3;9,34,33;, + 3;33,4,5;, + 3;34,11,1;, + // Gatling_base + 3;46,61,62;, + 3;45,63,64;, + 3;50,62,65;, + 3;58,66,63;, + 3;49,64,67;, + 3;55,52,48;, + 3;60,48,59;, + 3;54,67,68;, + 3;53,65,66;, + 3;56,51,47;, + 3;57,68,61;, + 3;53,57,46;, + 3;57,53,58;, + 3;54,57,45;, + 3;61,47,51;, + 3;63,48,52;, + 3;62,51,56;, + 3;66,59,48;, + 3;64,52,55;, + 3;67,55,60;, + 3;65,56,59;, + 3;68,60,47;, + 3;46,62,50;, + 3;45,64,49;, + 3;50,65,53;, + 3;58,63,45;, + 3;49,67,54;, + 3;55,48,60;, + 3;60,59,56;, + 3;54,68,57;, + 3;53,66,58;, + 3;56,47,60;, + 3;57,61,46;, + 3;53,46,50;, + 3;57,58,45;, + 3;54,45,49;, + 3;61,51,62;, + 3;63,52,64;, + 3;62,56,65;, + 3;66,48,63;, + 3;64,55,67;, + 3;67,60,68;, + 3;65,59,66;, + 3;68,47,61;, + // Gatling_base_2 + 3;69,70,74;, + 3;73,74,78;, + 3;77,78,82;, + 3;70,71,75;, + 3;74,75,79;, + 3;78,79,83;, + 3;71,72,76;, + 3;75,76,80;, + 3;79,80,84;, + 3;81,82,86;, + 3;85,86,90;, + 3;89,90,94;, + 3;82,83,87;, + 3;86,87,91;, + 3;90,91,95;, + 3;83,84,88;, + 3;87,88,92;, + 3;91,92,96;, + 3;93,94,98;, + 3;97,98,102;, + 3;101,102,106;, + 3;94,95,99;, + 3;98,99,103;, + 3;102,103,107;, + 3;95,96,100;, + 3;99,100,104;, + 3;103,104,108;, + 3;105,106,110;, + 3;109,110,114;, + 3;113,114,70;, + 3;106,107,111;, + 3;110,111,115;, + 3;114,115,71;, + 3;107,108,112;, + 3;111,112,116;, + 3;115,116,72;, + 3;72,116,117;, + 3;76,117,119;, + 3;80,119,88;, + 3;116,112,118;, + 3;117,118,120;, + 3;119,120,92;, + 3;112,108,104;, + 3;118,104,100;, + 3;120,100,96;, + 3;105,109,121;, + 3;101,121,123;, + 3;97,123,89;, + 3;109,113,122;, + 3;121,122,124;, + 3;123,124,85;, + 3;113,69,73;, + 3;122,73,77;, + 3;124,77,81;, + 3;69,74,73;, + 3;73,78,77;, + 3;77,82,81;, + 3;70,75,74;, + 3;74,79,78;, + 3;78,83,82;, + 3;71,76,75;, + 3;75,80,79;, + 3;79,84,83;, + 3;81,86,85;, + 3;85,90,89;, + 3;89,94,93;, + 3;82,87,86;, + 3;86,91,90;, + 3;90,95,94;, + 3;83,88,87;, + 3;87,92,91;, + 3;91,96,95;, + 3;93,98,97;, + 3;97,102,101;, + 3;101,106,105;, + 3;94,99,98;, + 3;98,103,102;, + 3;102,107,106;, + 3;95,100,99;, + 3;99,104,103;, + 3;103,108,107;, + 3;105,110,109;, + 3;109,114,113;, + 3;113,70,69;, + 3;106,111,110;, + 3;110,115,114;, + 3;114,71,70;, + 3;107,112,111;, + 3;111,116,115;, + 3;115,72,71;, + 3;72,117,76;, + 3;76,119,80;, + 3;80,88,84;, + 3;116,118,117;, + 3;117,120,119;, + 3;119,92,88;, + 3;112,104,118;, + 3;118,100,120;, + 3;120,96,92;, + 3;105,121,101;, + 3;101,123,97;, + 3;97,89,93;, + 3;109,122,121;, + 3;121,124,123;, + 3;123,85,89;, + 3;113,73,122;, + 3;122,77,124;, + 3;124,81,85;, + // Gatling_mid + 3;126,149,150;, + 3;125,151,152;, + 3;130,150,153;, + 3;138,154,151;, + 3;129,152,155;, + 3;153,145,146;, + 3;161,185,184;, + 3;163,187,186;, + 3;159,183,182;, + 3;141,127,131;, + 3;143,128,132;, + 3;160,184,183;, + 3;164,188,187;, + 3;142,131,136;, + 3;178,137,126;, + 3;175,126,130;, + 3;177,173,130;, + 3;167,179,178;, + 3;157,181,188;, + 3;171,177,180;, + 3;133,138,180;, + 3;168,160,159;, + 3;160,168,169;, + 3;137,156,149;, + 3;150,142,145;, + 3;152,144,147;, + 3;171,172,164;, + 3;154,146,143;, + 3;167,159,158;, + 3;149,141,142;, + 3;151,143,144;, + 3;162,170,171;, + 3;168,178,175;, + 3;172,180,176;, + 3;166,174,179;, + 3;158,182,181;, + 3;179,134,137;, + 3;146,139,128;, + 3;144,132,135;, + 3;170,173,177;, + 3;147,135,140;, + 3;145,136,139;, + 3;148,140,127;, + 3;162,186,185;, + 3;125,129,174;, + 3;162,161,169;, + 3;138,125,176;, + 3;174,129,134;, + 3;156,148,141;, + 3;172,165,157;, + 3;169,175,173;, + 3;165,176,174;, + 3;155,147,148;, + 3;134,155,156;, + 3;133,153,154;, + 3;165,166,158;, + 3;131,127,185;, + 3;131,186,187;, + 3;127,140,184;, + 3;140,135,183;, + 3;135,132,182;, + 3;182,132,128;, + 3;181,128,139;, + 3;188,139,136;, + 3;126,150,130;, + 3;125,152,129;, + 3;130,153,133;, + 3;138,151,125;, + 3;129,155,134;, + 3;153,146,154;, + 3;161,184,160;, + 3;163,186,162;, + 3;159,182,158;, + 3;141,131,142;, + 3;143,132,144;, + 3;160,183,159;, + 3;164,187,163;, + 3;142,136,145;, + 3;178,126,175;, + 3;175,130,173;, + 3;177,130,133;, + 3;167,178,168;, + 3;157,188,164;, + 3;171,180,172;, + 3;133,180,177;, + 3;168,159,167;, + 3;160,169,161;, + 3;137,149,126;, + 3;150,145,153;, + 3;152,147,155;, + 3;171,164,163;, + 3;154,143,151;, + 3;167,158,166;, + 3;149,142,150;, + 3;151,144,152;, + 3;162,171,163;, + 3;168,175,169;, + 3;172,176,165;, + 3;166,179,167;, + 3;158,181,157;, + 3;179,137,178;, + 3;146,128,143;, + 3;144,135,147;, + 3;170,177,171;, + 3;147,140,148;, + 3;145,139,146;, + 3;148,127,141;, + 3;162,185,161;, + 3;125,174,176;, + 3;162,169,170;, + 3;138,176,180;, + 3;174,134,179;, + 3;156,141,149;, + 3;172,157,164;, + 3;169,173,170;, + 3;165,174,166;, + 3;155,148,156;, + 3;134,156,137;, + 3;133,154,138;, + 3;165,158,157;, + 3;131,185,186;, + 3;131,187,136;, + 3;127,184,185;, + 3;140,183,184;, + 3;135,182,183;, + 3;182,128,181;, + 3;181,139,188;, + 3;188,136,187;, + // Gatling_fin_1 + 3;190,213,214;, + 3;189,215,216;, + 3;194,214,217;, + 3;202,218,215;, + 3;193,216,219;, + 3;217,209,210;, + 3;200,251,252;, + 3;195,191,249;, + 3;191,204,248;, + 3;204,199,247;, + 3;199,196,246;, + 3;224,248,247;, + 3;228,252,251;, + 3;212,204,191;, + 3;246,196,192;, + 3;235,236,228;, + 3;218,210,207;, + 3;231,243,242;, + 3;221,245,252;, + 3;235,241,244;, + 3;245,192,203;, + 3;211,199,204;, + 3;227,251,250;, + 3;208,196,199;, + 3;223,247,246;, + 3;251,200,195;, + 3;222,246,245;, + 3;209,200,203;, + 3;224,232,233;, + 3;213,205,206;, + 3;215,207,208;, + 3;232,242,239;, + 3;234,237,241;, + 3;201,220,213;, + 3;226,234,235;, + 3;232,224,223;, + 3;214,206,209;, + 3;216,208,211;, + 3;226,225,233;, + 3;233,239,237;, + 3;236,229,221;, + 3;229,230,222;, + 3;236,244,240;, + 3;230,238,243;, + 3;197,217,218;, + 3;229,240,238;, + 3;210,203,192;, + 3;226,250,249;, + 3;220,212,205;, + 3;205,191,195;, + 3;225,249,248;, + 3;231,223,222;, + 3;219,211,212;, + 3;198,219,220;, + 3;207,192,196;, + 3;206,195,200;, + 3;189,193,238;, + 3;202,189,240;, + 3;238,193,198;, + 3;243,198,201;, + 3;242,201,190;, + 3;239,190,194;, + 3;241,237,194;, + 3;197,202,244;, + 3;190,214,194;, + 3;189,216,193;, + 3;194,217,197;, + 3;202,215,189;, + 3;193,219,198;, + 3;217,210,218;, + 3;200,252,203;, + 3;195,249,250;, + 3;191,248,249;, + 3;204,247,248;, + 3;199,246,247;, + 3;224,247,223;, + 3;228,251,227;, + 3;212,191,205;, + 3;246,192,245;, + 3;235,228,227;, + 3;218,207,215;, + 3;231,242,232;, + 3;221,252,228;, + 3;235,244,236;, + 3;245,203,252;, + 3;211,204,212;, + 3;227,250,226;, + 3;208,199,211;, + 3;223,246,222;, + 3;251,195,250;, + 3;222,245,221;, + 3;209,203,210;, + 3;224,233,225;, + 3;213,206,214;, + 3;215,208,216;, + 3;232,239,233;, + 3;234,241,235;, + 3;201,213,190;, + 3;226,235,227;, + 3;232,223,231;, + 3;214,209,217;, + 3;216,211,219;, + 3;226,233,234;, + 3;233,237,234;, + 3;236,221,228;, + 3;229,222,221;, + 3;236,240,229;, + 3;230,243,231;, + 3;197,218,202;, + 3;229,238,230;, + 3;210,192,207;, + 3;226,249,225;, + 3;220,205,213;, + 3;205,195,206;, + 3;225,248,224;, + 3;231,222,230;, + 3;219,212,220;, + 3;198,220,201;, + 3;207,196,208;, + 3;206,200,209;, + 3;189,238,240;, + 3;202,240,244;, + 3;238,198,243;, + 3;243,201,242;, + 3;242,190,239;, + 3;239,194,237;, + 3;241,194,197;, + 3;197,244,241;, + // Gatling_fin_2 + 3;254,277,278;, + 3;253,279,280;, + 3;258,278,281;, + 3;266,282,279;, + 3;257,280,283;, + 3;281,273,274;, + 3;276,268,255;, + 3;259,255,313;, + 3;286,310,309;, + 3;268,263,311;, + 3;263,260,310;, + 3;288,312,311;, + 3;292,316,315;, + 3;310,260,256;, + 3;309,256,267;, + 3;316,267,264;, + 3;315,264,259;, + 3;295,307,306;, + 3;285,309,316;, + 3;299,305,308;, + 3;297,303,301;, + 3;262,283,284;, + 3;261,281,282;, + 3;280,272,275;, + 3;255,268,312;, + 3;289,313,312;, + 3;291,315,314;, + 3;265,284,277;, + 3;295,287,286;, + 3;277,269,270;, + 3;279,271,272;, + 3;290,298,299;, + 3;253,257,302;, + 3;307,262,265;, + 3;306,265,254;, + 3;300,308,304;, + 3;296,288,287;, + 3;288,296,297;, + 3;293,294,286;, + 3;299,300,292;, + 3;302,257,262;, + 3;282,274,271;, + 3;296,306,303;, + 3;274,267,256;, + 3;303,254,258;, + 3;272,260,263;, + 3;305,301,258;, + 3;261,266,308;, + 3;284,276,269;, + 3;278,270,273;, + 3;275,263,268;, + 3;290,289,297;, + 3;269,255,259;, + 3;273,264,267;, + 3;290,314,313;, + 3;287,311,310;, + 3;293,304,302;, + 3;271,256,260;, + 3;266,253,304;, + 3;294,302,307;, + 3;270,259,264;, + 3;300,293,285;, + 3;283,275,276;, + 3;298,301,305;, + 3;254,278,258;, + 3;253,280,257;, + 3;258,281,261;, + 3;266,279,253;, + 3;257,283,262;, + 3;281,274,282;, + 3;276,255,269;, + 3;259,313,314;, + 3;286,309,285;, + 3;268,311,312;, + 3;263,310,311;, + 3;288,311,287;, + 3;292,315,291;, + 3;310,256,309;, + 3;309,267,316;, + 3;316,264,315;, + 3;315,259,314;, + 3;295,306,296;, + 3;285,316,292;, + 3;299,308,300;, + 3;297,301,298;, + 3;262,284,265;, + 3;261,282,266;, + 3;280,275,283;, + 3;255,312,313;, + 3;289,312,288;, + 3;291,314,290;, + 3;265,277,254;, + 3;295,286,294;, + 3;277,270,278;, + 3;279,272,280;, + 3;290,299,291;, + 3;253,302,304;, + 3;307,265,306;, + 3;306,254,303;, + 3;300,304,293;, + 3;296,287,295;, + 3;288,297,289;, + 3;293,286,285;, + 3;299,292,291;, + 3;302,262,307;, + 3;282,271,279;, + 3;296,303,297;, + 3;274,256,271;, + 3;303,258,301;, + 3;272,263,275;, + 3;305,258,261;, + 3;261,308,305;, + 3;284,269,277;, + 3;278,273,281;, + 3;275,268,276;, + 3;290,297,298;, + 3;269,259,270;, + 3;273,267,274;, + 3;290,313,289;, + 3;287,310,286;, + 3;293,302,294;, + 3;271,260,272;, + 3;266,304,308;, + 3;294,307,295;, + 3;270,264,273;, + 3;300,285,292;, + 3;283,276,284;, + 3;298,305,299;, + // Gatling_fin_3 + 3;319,342,343;, + 3;318,344,345;, + 3;323,343,346;, + 3;331,347,344;, + 3;322,345,348;, + 3;346,338,339;, + 3;324,320,378;, + 3;333,328,376;, + 3;328,325,375;, + 3;375,325,321;, + 3;374,321,332;, + 3;353,377,376;, + 3;357,381,380;, + 3;381,332,329;, + 3;380,329,324;, + 3;351,375,374;, + 3;359,367,372;, + 3;360,372,371;, + 3;350,374,381;, + 3;364,370,373;, + 3;323,326,370;, + 3;331,318,369;, + 3;318,322,367;, + 3;367,322,327;, + 3;372,327,330;, + 3;358,369,367;, + 3;371,330,319;, + 3;355,363,364;, + 3;368,319,323;, + 3;342,334,335;, + 3;344,336,337;, + 3;334,320,324;, + 3;326,331,373;, + 3;355,354,362;, + 3;341,333,320;, + 3;336,321,325;, + 3;365,373,369;, + 3;362,368,366;, + 3;335,324,329;, + 3;355,379,378;, + 3;338,329,332;, + 3;361,371,368;, + 3;353,361,362;, + 3;327,348,349;, + 3;343,335,338;, + 3;365,358,350;, + 3;326,346,347;, + 3;345,337,340;, + 3;349,341,334;, + 3;360,352,351;, + 3;339,332,321;, + 3;340,328,333;, + 3;337,325,328;, + 3;354,378,377;, + 3;320,333,377;, + 3;347,339,336;, + 3;356,380,379;, + 3;352,376,375;, + 3;358,359,351;, + 3;363,366,370;, + 3;330,349,342;, + 3;364,365,357;, + 3;361,353,352;, + 3;348,340,341;, + 3;319,343,323;, + 3;318,345,322;, + 3;323,346,326;, + 3;331,344,318;, + 3;322,348,327;, + 3;346,339,347;, + 3;324,378,379;, + 3;333,376,377;, + 3;328,375,376;, + 3;375,321,374;, + 3;374,332,381;, + 3;353,376,352;, + 3;357,380,356;, + 3;381,329,380;, + 3;380,324,379;, + 3;351,374,350;, + 3;359,372,360;, + 3;360,371,361;, + 3;350,381,357;, + 3;364,373,365;, + 3;323,370,366;, + 3;331,369,373;, + 3;318,367,369;, + 3;367,327,372;, + 3;372,330,371;, + 3;358,367,359;, + 3;371,319,368;, + 3;355,364,356;, + 3;368,323,366;, + 3;342,335,343;, + 3;344,337,345;, + 3;334,324,335;, + 3;326,373,370;, + 3;355,362,363;, + 3;341,320,334;, + 3;336,325,337;, + 3;365,369,358;, + 3;362,366,363;, + 3;335,329,338;, + 3;355,378,354;, + 3;338,332,339;, + 3;361,368,362;, + 3;353,362,354;, + 3;327,349,330;, + 3;343,338,346;, + 3;365,350,357;, + 3;326,347,331;, + 3;345,340,348;, + 3;349,334,342;, + 3;360,351,359;, + 3;339,321,336;, + 3;340,333,341;, + 3;337,328,340;, + 3;354,377,353;, + 3;320,377,378;, + 3;347,336,344;, + 3;356,379,355;, + 3;352,375,351;, + 3;358,351,350;, + 3;363,370,364;, + 3;330,342,319;, + 3;364,357,356;, + 3;361,352,360;, + 3;348,341,349;, + // Barrel_11 + 3;385,387,391;, + 3;387,388,389;, + 3;427,426,433;, + 3;385,391,396;, + 3;391,389,392;, + 3;419,403,406;, + 3;385,396,400;, + 3;396,392,393;, + 3;432,431,430;, + 3;385,400,404;, + 3;400,393,395;, + 3;427,432,430;, + 3;385,404,407;, + 3;404,395,398;, + 3;385,415,387;, + 3;385,407,412;, + 3;407,398,399;, + 3;415,401,388;, + 3;385,412,415;, + 3;412,399,401;, + 3;427,429,428;, + 3;403,427,428;, + 3;406,428,429;, + 3;408,429,430;, + 3;409,430,431;, + 3;411,431,432;, + 3;413,432,433;, + 3;416,433,426;, + 3;417,426,427;, + 3;420,406,408;, + 3;421,408,409;, + 3;422,409,411;, + 3;423,411,413;, + 3;424,413,416;, + 3;425,416,417;, + 3;418,417,403;, + 3;388,390,394;, + 3;389,394,397;, + 3;392,397,402;, + 3;393,402,405;, + 3;395,405,410;, + 3;398,410,414;, + 3;401,386,390;, + 3;399,414,386;, + 3;402,397,421;, + 3;397,394,420;, + 3;394,390,419;, + 3;418,419,390;, + 3;425,418,386;, + 3;424,425,414;, + 3;423,424,410;, + 3;422,423,405;, + 3;387,389,391;, + 3;427,433,432;, + 3;391,392,396;, + 3;419,406,420;, + 3;396,393,400;, + 3;400,395,404;, + 3;427,430,429;, + 3;404,398,407;, + 3;407,399,412;, + 3;415,388,387;, + 3;412,401,415;, + 3;403,428,406;, + 3;406,429,408;, + 3;408,430,409;, + 3;409,431,411;, + 3;411,432,413;, + 3;413,433,416;, + 3;416,426,417;, + 3;417,427,403;, + 3;420,408,421;, + 3;421,409,422;, + 3;422,411,423;, + 3;423,413,424;, + 3;424,416,425;, + 3;425,417,418;, + 3;418,403,419;, + 3;388,394,389;, + 3;389,397,392;, + 3;392,402,393;, + 3;393,405,395;, + 3;395,410,398;, + 3;398,414,399;, + 3;401,390,388;, + 3;399,386,401;, + 3;402,421,422;, + 3;397,420,421;, + 3;394,419,420;, + 3;418,390,386;, + 3;425,386,414;, + 3;424,414,410;, + 3;423,410,405;, + 3;422,405,402;, + // Barrel_1 + 3;434,436,440;, + 3;436,437,438;, + 3;476,475,482;, + 3;434,440,445;, + 3;440,438,441;, + 3;468,452,455;, + 3;434,445,449;, + 3;445,441,442;, + 3;481,480,479;, + 3;434,449,453;, + 3;449,442,444;, + 3;476,481,479;, + 3;434,453,456;, + 3;453,444,447;, + 3;434,464,436;, + 3;434,456,461;, + 3;456,447,448;, + 3;464,450,437;, + 3;434,461,464;, + 3;461,448,450;, + 3;476,478,477;, + 3;452,476,477;, + 3;455,477,478;, + 3;457,478,479;, + 3;458,479,480;, + 3;460,480,481;, + 3;462,481,482;, + 3;465,482,475;, + 3;466,475,476;, + 3;469,455,457;, + 3;470,457,458;, + 3;471,458,460;, + 3;472,460,462;, + 3;473,462,465;, + 3;474,465,466;, + 3;467,466,452;, + 3;437,439,443;, + 3;438,443,446;, + 3;441,446,451;, + 3;442,451,454;, + 3;444,454,459;, + 3;447,459,463;, + 3;450,435,439;, + 3;448,463,435;, + 3;451,446,470;, + 3;446,443,469;, + 3;443,439,468;, + 3;467,468,439;, + 3;474,467,435;, + 3;473,474,463;, + 3;472,473,459;, + 3;471,472,454;, + 3;436,438,440;, + 3;476,482,481;, + 3;440,441,445;, + 3;468,455,469;, + 3;445,442,449;, + 3;449,444,453;, + 3;476,479,478;, + 3;453,447,456;, + 3;456,448,461;, + 3;464,437,436;, + 3;461,450,464;, + 3;452,477,455;, + 3;455,478,457;, + 3;457,479,458;, + 3;458,480,460;, + 3;460,481,462;, + 3;462,482,465;, + 3;465,475,466;, + 3;466,476,452;, + 3;469,457,470;, + 3;470,458,471;, + 3;471,460,472;, + 3;472,462,473;, + 3;473,465,474;, + 3;474,466,467;, + 3;467,452,468;, + 3;437,443,438;, + 3;438,446,441;, + 3;441,451,442;, + 3;442,454,444;, + 3;444,459,447;, + 3;447,463,448;, + 3;450,439,437;, + 3;448,435,450;, + 3;451,470,471;, + 3;446,469,470;, + 3;443,468,469;, + 3;467,439,435;, + 3;474,435,463;, + 3;473,463,459;, + 3;472,459,454;, + 3;471,454,451;, + // Barrel_13 + 3;483,485,489;, + 3;485,486,487;, + 3;525,524,531;, + 3;483,489,494;, + 3;489,487,490;, + 3;517,501,504;, + 3;483,494,498;, + 3;494,490,491;, + 3;530,529,528;, + 3;483,498,502;, + 3;498,491,493;, + 3;525,530,528;, + 3;483,502,505;, + 3;502,493,496;, + 3;483,513,485;, + 3;483,505,510;, + 3;505,496,497;, + 3;513,499,486;, + 3;483,510,513;, + 3;510,497,499;, + 3;525,527,526;, + 3;501,525,526;, + 3;504,526,527;, + 3;506,527,528;, + 3;507,528,529;, + 3;509,529,530;, + 3;511,530,531;, + 3;514,531,524;, + 3;515,524,525;, + 3;518,504,506;, + 3;519,506,507;, + 3;520,507,509;, + 3;521,509,511;, + 3;522,511,514;, + 3;523,514,515;, + 3;516,515,501;, + 3;486,488,492;, + 3;487,492,495;, + 3;490,495,500;, + 3;491,500,503;, + 3;493,503,508;, + 3;496,508,512;, + 3;499,484,488;, + 3;497,512,484;, + 3;500,495,519;, + 3;495,492,518;, + 3;492,488,517;, + 3;516,517,488;, + 3;523,516,484;, + 3;522,523,512;, + 3;521,522,508;, + 3;520,521,503;, + 3;485,487,489;, + 3;525,531,530;, + 3;489,490,494;, + 3;517,504,518;, + 3;494,491,498;, + 3;498,493,502;, + 3;525,528,527;, + 3;502,496,505;, + 3;505,497,510;, + 3;513,486,485;, + 3;510,499,513;, + 3;501,526,504;, + 3;504,527,506;, + 3;506,528,507;, + 3;507,529,509;, + 3;509,530,511;, + 3;511,531,514;, + 3;514,524,515;, + 3;515,525,501;, + 3;518,506,519;, + 3;519,507,520;, + 3;520,509,521;, + 3;521,511,522;, + 3;522,514,523;, + 3;523,515,516;, + 3;516,501,517;, + 3;486,492,487;, + 3;487,495,490;, + 3;490,500,491;, + 3;491,503,493;, + 3;493,508,496;, + 3;496,512,497;, + 3;499,488,486;, + 3;497,484,499;, + 3;500,519,520;, + 3;495,518,519;, + 3;492,517,518;, + 3;516,488,484;, + 3;523,484,512;, + 3;522,512,508;, + 3;521,508,503;, + 3;520,503,500;, + // Barrel_14 + 3;532,534,538;, + 3;534,535,536;, + 3;574,573,580;, + 3;532,538,543;, + 3;538,536,539;, + 3;566,550,553;, + 3;532,543,547;, + 3;543,539,540;, + 3;579,578,577;, + 3;532,547,551;, + 3;547,540,542;, + 3;574,579,577;, + 3;532,551,554;, + 3;551,542,545;, + 3;532,562,534;, + 3;532,554,559;, + 3;554,545,546;, + 3;562,548,535;, + 3;532,559,562;, + 3;559,546,548;, + 3;574,576,575;, + 3;550,574,575;, + 3;553,575,576;, + 3;555,576,577;, + 3;556,577,578;, + 3;558,578,579;, + 3;560,579,580;, + 3;563,580,573;, + 3;564,573,574;, + 3;567,553,555;, + 3;568,555,556;, + 3;569,556,558;, + 3;570,558,560;, + 3;571,560,563;, + 3;572,563,564;, + 3;565,564,550;, + 3;535,537,541;, + 3;536,541,544;, + 3;539,544,549;, + 3;540,549,552;, + 3;542,552,557;, + 3;545,557,561;, + 3;548,533,537;, + 3;546,561,533;, + 3;549,544,568;, + 3;544,541,567;, + 3;541,537,566;, + 3;565,566,537;, + 3;572,565,533;, + 3;571,572,561;, + 3;570,571,557;, + 3;569,570,552;, + 3;534,536,538;, + 3;574,580,579;, + 3;538,539,543;, + 3;566,553,567;, + 3;543,540,547;, + 3;547,542,551;, + 3;574,577,576;, + 3;551,545,554;, + 3;554,546,559;, + 3;562,535,534;, + 3;559,548,562;, + 3;550,575,553;, + 3;553,576,555;, + 3;555,577,556;, + 3;556,578,558;, + 3;558,579,560;, + 3;560,580,563;, + 3;563,573,564;, + 3;564,574,550;, + 3;567,555,568;, + 3;568,556,569;, + 3;569,558,570;, + 3;570,560,571;, + 3;571,563,572;, + 3;572,564,565;, + 3;565,550,566;, + 3;535,541,536;, + 3;536,544,539;, + 3;539,549,540;, + 3;540,552,542;, + 3;542,557,545;, + 3;545,561,546;, + 3;548,537,535;, + 3;546,533,548;, + 3;549,568,569;, + 3;544,567,568;, + 3;541,566,567;, + 3;565,537,533;, + 3;572,533,561;, + 3;571,561,557;, + 3;570,557,552;, + 3;569,552,549;, + // Barrel_12 + 3;581,583,587;, + 3;583,584,585;, + 3;623,622,629;, + 3;581,587,592;, + 3;587,585,588;, + 3;615,599,602;, + 3;581,592,596;, + 3;592,588,589;, + 3;628,627,626;, + 3;581,596,600;, + 3;596,589,591;, + 3;623,628,626;, + 3;581,600,603;, + 3;600,591,594;, + 3;581,611,583;, + 3;581,603,608;, + 3;603,594,595;, + 3;611,597,584;, + 3;581,608,611;, + 3;608,595,597;, + 3;623,625,624;, + 3;599,623,624;, + 3;602,624,625;, + 3;604,625,626;, + 3;605,626,627;, + 3;607,627,628;, + 3;609,628,629;, + 3;612,629,622;, + 3;613,622,623;, + 3;616,602,604;, + 3;617,604,605;, + 3;618,605,607;, + 3;619,607,609;, + 3;620,609,612;, + 3;621,612,613;, + 3;614,613,599;, + 3;584,586,590;, + 3;585,590,593;, + 3;588,593,598;, + 3;589,598,601;, + 3;591,601,606;, + 3;594,606,610;, + 3;597,582,586;, + 3;595,610,582;, + 3;598,593,617;, + 3;593,590,616;, + 3;590,586,615;, + 3;614,615,586;, + 3;621,614,582;, + 3;620,621,610;, + 3;619,620,606;, + 3;618,619,601;, + 3;583,585,587;, + 3;623,629,628;, + 3;587,588,592;, + 3;615,602,616;, + 3;592,589,596;, + 3;596,591,600;, + 3;623,626,625;, + 3;600,594,603;, + 3;603,595,608;, + 3;611,584,583;, + 3;608,597,611;, + 3;599,624,602;, + 3;602,625,604;, + 3;604,626,605;, + 3;605,627,607;, + 3;607,628,609;, + 3;609,629,612;, + 3;612,622,613;, + 3;613,623,599;, + 3;616,604,617;, + 3;617,605,618;, + 3;618,607,619;, + 3;619,609,620;, + 3;620,612,621;, + 3;621,613,614;, + 3;614,599,615;, + 3;584,590,585;, + 3;585,593,588;, + 3;588,598,589;, + 3;589,601,591;, + 3;591,606,594;, + 3;594,610,595;, + 3;597,586,584;, + 3;595,582,597;, + 3;598,617,618;, + 3;593,616,617;, + 3;590,615,616;, + 3;614,586,582;, + 3;621,582,610;, + 3;620,610,606;, + 3;619,606,601;, + 3;618,601,598;, + // Barrel_16 + 3;630,632,636;, + 3;632,633,634;, + 3;672,671,678;, + 3;630,636,641;, + 3;636,634,637;, + 3;664,648,651;, + 3;630,641,645;, + 3;641,637,638;, + 3;677,676,675;, + 3;630,645,649;, + 3;645,638,640;, + 3;672,677,675;, + 3;630,649,652;, + 3;649,640,643;, + 3;630,660,632;, + 3;630,652,657;, + 3;652,643,644;, + 3;660,646,633;, + 3;630,657,660;, + 3;657,644,646;, + 3;672,674,673;, + 3;648,672,673;, + 3;651,673,674;, + 3;653,674,675;, + 3;654,675,676;, + 3;656,676,677;, + 3;658,677,678;, + 3;661,678,671;, + 3;662,671,672;, + 3;665,651,653;, + 3;666,653,654;, + 3;667,654,656;, + 3;668,656,658;, + 3;669,658,661;, + 3;670,661,662;, + 3;663,662,648;, + 3;633,635,639;, + 3;634,639,642;, + 3;637,642,647;, + 3;638,647,650;, + 3;640,650,655;, + 3;643,655,659;, + 3;646,631,635;, + 3;644,659,631;, + 3;647,642,666;, + 3;642,639,665;, + 3;639,635,664;, + 3;663,664,635;, + 3;670,663,631;, + 3;669,670,659;, + 3;668,669,655;, + 3;667,668,650;, + 3;632,634,636;, + 3;672,678,677;, + 3;636,637,641;, + 3;664,651,665;, + 3;641,638,645;, + 3;645,640,649;, + 3;672,675,674;, + 3;649,643,652;, + 3;652,644,657;, + 3;660,633,632;, + 3;657,646,660;, + 3;648,673,651;, + 3;651,674,653;, + 3;653,675,654;, + 3;654,676,656;, + 3;656,677,658;, + 3;658,678,661;, + 3;661,671,662;, + 3;662,672,648;, + 3;665,653,666;, + 3;666,654,667;, + 3;667,656,668;, + 3;668,658,669;, + 3;669,661,670;, + 3;670,662,663;, + 3;663,648,664;, + 3;633,639,634;, + 3;634,642,637;, + 3;637,647,638;, + 3;638,650,640;, + 3;640,655,643;, + 3;643,659,644;, + 3;646,635,633;, + 3;644,631,646;, + 3;647,666,667;, + 3;642,665,666;, + 3;639,664,665;, + 3;663,635,631;, + 3;670,631,659;, + 3;669,659,655;, + 3;668,655,650;, + 3;667,650,647;, + // Barrel_17 + 3;679,681,685;, + 3;681,682,683;, + 3;721,720,727;, + 3;679,685,690;, + 3;685,683,686;, + 3;713,697,700;, + 3;679,690,694;, + 3;690,686,687;, + 3;726,725,724;, + 3;679,694,698;, + 3;694,687,689;, + 3;721,726,724;, + 3;679,698,701;, + 3;698,689,692;, + 3;679,709,681;, + 3;679,701,706;, + 3;701,692,693;, + 3;709,695,682;, + 3;679,706,709;, + 3;706,693,695;, + 3;721,723,722;, + 3;697,721,722;, + 3;700,722,723;, + 3;702,723,724;, + 3;703,724,725;, + 3;705,725,726;, + 3;707,726,727;, + 3;710,727,720;, + 3;711,720,721;, + 3;714,700,702;, + 3;715,702,703;, + 3;716,703,705;, + 3;717,705,707;, + 3;718,707,710;, + 3;719,710,711;, + 3;712,711,697;, + 3;682,684,688;, + 3;683,688,691;, + 3;686,691,696;, + 3;687,696,699;, + 3;689,699,704;, + 3;692,704,708;, + 3;695,680,684;, + 3;693,708,680;, + 3;696,691,715;, + 3;691,688,714;, + 3;688,684,713;, + 3;712,713,684;, + 3;719,712,680;, + 3;718,719,708;, + 3;717,718,704;, + 3;716,717,699;, + 3;681,683,685;, + 3;721,727,726;, + 3;685,686,690;, + 3;713,700,714;, + 3;690,687,694;, + 3;694,689,698;, + 3;721,724,723;, + 3;698,692,701;, + 3;701,693,706;, + 3;709,682,681;, + 3;706,695,709;, + 3;697,722,700;, + 3;700,723,702;, + 3;702,724,703;, + 3;703,725,705;, + 3;705,726,707;, + 3;707,727,710;, + 3;710,720,711;, + 3;711,721,697;, + 3;714,702,715;, + 3;715,703,716;, + 3;716,705,717;, + 3;717,707,718;, + 3;718,710,719;, + 3;719,711,712;, + 3;712,697,713;, + 3;682,688,683;, + 3;683,691,686;, + 3;686,696,687;, + 3;687,699,689;, + 3;689,704,692;, + 3;692,708,693;, + 3;695,684,682;, + 3;693,680,695;, + 3;696,715,716;, + 3;691,714,715;, + 3;688,713,714;, + 3;712,684,680;, + 3;719,680,708;, + 3;718,708,704;, + 3;717,704,699;, + 3;716,699,696;, + // Barrel_15 + 3;728,730,734;, + 3;730,731,732;, + 3;770,769,776;, + 3;728,734,739;, + 3;734,732,735;, + 3;762,746,749;, + 3;728,739,743;, + 3;739,735,736;, + 3;775,774,773;, + 3;728,743,747;, + 3;743,736,738;, + 3;770,775,773;, + 3;728,747,750;, + 3;747,738,741;, + 3;728,758,730;, + 3;728,750,755;, + 3;750,741,742;, + 3;758,744,731;, + 3;728,755,758;, + 3;755,742,744;, + 3;770,772,771;, + 3;746,770,771;, + 3;749,771,772;, + 3;751,772,773;, + 3;752,773,774;, + 3;754,774,775;, + 3;756,775,776;, + 3;759,776,769;, + 3;760,769,770;, + 3;763,749,751;, + 3;764,751,752;, + 3;765,752,754;, + 3;766,754,756;, + 3;767,756,759;, + 3;768,759,760;, + 3;761,760,746;, + 3;731,733,737;, + 3;732,737,740;, + 3;735,740,745;, + 3;736,745,748;, + 3;738,748,753;, + 3;741,753,757;, + 3;744,729,733;, + 3;742,757,729;, + 3;745,740,764;, + 3;740,737,763;, + 3;737,733,762;, + 3;761,762,733;, + 3;768,761,729;, + 3;767,768,757;, + 3;766,767,753;, + 3;765,766,748;, + 3;730,732,734;, + 3;770,776,775;, + 3;734,735,739;, + 3;762,749,763;, + 3;739,736,743;, + 3;743,738,747;, + 3;770,773,772;, + 3;747,741,750;, + 3;750,742,755;, + 3;758,731,730;, + 3;755,744,758;, + 3;746,771,749;, + 3;749,772,751;, + 3;751,773,752;, + 3;752,774,754;, + 3;754,775,756;, + 3;756,776,759;, + 3;759,769,760;, + 3;760,770,746;, + 3;763,751,764;, + 3;764,752,765;, + 3;765,754,766;, + 3;766,756,767;, + 3;767,759,768;, + 3;768,760,761;, + 3;761,746,762;, + 3;731,737,732;, + 3;732,740,735;, + 3;735,745,736;, + 3;736,748,738;, + 3;738,753,741;, + 3;741,757,742;, + 3;744,733,731;, + 3;742,729,744;, + 3;745,764,765;, + 3;740,763,764;, + 3;737,762,763;, + 3;761,733,729;, + 3;768,729,757;, + 3;767,757,753;, + 3;766,753,748;, + 3;765,748,745;, + // Side_guns + 3;817,801,803;, + 3;777,809,810;, + 3;782,811,812;, + 3;818,803,805;, + 3;781,810,813;, + 3;819,805,808;, + 3;820,808,802;, + 3;786,813,814;, + 3;785,812,815;, + 3;821,802,804;, + 3;789,814,816;, + 3;822,804,806;, + 3;823,806,807;, + 3;778,816,811;, + 3;790,815,809;, + 3;824,807,801;, + 3;801,807,803;, + 3;807,806,804;, + 3;803,807,804;, + 3;804,802,808;, + 3;808,805,803;, + 3;779,793,795;, + 3;783,795,797;, + 3;787,797,800;, + 3;792,800,794;, + 3;780,794,796;, + 3;784,796,798;, + 3;788,798,799;, + 3;791,799,793;, + 3;793,817,818;, + 3;795,818,819;, + 3;797,819,820;, + 3;800,820,821;, + 3;794,821,822;, + 3;796,822,823;, + 3;798,823,824;, + 3;799,824,817;, + 3;809,780,784;, + 3;811,783,787;, + 3;810,784,788;, + 3;813,788,791;, + 3;812,787,792;, + 3;814,791,779;, + 3;816,779,783;, + 3;815,792,780;, + 3;817,803,818;, + 3;777,810,781;, + 3;782,812,785;, + 3;818,805,819;, + 3;781,813,786;, + 3;819,808,820;, + 3;820,802,821;, + 3;786,814,789;, + 3;785,815,790;, + 3;821,804,822;, + 3;789,816,778;, + 3;822,806,823;, + 3;823,807,824;, + 3;778,811,782;, + 3;790,809,777;, + 3;824,801,817;, + 3;803,804,808;, + 3;779,795,783;, + 3;783,797,787;, + 3;787,800,792;, + 3;792,794,780;, + 3;780,796,784;, + 3;784,798,788;, + 3;788,799,791;, + 3;791,793,779;, + 3;793,818,795;, + 3;795,819,797;, + 3;797,820,800;, + 3;800,821,794;, + 3;794,822,796;, + 3;796,823,798;, + 3;798,824,799;, + 3;799,817,793;, + 3;809,784,810;, + 3;811,787,812;, + 3;810,788,813;, + 3;813,791,814;, + 3;812,792,815;, + 3;814,779,816;, + 3;816,783,811;, + 3;815,780,809;, + 3;865,851,849;, + 3;825,858,857;, + 3;830,860,859;, + 3;866,853,851;, + 3;829,861,858;, + 3;867,856,853;, + 3;868,850,856;, + 3;834,862,861;, + 3;833,863,860;, + 3;869,852,850;, + 3;837,864,862;, + 3;870,854,852;, + 3;871,855,854;, + 3;826,859,864;, + 3;838,857,863;, + 3;872,849,855;, + 3;849,851,855;, + 3;855,852,854;, + 3;851,852,855;, + 3;852,856,850;, + 3;856,851,853;, + 3;827,843,841;, + 3;831,845,843;, + 3;835,848,845;, + 3;840,842,848;, + 3;828,844,842;, + 3;832,846,844;, + 3;836,847,846;, + 3;839,841,847;, + 3;841,866,865;, + 3;843,867,866;, + 3;845,868,867;, + 3;848,869,868;, + 3;842,870,869;, + 3;844,871,870;, + 3;846,872,871;, + 3;847,865,872;, + 3;857,832,828;, + 3;859,835,831;, + 3;858,836,832;, + 3;861,839,836;, + 3;860,840,835;, + 3;862,827,839;, + 3;864,831,827;, + 3;863,828,840;, + 3;865,866,851;, + 3;825,829,858;, + 3;830,833,860;, + 3;866,867,853;, + 3;829,834,861;, + 3;867,868,856;, + 3;868,869,850;, + 3;834,837,862;, + 3;833,838,863;, + 3;869,870,852;, + 3;837,826,864;, + 3;870,871,854;, + 3;871,872,855;, + 3;826,830,859;, + 3;838,825,857;, + 3;872,865,849;, + 3;851,856,852;, + 3;827,831,843;, + 3;831,835,845;, + 3;835,840,848;, + 3;840,828,842;, + 3;828,832,844;, + 3;832,836,846;, + 3;836,839,847;, + 3;839,827,841;, + 3;841,843,866;, + 3;843,845,867;, + 3;845,848,868;, + 3;848,842,869;, + 3;842,844,870;, + 3;844,846,871;, + 3;846,847,872;, + 3;847,841,865;, + 3;857,858,832;, + 3;859,860,835;, + 3;858,861,836;, + 3;861,862,839;, + 3;860,863,840;, + 3;862,864,827;, + 3;864,859,831;, + 3;863,857,828;, + // Frontal_aux_gun + 3;913,897,899;, + 3;873,905,906;, + 3;878,907,908;, + 3;914,899,901;, + 3;877,906,909;, + 3;915,901,904;, + 3;916,904,898;, + 3;882,909,910;, + 3;881,908,911;, + 3;917,898,900;, + 3;885,910,912;, + 3;918,900,902;, + 3;919,902,903;, + 3;874,912,907;, + 3;886,911,905;, + 3;920,903,897;, + 3;897,903,899;, + 3;903,902,900;, + 3;899,903,900;, + 3;900,898,904;, + 3;904,901,899;, + 3;875,889,891;, + 3;879,891,893;, + 3;883,893,896;, + 3;888,896,890;, + 3;876,890,892;, + 3;880,892,894;, + 3;884,894,895;, + 3;887,895,889;, + 3;889,913,914;, + 3;891,914,915;, + 3;893,915,916;, + 3;896,916,917;, + 3;890,917,918;, + 3;892,918,919;, + 3;894,919,920;, + 3;895,920,913;, + 3;905,876,880;, + 3;907,879,883;, + 3;906,880,884;, + 3;909,884,887;, + 3;908,883,888;, + 3;910,887,875;, + 3;912,875,879;, + 3;911,888,876;, + 3;913,899,914;, + 3;873,906,877;, + 3;878,908,881;, + 3;914,901,915;, + 3;877,909,882;, + 3;915,904,916;, + 3;916,898,917;, + 3;882,910,885;, + 3;881,911,886;, + 3;917,900,918;, + 3;885,912,874;, + 3;918,902,919;, + 3;919,903,920;, + 3;874,907,878;, + 3;886,905,873;, + 3;920,897,913;, + 3;899,900,904;, + 3;875,891,879;, + 3;879,893,883;, + 3;883,896,888;, + 3;888,890,876;, + 3;876,892,880;, + 3;880,894,884;, + 3;884,895,887;, + 3;887,889,875;, + 3;889,914,891;, + 3;891,915,893;, + 3;893,916,896;, + 3;896,917,890;, + 3;890,918,892;, + 3;892,919,894;, + 3;894,920,895;, + 3;895,913,889;, + 3;905,880,906;, + 3;907,883,908;, + 3;906,884,909;, + 3;909,887,910;, + 3;908,888,911;, + 3;910,875,912;, + 3;912,879,907;, + 3;911,876,905;, + 3;961,947,945;, + 3;921,954,953;, + 3;926,956,955;, + 3;962,949,947;, + 3;925,957,954;, + 3;963,952,949;, + 3;964,946,952;, + 3;930,958,957;, + 3;929,959,956;, + 3;965,948,946;, + 3;933,960,958;, + 3;966,950,948;, + 3;967,951,950;, + 3;922,955,960;, + 3;934,953,959;, + 3;968,945,951;, + 3;945,947,951;, + 3;951,948,950;, + 3;947,948,951;, + 3;948,952,946;, + 3;952,947,949;, + 3;923,939,937;, + 3;927,941,939;, + 3;931,944,941;, + 3;936,938,944;, + 3;924,940,938;, + 3;928,942,940;, + 3;932,943,942;, + 3;935,937,943;, + 3;937,962,961;, + 3;939,963,962;, + 3;941,964,963;, + 3;944,965,964;, + 3;938,966,965;, + 3;940,967,966;, + 3;942,968,967;, + 3;943,961,968;, + 3;953,928,924;, + 3;955,931,927;, + 3;954,932,928;, + 3;957,935,932;, + 3;956,936,931;, + 3;958,923,935;, + 3;960,927,923;, + 3;959,924,936;, + 3;961,962,947;, + 3;921,925,954;, + 3;926,929,956;, + 3;962,963,949;, + 3;925,930,957;, + 3;963,964,952;, + 3;964,965,946;, + 3;930,933,958;, + 3;929,934,959;, + 3;965,966,948;, + 3;933,922,960;, + 3;966,967,950;, + 3;967,968,951;, + 3;922,926,955;, + 3;934,921,953;, + 3;968,961,945;, + 3;947,952,948;, + 3;923,927,939;, + 3;927,931,941;, + 3;931,936,944;, + 3;936,924,938;, + 3;924,928,940;, + 3;928,932,942;, + 3;932,935,943;, + 3;935,923,937;, + 3;937,939,962;, + 3;939,941,963;, + 3;941,944,964;, + 3;944,938,965;, + 3;938,940,966;, + 3;940,942,967;, + 3;942,943,968;, + 3;943,937,961;, + 3;953,954,928;, + 3;955,956,931;, + 3;954,957,932;, + 3;957,958,935;, + 3;956,959,936;, + 3;958,960,923;, + 3;960,955,927;, + 3;959,953,924;, + // Jet + 3;1050,1070,1071;, + 3;1051,1071,1072;, + 3;971,972,976;, + 3;972,973,977;, + 3;1070,969,1071;, + 3;1035,1036,1040;, + 3;1052,1072,1073;, + 3;975,976,980;, + 3;976,977,981;, + 3;1071,969,1072;, + 3;1036,1037,1041;, + 3;1066,1086,1087;, + 3;979,980,984;, + 3;980,981,985;, + 3;1072,969,1073;, + 3;1086,969,1087;, + 3;1053,1073,1074;, + 3;983,984,988;, + 3;984,985,989;, + 3;1073,969,1074;, + 3;1054,1074,1075;, + 3;1055,1075,1076;, + 3;987,988,992;, + 3;988,989,993;, + 3;1074,969,1075;, + 3;1039,1040,1044;, + 3;1056,1076,1077;, + 3;991,992,996;, + 3;992,993,997;, + 3;1075,969,1076;, + 3;1040,1041,1045;, + 3;1067,1087,1088;, + 3;995,996,1000;, + 3;996,997,1001;, + 3;1076,969,1077;, + 3;1087,969,1088;, + 3;1057,1077,1078;, + 3;999,1000,1004;, + 3;1000,1001,1005;, + 3;1077,969,1078;, + 3;1058,1078,1079;, + 3;1059,1079,1080;, + 3;1003,1004,1008;, + 3;1004,1005,1009;, + 3;1078,969,1079;, + 3;1043,1044,1048;, + 3;1060,1080,1081;, + 3;1007,1008,1012;, + 3;1008,1009,1013;, + 3;1079,969,1080;, + 3;1044,1045,1049;, + 3;1068,1088,1089;, + 3;1011,1012,1016;, + 3;1012,1013,1017;, + 3;1080,969,1081;, + 3;1088,969,1089;, + 3;1061,1081,1082;, + 3;1015,1016,1020;, + 3;1016,1017,1021;, + 3;1081,969,1082;, + 3;1062,1082,1083;, + 3;1063,1083,1084;, + 3;1019,1020,1024;, + 3;1020,1021,1025;, + 3;1082,969,1083;, + 3;1047,1048,972;, + 3;1064,1084,1085;, + 3;1023,1024,1028;, + 3;1024,1025,1029;, + 3;1083,969,1084;, + 3;1048,1049,973;, + 3;1069,1089,1070;, + 3;1027,1028,1032;, + 3;1028,1029,1033;, + 3;1084,969,1085;, + 3;1089,969,1070;, + 3;1065,1085,1086;, + 3;1031,1032,1036;, + 3;1032,1033,1037;, + 3;1085,969,1086;, + 3;973,1050,1051;, + 3;977,1051,1052;, + 3;981,1052,1053;, + 3;1037,1066,1067;, + 3;985,1053,1054;, + 3;989,1054,1055;, + 3;993,1055,1056;, + 3;997,1056,1057;, + 3;1041,1067,1068;, + 3;1001,1057,1058;, + 3;1005,1058,1059;, + 3;1009,1059,1060;, + 3;1013,1060,1061;, + 3;1045,1068,1069;, + 3;1017,1061,1062;, + 3;1021,1062,1063;, + 3;1025,1063,1064;, + 3;1029,1064,1065;, + 3;1049,1069,1050;, + 3;1033,1065,1066;, + 3;1050,1071,1051;, + 3;1051,1072,1052;, + 3;971,976,975;, + 3;972,977,976;, + 3;1035,1040,1039;, + 3;1052,1073,1053;, + 3;975,980,979;, + 3;976,981,980;, + 3;1036,1041,1040;, + 3;1066,1087,1067;, + 3;979,984,983;, + 3;980,985,984;, + 3;1053,1074,1054;, + 3;983,988,987;, + 3;984,989,988;, + 3;1054,1075,1055;, + 3;1055,1076,1056;, + 3;987,992,991;, + 3;988,993,992;, + 3;1039,1044,1043;, + 3;1056,1077,1057;, + 3;991,996,995;, + 3;992,997,996;, + 3;1040,1045,1044;, + 3;1067,1088,1068;, + 3;995,1000,999;, + 3;996,1001,1000;, + 3;1057,1078,1058;, + 3;999,1004,1003;, + 3;1000,1005,1004;, + 3;1058,1079,1059;, + 3;1059,1080,1060;, + 3;1003,1008,1007;, + 3;1004,1009,1008;, + 3;1043,1048,1047;, + 3;1060,1081,1061;, + 3;1007,1012,1011;, + 3;1008,1013,1012;, + 3;1044,1049,1048;, + 3;1068,1089,1069;, + 3;1011,1016,1015;, + 3;1012,1017,1016;, + 3;1061,1082,1062;, + 3;1015,1020,1019;, + 3;1016,1021,1020;, + 3;1062,1083,1063;, + 3;1063,1084,1064;, + 3;1019,1024,1023;, + 3;1020,1025,1024;, + 3;1047,972,971;, + 3;1064,1085,1065;, + 3;1023,1028,1027;, + 3;1024,1029,1028;, + 3;1048,973,972;, + 3;1069,1070,1050;, + 3;1027,1032,1031;, + 3;1028,1033,1032;, + 3;1065,1086,1066;, + 3;1031,1036,1035;, + 3;1032,1037,1036;, + 3;973,1051,977;, + 3;977,1052,981;, + 3;981,1053,985;, + 3;1037,1067,1041;, + 3;985,1054,989;, + 3;989,1055,993;, + 3;993,1056,997;, + 3;997,1057,1001;, + 3;1041,1068,1045;, + 3;1001,1058,1005;, + 3;1005,1059,1009;, + 3;1009,1060,1013;, + 3;1013,1061,1017;, + 3;1045,1069,1049;, + 3;1017,1062,1021;, + 3;1021,1063,1025;, + 3;1025,1064,1029;, + 3;1029,1065,1033;, + 3;1049,1050,973;, + 3;1033,1066,1037;, + 3;1151,1172,1171;, + 3;1152,1173,1172;, + 3;1091,1095,1092;, + 3;1092,1096,1093;, + 3;1171,1172,1090;, + 3;1139,1143,1140;, + 3;1153,1174,1173;, + 3;1094,1098,1095;, + 3;1095,1099,1096;, + 3;1172,1173,1090;, + 3;1140,1144,1141;, + 3;1167,1188,1187;, + 3;1097,1101,1098;, + 3;1098,1102,1099;, + 3;1173,1174,1090;, + 3;1187,1188,1090;, + 3;1154,1175,1174;, + 3;1100,1104,1101;, + 3;1101,1105,1102;, + 3;1174,1175,1090;, + 3;1155,1176,1175;, + 3;1156,1177,1176;, + 3;1103,1107,1104;, + 3;1104,1108,1105;, + 3;1175,1176,1090;, + 3;1142,1146,1143;, + 3;1157,1178,1177;, + 3;1106,1110,1107;, + 3;1107,1111,1108;, + 3;1176,1177,1090;, + 3;1143,1147,1144;, + 3;1168,1189,1188;, + 3;1109,1113,1110;, + 3;1110,1114,1111;, + 3;1177,1178,1090;, + 3;1188,1189,1090;, + 3;1158,1179,1178;, + 3;1112,1116,1113;, + 3;1113,1117,1114;, + 3;1178,1179,1090;, + 3;1159,1180,1179;, + 3;1160,1181,1180;, + 3;1115,1119,1116;, + 3;1116,1120,1117;, + 3;1179,1180,1090;, + 3;1145,1149,1146;, + 3;1161,1182,1181;, + 3;1118,1122,1119;, + 3;1119,1123,1120;, + 3;1180,1181,1090;, + 3;1146,1150,1147;, + 3;1169,1190,1189;, + 3;1121,1125,1122;, + 3;1122,1126,1123;, + 3;1181,1182,1090;, + 3;1189,1190,1090;, + 3;1162,1183,1182;, + 3;1124,1128,1125;, + 3;1125,1129,1126;, + 3;1182,1183,1090;, + 3;1163,1184,1183;, + 3;1164,1185,1184;, + 3;1127,1131,1128;, + 3;1128,1132,1129;, + 3;1183,1184,1090;, + 3;1148,1092,1149;, + 3;1165,1186,1185;, + 3;1130,1134,1131;, + 3;1131,1135,1132;, + 3;1184,1185,1090;, + 3;1149,1093,1150;, + 3;1170,1171,1190;, + 3;1133,1137,1134;, + 3;1134,1138,1135;, + 3;1185,1186,1090;, + 3;1190,1171,1090;, + 3;1166,1187,1186;, + 3;1136,1140,1137;, + 3;1137,1141,1138;, + 3;1186,1187,1090;, + 3;1093,1152,1151;, + 3;1096,1153,1152;, + 3;1099,1154,1153;, + 3;1141,1168,1167;, + 3;1102,1155,1154;, + 3;1105,1156,1155;, + 3;1108,1157,1156;, + 3;1111,1158,1157;, + 3;1144,1169,1168;, + 3;1114,1159,1158;, + 3;1117,1160,1159;, + 3;1120,1161,1160;, + 3;1123,1162,1161;, + 3;1147,1170,1169;, + 3;1126,1163,1162;, + 3;1129,1164,1163;, + 3;1132,1165,1164;, + 3;1135,1166,1165;, + 3;1150,1151,1170;, + 3;1138,1167,1166;, + 3;1151,1152,1172;, + 3;1152,1153,1173;, + 3;1091,1094,1095;, + 3;1092,1095,1096;, + 3;1139,1142,1143;, + 3;1153,1154,1174;, + 3;1094,1097,1098;, + 3;1095,1098,1099;, + 3;1140,1143,1144;, + 3;1167,1168,1188;, + 3;1097,1100,1101;, + 3;1098,1101,1102;, + 3;1154,1155,1175;, + 3;1100,1103,1104;, + 3;1101,1104,1105;, + 3;1155,1156,1176;, + 3;1156,1157,1177;, + 3;1103,1106,1107;, + 3;1104,1107,1108;, + 3;1142,1145,1146;, + 3;1157,1158,1178;, + 3;1106,1109,1110;, + 3;1107,1110,1111;, + 3;1143,1146,1147;, + 3;1168,1169,1189;, + 3;1109,1112,1113;, + 3;1110,1113,1114;, + 3;1158,1159,1179;, + 3;1112,1115,1116;, + 3;1113,1116,1117;, + 3;1159,1160,1180;, + 3;1160,1161,1181;, + 3;1115,1118,1119;, + 3;1116,1119,1120;, + 3;1145,1148,1149;, + 3;1161,1162,1182;, + 3;1118,1121,1122;, + 3;1119,1122,1123;, + 3;1146,1149,1150;, + 3;1169,1170,1190;, + 3;1121,1124,1125;, + 3;1122,1125,1126;, + 3;1162,1163,1183;, + 3;1124,1127,1128;, + 3;1125,1128,1129;, + 3;1163,1164,1184;, + 3;1164,1165,1185;, + 3;1127,1130,1131;, + 3;1128,1131,1132;, + 3;1148,1091,1092;, + 3;1165,1166,1186;, + 3;1130,1133,1134;, + 3;1131,1134,1135;, + 3;1149,1092,1093;, + 3;1170,1151,1171;, + 3;1133,1136,1137;, + 3;1134,1137,1138;, + 3;1166,1167,1187;, + 3;1136,1139,1140;, + 3;1137,1140,1141;, + 3;1093,1096,1152;, + 3;1096,1099,1153;, + 3;1099,1102,1154;, + 3;1141,1144,1168;, + 3;1102,1105,1155;, + 3;1105,1108,1156;, + 3;1108,1111,1157;, + 3;1111,1114,1158;, + 3;1144,1147,1169;, + 3;1114,1117,1159;, + 3;1117,1120,1160;, + 3;1120,1123,1161;, + 3;1123,1126,1162;, + 3;1147,1150,1170;, + 3;1126,1129,1163;, + 3;1129,1132,1164;, + 3;1132,1135,1165;, + 3;1135,1138,1166;, + 3;1150,1093,1151;, + 3;1138,1141,1167;, + // Chassis + 3;1195,1191,1192;, + 3;1200,1195,1196;, + 3;1371,1366,1380;, + 3;1365,1369,1383;, + 3;1200,1201,1395;, + 3;1398,1196,1397;, + 3;1400,1398,1197;, + 3;1376,1375,1385;, + 3;1400,1201,1398;, + 3;1348,1386,1237;, + 3;1196,1398,1201;, + 3;1368,1367,1381;, + 3;1400,1396,1395;, + 3;1288,1293,1290;, + 3;1345,1386,1224;, + 3;1399,1258,1401;, + 3;1388,1344,1392;, + 3;1202,1206,1396;, + 3;1237,1259,1238;, + 3;1388,1387,1399;, + 3;1367,1365,1379;, + 3;1387,1388,1200;, + 3;1397,1193,1194;, + 3;1202,1197,1198;, + 3;1206,1202,1203;, + 3;1371,1253,1210;, + 3;1203,1198,1199;, + 3;1207,1203,1204;, + 3;1255,1254,1251;, + 3;1265,1267,1270;, + 3;1292,1290,1293;, + 3;1278,1216,1297;, + 3;1225,1296,1293;, + 3;1357,1369,1365;, + 3;1362,1194,1193;, + 3;1372,1377,1381;, + 3;1237,1238,1346;, + 3;1345,1316,1354;, + 3;1316,1345,1343;, + 3;1224,1211,1343;, + 3;1345,1257,1237;, + 3;1224,1349,1324;, + 3;1373,1372,1379;, + 3;1370,1371,1385;, + 3;1369,1370,1384;, + 3;1246,1390,1358;, + 3;1246,1389,1364;, + 3;1195,1200,1388;, + 3;1250,1245,1350;, + 3;1253,1250,1351;, + 3;1253,1352,1353;, + 3;1304,1277,1220;, + 3;1277,1304,1227;, + 3;1223,1255,1289;, + 3;1254,1255,1223;, + 3;1235,1239,1266;, + 3;1222,1226,1283;, + 3;1227,1304,1301;, + 3;1261,1221,1275;, + 3;1294,1307,1223;, + 3;1251,1240,1236;, + 3;1358,1391,1401;, + 3;1390,1393,1394;, + 3;1323,1191,1388;, + 3;1230,1231,1261;, + 3;1273,1269,1271;, + 3;1268,1259,1257;, + 3;1242,1243,1360;, + 3;1192,1247,1248;, + 3;1319,1317,1318;, + 3;1280,1279,1264;, + 3;1238,1239,1355;, + 3;1362,1248,1360;, + 3;1358,1394,1392;, + 3;1282,1281,1272;, + 3;1239,1235,1236;, + 3;1239,1240,1350;, + 3;1245,1356,1249;, + 3;1359,1360,1248;, + 3;1249,1360,1243;, + 3;1204,1199,1209;, + 3;1204,1367,1368;, + 3;1219,1213,1215;, + 3;1284,1283,1264;, + 3;1212,1254,1214;, + 3;1393,1242,1359;, + 3;1268,1267,1265;, + 3;1293,1288,1234;, + 3;1219,1220,1260;, + 3;1252,1236,1216;, + 3;1231,1340,1261;, + 3;1225,1229,1299;, + 3;1260,1261,1274;, + 3;1260,1270,1267;, + 3;1237,1257,1259;, + 3;1319,1320,1321;, + 3;1266,1264,1228;, + 3;1230,1326,1327;, + 3;1255,1252,1278;, + 3;1236,1235,1228;, + 3;1257,1354,1268;, + 3;1300,1295,1289;, + 3;1270,1274,1282;, + 3;1283,1284,1281;, + 3;1275,1286,1281;, + 3;1238,1266,1239;, + 3;1330,1339,1325;, + 3;1332,1334,1337;, + 3;1341,1342,1333;, + 3;1282,1274,1275;, + 3;1277,1230,1260;, + 3;1261,1340,1232;, + 3;1285,1265,1271;, + 3;1265,1263,1282;, + 3;1273,1272,1279;, + 3;1284,1279,1272;, + 3;1338,1326,1331;, + 3;1288,1218,1308;, + 3;1221,1222,1286;, + 3;1339,1336,1337;, + 3;1287,1337,1335;, + 3;1342,1338,1335;, + 3;1226,1228,1264;, + 3;1288,1276,1305;, + 3;1330,1332,1336;, + 3;1394,1247,1323;, + 3;1294,1295,1225;, + 3;1295,1294,1217;, + 3;1300,1297,1302;, + 3;1299,1298,1232;, + 3;1225,1295,1300;, + 3;1296,1299,1291;, + 3;1303,1234,1307;, + 3;1227,1305,1262;, + 3;1226,1297,1216;, + 3;1305,1301,1218;, + 3;1291,1232,1341;, + 3;1354,1316,1219;, + 3;1276,1262,1305;, + 3;1307,1306,1214;, + 3;1234,1308,1306;, + 3;1266,1238,1309;, + 3;1280,1266,1311;, + 3;1273,1280,1314;, + 3;1269,1273,1314;, + 3;1285,1269,1313;, + 3;1268,1285,1313;, + 3;1259,1268,1312;, + 3;1238,1259,1310;, + 3;1311,1309,1317;, + 3;1314,1311,1319;, + 3;1246,1241,1324;, + 3;1313,1314,1322;, + 3;1213,1219,1316;, + 3;1312,1313,1321;, + 3;1310,1312,1320;, + 3;1309,1310,1318;, + 3;1277,1331,1326;, + 3;1287,1331,1325;, + 3;1233,1231,1327;, + 3;1262,1276,1330;, + 3;1290,1292,1334;, + 3;1276,1290,1332;, + 3;1233,1328,1342;, + 3;1292,1291,1333;, + 3;1227,1262,1329;, + 3;1277,1227,1325;, + 3;1342,1328,1338;, + 3;1334,1333,1335;, + 3;1328,1327,1326;, + 3;1232,1298,1222;, + 3;1298,1299,1229;, + 3;1297,1226,1302;, + 3;1222,1298,1302;, + 3;1357,1361,1194;, + 3;1394,1359,1247;, + 3;1340,1341,1232;, + 3;1348,1347,1242;, + 3;1199,1198,1363;, + 3;1371,1370,1250;, + 3;1361,1365,1367;, + 3;1249,1356,1357;, + 3;1191,1323,1247;, + 3;1341,1340,1233;, + 3;1340,1231,1233;, + 3;1374,1373,1383;, + 3;1196,1192,1193;, + 3;1377,1378,1382;, + 3;1375,1374,1384;, + 3;1224,1386,1348;, + 3;1393,1390,1348;, + 3;1197,1397,1363;, + 3;1347,1346,1243;, + 3;1349,1348,1390;, + 3;1351,1350,1240;, + 3;1352,1351,1251;, + 3;1353,1352,1254;, + 3;1346,1355,1244;, + 3;1355,1350,1245;, + 3;1209,1363,1194;, + 3;1268,1354,1256;, + 3;1356,1370,1369;, + 3;1370,1356,1245;, + 3;1344,1401,1391;, + 3;1258,1364,1389;, + 3;1348,1237,1347;, + 3;1195,1192,1196;, + 3;1200,1196,1201;, + 3;1371,1380,1385;, + 3;1365,1383,1379;, + 3;1200,1395,1205;, + 3;1398,1397,1197;, + 3;1400,1197,1202;, + 3;1376,1385,1380;, + 3;1368,1381,1382;, + 3;1400,1395,1201;, + 3;1288,1290,1276;, + 3;1399,1401,1344;, + 3;1202,1396,1400;, + 3;1388,1399,1344;, + 3;1367,1379,1381;, + 3;1387,1200,1205;, + 3;1397,1194,1363;, + 3;1202,1198,1203;, + 3;1206,1203,1207;, + 3;1371,1210,1366;, + 3;1203,1199,1204;, + 3;1207,1204,1208;, + 3;1255,1251,1252;, + 3;1265,1270,1263;, + 3;1292,1293,1296;, + 3;1278,1297,1300;, + 3;1225,1293,1303;, + 3;1357,1365,1361;, + 3;1362,1193,1248;, + 3;1372,1381,1379;, + 3;1237,1346,1347;, + 3;1345,1354,1257;, + 3;1316,1343,1315;, + 3;1224,1343,1345;, + 3;1345,1237,1386;, + 3;1224,1324,1211;, + 3;1373,1379,1383;, + 3;1370,1385,1384;, + 3;1369,1384,1383;, + 3;1246,1358,1389;, + 3;1246,1364,1241;, + 3;1195,1388,1191;, + 3;1250,1350,1351;, + 3;1253,1351,1352;, + 3;1253,1353,1210;, + 3;1304,1220,1215;, + 3;1223,1289,1217;, + 3;1254,1223,1214;, + 3;1235,1266,1228;, + 3;1222,1283,1286;, + 3;1227,1301,1305;, + 3;1261,1275,1274;, + 3;1294,1223,1217;, + 3;1251,1236,1252;, + 3;1358,1401,1389;, + 3;1390,1394,1358;, + 3;1323,1388,1392;, + 3;1230,1261,1260;, + 3;1273,1271,1272;, + 3;1242,1360,1359;, + 3;1192,1248,1193;, + 3;1319,1318,1320;, + 3;1280,1264,1266;, + 3;1238,1355,1346;, + 3;1362,1360,1249;, + 3;1358,1392,1391;, + 3;1282,1272,1271;, + 3;1239,1236,1240;, + 3;1239,1350,1355;, + 3;1245,1249,1244;, + 3;1359,1248,1247;, + 3;1249,1243,1244;, + 3;1204,1209,1367;, + 3;1204,1368,1208;, + 3;1219,1215,1220;, + 3;1284,1264,1279;, + 3;1393,1359,1394;, + 3;1268,1265,1285;, + 3;1293,1234,1303;, + 3;1219,1260,1256;, + 3;1252,1216,1278;, + 3;1225,1299,1296;, + 3;1260,1274,1270;, + 3;1260,1267,1256;, + 3;1319,1321,1322;, + 3;1230,1327,1231;, + 3;1255,1278,1289;, + 3;1236,1228,1216;, + 3;1300,1289,1278;, + 3;1270,1282,1263;, + 3;1283,1281,1286;, + 3;1330,1325,1329;, + 3;1332,1337,1336;, + 3;1341,1333,1291;, + 3;1282,1275,1281;, + 3;1277,1260,1220;, + 3;1261,1232,1221;, + 3;1285,1271,1269;, + 3;1265,1282,1271;, + 3;1273,1279,1280;, + 3;1284,1272,1281;, + 3;1338,1331,1287;, + 3;1288,1308,1234;, + 3;1221,1286,1275;, + 3;1339,1337,1287;, + 3;1287,1335,1338;, + 3;1342,1335,1333;, + 3;1226,1264,1283;, + 3;1330,1336,1339;, + 3;1394,1323,1392;, + 3;1294,1225,1303;, + 3;1295,1217,1289;, + 3;1300,1302,1229;, + 3;1299,1232,1291;, + 3;1225,1300,1229;, + 3;1296,1291,1292;, + 3;1303,1307,1294;, + 3;1226,1216,1228;, + 3;1305,1218,1288;, + 3;1354,1219,1256;, + 3;1307,1214,1223;, + 3;1234,1306,1307;, + 3;1266,1309,1311;, + 3;1280,1311,1314;, + 3;1269,1314,1313;, + 3;1268,1313,1312;, + 3;1259,1312,1310;, + 3;1238,1310,1309;, + 3;1311,1317,1319;, + 3;1314,1319,1322;, + 3;1246,1324,1349;, + 3;1313,1322,1321;, + 3;1213,1316,1315;, + 3;1312,1321,1320;, + 3;1310,1320,1318;, + 3;1309,1318,1317;, + 3;1277,1326,1230;, + 3;1287,1325,1339;, + 3;1233,1327,1328;, + 3;1262,1330,1329;, + 3;1290,1334,1332;, + 3;1276,1332,1330;, + 3;1233,1342,1341;, + 3;1292,1333,1334;, + 3;1227,1329,1325;, + 3;1277,1325,1331;, + 3;1334,1335,1337;, + 3;1328,1326,1338;, + 3;1232,1222,1221;, + 3;1298,1229,1302;, + 3;1222,1302,1226;, + 3;1357,1194,1362;, + 3;1348,1242,1393;, + 3;1199,1363,1209;, + 3;1371,1250,1253;, + 3;1361,1367,1209;, + 3;1249,1357,1362;, + 3;1191,1247,1192;, + 3;1374,1383,1384;, + 3;1196,1193,1397;, + 3;1377,1382,1381;, + 3;1375,1384,1385;, + 3;1224,1348,1349;, + 3;1197,1363,1198;, + 3;1347,1243,1242;, + 3;1349,1390,1246;, + 3;1351,1240,1251;, + 3;1352,1251,1254;, + 3;1353,1254,1212;, + 3;1346,1244,1243;, + 3;1355,1245,1244;, + 3;1209,1194,1361;, + 3;1268,1256,1267;, + 3;1356,1369,1357;, + 3;1370,1245,1250;, + 3;1344,1391,1392;, + 3;1258,1389,1401;, + 3;1406,1403,1402;, + 3;1411,1407,1406;, + 3;1558,1380,1366;, + 3;1554,1566,1556;, + 3;1411,1395,1412;, + 3;1578,1577,1407;, + 3;1579,1408,1578;, + 3;1376,1568,1562;, + 3;1579,1578,1412;, + 3;1539,1437,1569;, + 3;1407,1412,1578;, + 3;1368,1565,1555;, + 3;1579,1395,1396;, + 3;1486,1488,1491;, + 3;1536,1424,1569;, + 3;1399,1580,1258;, + 3;1570,1574,1535;, + 3;1413,1396,1206;, + 3;1437,1438,1457;, + 3;1570,1399,1387;, + 3;1555,1564,1554;, + 3;1387,1411,1570;, + 3;1577,1405,1404;, + 3;1413,1409,1408;, + 3;1206,1414,1413;, + 3;1558,1210,1452;, + 3;1414,1410,1409;, + 3;1207,1415,1414;, + 3;1454,1450,1453;, + 3;1463,1468,1465;, + 3;1490,1491,1488;, + 3;1476,1495,1417;, + 3;1425,1491,1494;, + 3;1547,1554,1556;, + 3;1552,1404,1405;, + 3;1559,1565,1563;, + 3;1437,1537,1438;, + 3;1536,1544,1509;, + 3;1509,1343,1536;, + 3;1424,1343,1211;, + 3;1536,1437,1456;, + 3;1424,1324,1540;, + 3;1560,1564,1559;, + 3;1557,1568,1558;, + 3;1556,1567,1557;, + 3;1445,1548,1572;, + 3;1445,1364,1571;, + 3;1406,1570,1411;, + 3;1449,1541,1444;, + 3;1452,1542,1449;, + 3;1452,1353,1543;, + 3;1304,1420,1475;, + 3;1475,1427,1304;, + 3;1423,1487,1454;, + 3;1453,1423,1454;, + 3;1435,1464,1439;, + 3;1422,1481,1426;, + 3;1427,1301,1304;, + 3;1459,1473,1421;, + 3;1492,1423,1502;, + 3;1450,1436,1440;, + 3;1548,1580,1573;, + 3;1572,1576,1575;, + 3;1516,1570,1402;, + 3;1430,1459,1431;, + 3;1471,1469,1467;, + 3;1466,1456,1457;, + 3;1441,1550,1442;, + 3;1403,1447,1446;, + 3;1512,1511,1510;, + 3;1478,1462,1477;, + 3;1438,1545,1439;, + 3;1552,1550,1447;, + 3;1548,1574,1576;, + 3;1480,1470,1479;, + 3;1439,1436,1435;, + 3;1439,1541,1440;, + 3;1444,1448,1546;, + 3;1549,1447,1550;, + 3;1448,1442,1550;, + 3;1415,1416,1410;, + 3;1415,1368,1555;, + 3;1419,1215,1213;, + 3;1482,1462,1481;, + 3;1212,1214,1453;, + 3;1575,1549,1441;, + 3;1466,1463,1465;, + 3;1491,1434,1486;, + 3;1419,1458,1420;, + 3;1451,1417,1436;, + 3;1431,1459,1532;, + 3;1425,1497,1429;, + 3;1458,1472,1459;, + 3;1458,1465,1468;, + 3;1437,1457,1456;, + 3;1512,1514,1513;, + 3;1464,1428,1462;, + 3;1430,1519,1518;, + 3;1454,1476,1451;, + 3;1436,1428,1435;, + 3;1456,1466,1544;, + 3;1498,1487,1493;, + 3;1468,1480,1472;, + 3;1481,1479,1482;, + 3;1473,1479,1484;, + 3;1438,1439,1464;, + 3;1522,1517,1531;, + 3;1524,1529,1526;, + 3;1533,1525,1534;, + 3;1480,1473,1472;, + 3;1475,1458,1430;, + 3;1459,1432,1532;, + 3;1483,1469,1463;, + 3;1463,1480,1461;, + 3;1471,1477,1470;, + 3;1482,1470,1477;, + 3;1530,1523,1518;, + 3;1486,1308,1218;, + 3;1421,1484,1422;, + 3;1531,1529,1528;, + 3;1485,1527,1529;, + 3;1534,1527,1530;, + 3;1426,1462,1428;, + 3;1486,1501,1474;, + 3;1522,1528,1524;, + 3;1576,1516,1446;, + 3;1492,1425,1493;, + 3;1493,1418,1492;, + 3;1498,1499,1495;, + 3;1497,1432,1496;, + 3;1425,1498,1493;, + 3;1494,1489,1497;, + 3;1500,1502,1434;, + 3;1427,1460,1501;, + 3;1426,1417,1495;, + 3;1501,1218,1301;, + 3;1489,1533,1432;, + 3;1544,1419,1509;, + 3;1474,1501,1460;, + 3;1502,1214,1306;, + 3;1434,1306,1308;, + 3;1464,1503,1438;, + 3;1478,1505,1464;, + 3;1471,1508,1478;, + 3;1467,1508,1471;, + 3;1483,1507,1467;, + 3;1466,1507,1483;, + 3;1457,1506,1466;, + 3;1438,1504,1457;, + 3;1505,1510,1503;, + 3;1508,1512,1505;, + 3;1445,1324,1241;, + 3;1507,1515,1508;, + 3;1213,1509,1419;, + 3;1506,1514,1507;, + 3;1504,1513,1506;, + 3;1503,1511,1504;, + 3;1475,1518,1523;, + 3;1485,1517,1523;, + 3;1433,1519,1431;, + 3;1460,1522,1474;, + 3;1488,1526,1490;, + 3;1474,1524,1488;, + 3;1433,1534,1520;, + 3;1490,1525,1489;, + 3;1427,1521,1460;, + 3;1475,1517,1427;, + 3;1534,1530,1520;, + 3;1526,1527,1525;, + 3;1520,1518,1519;, + 3;1432,1422,1496;, + 3;1496,1429,1497;, + 3;1495,1499,1426;, + 3;1422,1499,1496;, + 3;1547,1405,1551;, + 3;1576,1446,1549;, + 3;1532,1432,1533;, + 3;1539,1441,1538;, + 3;1410,1553,1409;, + 3;1558,1449,1557;, + 3;1551,1555,1554;, + 3;1448,1547,1546;, + 3;1402,1446,1516;, + 3;1533,1433,1532;, + 3;1532,1433,1431;, + 3;1561,1566,1560;, + 3;1407,1404,1403;, + 3;1563,1382,1378;, + 3;1562,1567,1561;, + 3;1424,1539,1569;, + 3;1575,1539,1572;, + 3;1408,1553,1577;, + 3;1538,1442,1537;, + 3;1540,1572,1539;, + 3;1542,1440,1541;, + 3;1543,1450,1542;, + 3;1353,1453,1543;, + 3;1537,1443,1545;, + 3;1545,1444,1541;, + 3;1416,1405,1553;, + 3;1466,1455,1544;, + 3;1546,1556,1557;, + 3;1557,1444,1546;, + 3;1535,1573,1580;, + 3;1258,1571,1364;, + 3;1539,1538,1437;, + 3;1406,1407,1403;, + 3;1411,1412,1407;, + 3;1558,1568,1380;, + 3;1554,1564,1566;, + 3;1411,1205,1395;, + 3;1578,1408,1577;, + 3;1579,1413,1408;, + 3;1376,1380,1568;, + 3;1368,1382,1565;, + 3;1579,1412,1395;, + 3;1486,1474,1488;, + 3;1399,1535,1580;, + 3;1413,1579,1396;, + 3;1570,1535,1399;, + 3;1555,1565,1564;, + 3;1387,1205,1411;, + 3;1577,1553,1405;, + 3;1413,1414,1409;, + 3;1206,1207,1414;, + 3;1558,1366,1210;, + 3;1414,1415,1410;, + 3;1207,1208,1415;, + 3;1454,1451,1450;, + 3;1463,1461,1468;, + 3;1490,1494,1491;, + 3;1476,1498,1495;, + 3;1425,1500,1491;, + 3;1547,1551,1554;, + 3;1552,1447,1404;, + 3;1559,1564,1565;, + 3;1437,1538,1537;, + 3;1536,1456,1544;, + 3;1509,1315,1343;, + 3;1424,1536,1343;, + 3;1536,1569,1437;, + 3;1424,1211,1324;, + 3;1560,1566,1564;, + 3;1557,1567,1568;, + 3;1556,1566,1567;, + 3;1445,1571,1548;, + 3;1445,1241,1364;, + 3;1406,1402,1570;, + 3;1449,1542,1541;, + 3;1452,1543,1542;, + 3;1452,1210,1353;, + 3;1304,1215,1420;, + 3;1423,1418,1487;, + 3;1453,1214,1423;, + 3;1435,1428,1464;, + 3;1422,1484,1481;, + 3;1427,1501,1301;, + 3;1459,1472,1473;, + 3;1492,1418,1423;, + 3;1450,1451,1436;, + 3;1548,1571,1580;, + 3;1572,1548,1576;, + 3;1516,1574,1570;, + 3;1430,1458,1459;, + 3;1471,1470,1469;, + 3;1441,1549,1550;, + 3;1403,1404,1447;, + 3;1512,1513,1511;, + 3;1478,1464,1462;, + 3;1438,1537,1545;, + 3;1552,1448,1550;, + 3;1548,1573,1574;, + 3;1480,1469,1470;, + 3;1439,1440,1436;, + 3;1439,1545,1541;, + 3;1444,1443,1448;, + 3;1549,1446,1447;, + 3;1448,1443,1442;, + 3;1415,1555,1416;, + 3;1415,1208,1368;, + 3;1419,1420,1215;, + 3;1482,1477,1462;, + 3;1575,1576,1549;, + 3;1466,1483,1463;, + 3;1491,1500,1434;, + 3;1419,1455,1458;, + 3;1451,1476,1417;, + 3;1425,1494,1497;, + 3;1458,1468,1472;, + 3;1458,1455,1465;, + 3;1512,1515,1514;, + 3;1430,1431,1519;, + 3;1454,1487,1476;, + 3;1436,1417,1428;, + 3;1498,1476,1487;, + 3;1468,1461,1480;, + 3;1481,1484,1479;, + 3;1522,1521,1517;, + 3;1524,1528,1529;, + 3;1533,1489,1525;, + 3;1480,1479,1473;, + 3;1475,1420,1458;, + 3;1459,1421,1432;, + 3;1483,1467,1469;, + 3;1463,1469,1480;, + 3;1471,1478,1477;, + 3;1482,1479,1470;, + 3;1530,1485,1523;, + 3;1486,1434,1308;, + 3;1421,1473,1484;, + 3;1531,1485,1529;, + 3;1485,1530,1527;, + 3;1534,1525,1527;, + 3;1426,1481,1462;, + 3;1522,1531,1528;, + 3;1576,1574,1516;, + 3;1492,1500,1425;, + 3;1493,1487,1418;, + 3;1498,1429,1499;, + 3;1497,1489,1432;, + 3;1425,1429,1498;, + 3;1494,1490,1489;, + 3;1500,1492,1502;, + 3;1426,1428,1417;, + 3;1501,1486,1218;, + 3;1544,1455,1419;, + 3;1502,1423,1214;, + 3;1434,1502,1306;, + 3;1464,1505,1503;, + 3;1478,1508,1505;, + 3;1467,1507,1508;, + 3;1466,1506,1507;, + 3;1457,1504,1506;, + 3;1438,1503,1504;, + 3;1505,1512,1510;, + 3;1508,1515,1512;, + 3;1445,1540,1324;, + 3;1507,1514,1515;, + 3;1213,1315,1509;, + 3;1506,1513,1514;, + 3;1504,1511,1513;, + 3;1503,1510,1511;, + 3;1475,1430,1518;, + 3;1485,1531,1517;, + 3;1433,1520,1519;, + 3;1460,1521,1522;, + 3;1488,1524,1526;, + 3;1474,1522,1524;, + 3;1433,1533,1534;, + 3;1490,1526,1525;, + 3;1427,1517,1521;, + 3;1475,1523,1517;, + 3;1526,1529,1527;, + 3;1520,1530,1518;, + 3;1432,1421,1422;, + 3;1496,1499,1429;, + 3;1422,1426,1499;, + 3;1547,1552,1405;, + 3;1539,1575,1441;, + 3;1410,1416,1553;, + 3;1558,1452,1449;, + 3;1551,1416,1555;, + 3;1448,1552,1547;, + 3;1402,1403,1446;, + 3;1561,1567,1566;, + 3;1407,1577,1404;, + 3;1563,1565,1382;, + 3;1562,1568,1567;, + 3;1424,1540,1539;, + 3;1408,1409,1553;, + 3;1538,1441,1442;, + 3;1540,1445,1572;, + 3;1542,1450,1440;, + 3;1543,1453,1450;, + 3;1353,1212,1453;, + 3;1537,1442,1443;, + 3;1545,1443,1444;, + 3;1416,1551,1405;, + 3;1466,1465,1455;, + 3;1546,1547,1556;, + 3;1557,1449,1444;, + 3;1535,1574,1573;, + 3;1258,1580,1571;, + // Bubble + 3;1581,1597,1589;, + 3;1605,1604,1588;, + 3;1597,1605,1593;, + 3;1583,1585,1604;, + 3;1587,1588,1604;, + 3;1589,1597,1582;, + 3;1585,1586,1604;, + 3;1597,1581,1583;, + 3;1605,1588,1593;, + 3;1597,1593,1582;, + 3;1583,1604,1605;, + 3;1587,1604,1586;, + 3;1589,1582,1590;, + 3;1597,1583,1605;, + 3;1607,1611,1612;, + 3;1614,1588,1613;, + 3;1612,1593,1614;, + 3;1608,1613,1609;, + 3;1587,1613,1588;, + 3;1611,1582,1612;, + 3;1609,1613,1610;, + 3;1612,1608,1607;, + 3;1614,1593,1588;, + 3;1612,1582,1593;, + 3;1608,1614,1613;, + 3;1587,1610,1613;, + 3;1611,1590,1582;, + 3;1612,1614,1608;; + + } + MeshTextureCoords { + 1615; + // Turret_base + 0.25;0.845;, + 0.077;0.498;, + 1.005;0.497;, + 0.905;0.496;, + 0.595;0.496;, + 0.495;0.497;, + 0.423;0.498;, + 0.362;0.498;, + 0.305;0.498;, + 0.25;0.498;, + 0.195;0.498;, + 0.139;0.498;, + 0.087;0.644;, + 1.02;0.684;, + 0.924;0.752;, + 0.576;0.751;, + 0.48;0.683;, + 0.413;0.644;, + 0.356;0.622;, + 0.302;0.611;, + 0.25;0.608;, + 0.198;0.611;, + 0.145;0.622;, + 0.129;0.777;, + 1.091;0.829;, + 0.41;0.828;, + 0.371;0.776;, + 0.331;0.744;, + 0.291;0.727;, + 0.25;0.722;, + 0.21;0.727;, + 0.169;0.744;, + 0.902;0.773;, + 0.357;0.496;, + 0.144;0.496;, + 0.081;0.861;, + 0.535;0.841;, + 0.964;0.841;, + 0.631;0.495;, + 0.42;0.861;, + 0.144;0.812;, + 0.357;0.812;, + 0.868;0.495;, + 0.251;0.929;, + 0.597;0.772;, + // Gatling_base + 1.0;0.5;, + 0.0;0.5;, + 0.5;0.0;, + 1.0;0.0;, + 0.854;0.854;, + 0.146;0.146;, + 0.625;0.0;, + 0.125;0.0;, + 0.5;0.0;, + 0.5;1.0;, + 0.25;0.0;, + 0.75;0.0;, + 0.146;0.854;, + 0.854;0.146;, + 0.875;0.0;, + 0.375;0.0;, + 0.5;0.5;, + 0.625;0.5;, + 1.0;0.5;, + 0.125;0.5;, + 0.75;0.5;, + 0.875;0.5;, + 0.25;0.5;, + 0.375;0.5;, + // Gatling_base_2 + 1.0;1.0;, + 1.0;0.667;, + 1.0;0.333;, + 0.0;1.0;, + 0.333;0.0;, + 0.333;0.667;, + 0.333;0.333;, + 0.333;1.0;, + 0.667;0.0;, + 0.667;0.667;, + 0.667;0.333;, + 0.667;1.0;, + 1.0;0.0;, + 0.0;0.667;, + 0.0;0.333;, + 1.0;1.0;, + 1.0;0.333;, + 0.333;0.667;, + 0.333;0.333;, + 1.0;0.667;, + 1.0;0.667;, + 0.667;0.667;, + 0.667;0.333;, + 1.0;0.333;, + 1.0;1.0;, + 0.0;0.667;, + 0.0;0.333;, + 1.0;0.0;, + 0.667;1.0;, + 0.333;0.667;, + 0.333;0.333;, + 0.667;0.0;, + 0.333;1.0;, + 0.667;0.667;, + 0.667;0.333;, + 0.333;0.0;, + 0.0;1.0;, + 0.0;0.667;, + 0.0;0.333;, + 1.0;0.0;, + 0.0;0.667;, + 0.333;0.667;, + 0.333;0.333;, + 0.0;0.333;, + 0.0;0.333;, + 0.667;0.667;, + 0.667;0.333;, + 0.0;0.667;, + 0.333;0.667;, + 0.333;0.333;, + 0.667;0.667;, + 0.667;0.333;, + 0.333;0.667;, + 0.333;0.333;, + 0.667;0.667;, + 0.667;0.333;, + // Gatling_mid + 0.982;0.496;, + 0.5;1.0;, + 1.0;0.0;, + 1.0;0.5;, + 0.125;1.0;, + 0.989;0.967;, + 0.0;0.0;, + 0.125;0.0;, + 0.75;1.0;, + 0.25;1.0;, + 0.5;1.0;, + 0.5;0.0;, + 0.375;1.0;, + 0.875;1.0;, + 0.854;0.146;, + 0.146;0.854;, + 0.5;0.5;, + 0.625;0.5;, + 1.0;0.5;, + 0.125;0.5;, + 0.75;0.5;, + 0.875;0.5;, + 0.25;0.5;, + 0.375;0.5;, + 0.5;0.75;, + 0.625;0.75;, + 0.0;0.75;, + 0.125;0.75;, + 0.75;0.75;, + 0.875;0.75;, + 0.25;0.75;, + 0.375;0.75;, + 1.0;1.0;, + 1.0;1.0;, + 1.0;0.0;, + 1.0;1.0;, + 1.0;0.0;, + 0.0;0.0;, + 1.0;1.0;, + 1.0;1.0;, + 0.0;0.0;, + 0.638;0.638;, + 1.0;0.0;, + 0.361;0.638;, + 0.0;0.0;, + 1.0;0.0;, + 0.5;0.304;, + 1.0;1.0;, + 0.988;0.012;, + 0.635;0.627;, + 0.299;0.5;, + 0.7;0.494;, + 0.504;0.298;, + 0.368;0.633;, + 0.976;0.012;, + 0.645;0.362;, + 0.708;0.5;, + 0.647;0.647;, + 0.5;0.708;, + 0.352;0.647;, + 1.0;1.0;, + 0.0;1.0;, + 0.5;0.292;, + 0.647;0.353;, + // Gatling_fin_1 + 0.0;0.0;, + 0.5;0.0;, + 0.5;0.0;, + 1.0;0.0;, + 0.125;1.0;, + 0.146;0.146;, + 0.625;0.0;, + 0.125;0.0;, + 0.0;0.5;, + 1.0;0.5;, + 0.25;0.0;, + 0.75;0.0;, + 0.854;0.146;, + 0.146;0.854;, + 0.875;0.0;, + 0.375;0.0;, + 0.5;0.5;, + 0.625;0.5;, + 0.0;0.5;, + 0.125;0.5;, + 0.75;0.5;, + 0.875;0.5;, + 0.25;0.5;, + 0.375;0.5;, + 0.5;0.75;, + 0.625;0.75;, + 0.0;0.75;, + 0.125;0.75;, + 0.75;0.75;, + 0.875;0.75;, + 0.25;0.75;, + 0.375;0.75;, + 1.0;1.0;, + 1.0;0.0;, + 1.0;0.0;, + 0.361;0.638;, + 0.304;0.5;, + 0.0;0.0;, + 1.0;1.0;, + 1.0;1.0;, + 0.695;0.5;, + 0.0;0.0;, + 1.0;1.0;, + 0.0;0.0;, + 0.0;0.0;, + 1.0;0.0;, + 1.0;0.0;, + 0.638;0.362;, + 0.353;0.353;, + 1.0;1.0;, + 0.5;0.292;, + 0.0;1.0;, + 0.292;0.5;, + 0.647;0.353;, + 0.707;0.5;, + 0.353;0.646;, + 0.69;0.495;, + 0.988;0.025;, + 0.98;0.971;, + 0.366;0.643;, + 0.988;0.012;, + 0.037;0.012;, + 0.506;0.299;, + 0.637;0.353;, + // Gatling_fin_2 + 0.991;0.495;, + 0.989;0.011;, + 0.976;0.989;, + 1.0;0.0;, + 0.125;1.0;, + 0.982;0.007;, + 0.625;0.0;, + 0.125;0.0;, + 0.505;0.009;, + 0.978;0.024;, + 0.25;0.0;, + 0.75;0.0;, + 0.162;0.84;, + 0.851;0.157;, + 0.875;0.0;, + 0.375;0.0;, + 0.5;0.5;, + 0.625;0.5;, + 0.0;0.5;, + 0.125;0.5;, + 0.75;0.5;, + 0.875;0.5;, + 0.25;0.5;, + 0.375;0.5;, + 0.5;0.75;, + 0.625;0.75;, + 1.0;0.75;, + 0.125;0.75;, + 0.75;0.75;, + 0.875;0.75;, + 0.25;0.75;, + 0.375;0.75;, + 0.0;0.0;, + 1.0;0.0;, + 0.0;0.0;, + 1.0;1.0;, + 1.0;0.0;, + 0.0;0.0;, + 1.0;1.0;, + 1.0;1.0;, + 0.695;0.5;, + 0.0;0.0;, + 1.0;0.0;, + 0.361;0.638;, + 1.0;1.0;, + 0.361;0.362;, + 0.5;0.304;, + 1.0;1.0;, + 0.373;0.352;, + 0.635;0.627;, + 0.037;0.012;, + 0.7;0.494;, + 0.504;0.298;, + 0.368;0.633;, + 0.976;0.012;, + 0.645;0.362;, + 0.7;0.494;, + 0.988;0.025;, + 0.98;0.971;, + 0.366;0.643;, + 0.988;0.012;, + 0.36;0.352;, + 0.492;0.297;, + 0.646;0.362;, + 0.0;0.0;, + // Gatling_fin_3 + 0.991;0.495;, + 0.5;1.0;, + 0.989;0.011;, + 1.0;0.0;, + 0.125;1.0;, + 0.989;0.967;, + 0.625;0.0;, + 0.125;0.0;, + 0.75;1.0;, + 0.25;1.0;, + 0.25;0.0;, + 0.75;0.0;, + 0.375;1.0;, + 0.875;1.0;, + 0.875;0.0;, + 0.375;0.0;, + 0.5;0.5;, + 0.625;0.5;, + 1.0;0.5;, + 0.125;0.5;, + 0.75;0.5;, + 0.875;0.5;, + 0.25;0.5;, + 0.375;0.5;, + 0.5;0.75;, + 0.625;0.75;, + 1.0;0.75;, + 0.125;0.75;, + 0.75;0.75;, + 0.875;0.75;, + 0.25;0.75;, + 0.375;0.75;, + 1.0;1.0;, + 1.0;1.0;, + 1.0;0.0;, + 0.361;0.638;, + 0.304;0.5;, + 0.361;0.361;, + 1.0;1.0;, + 1.0;1.0;, + 0.0;0.0;, + 0.0;0.0;, + 1.0;1.0;, + 0.0;0.0;, + 1.0;0.0;, + 0.361;0.362;, + 0.0;0.0;, + 1.0;1.0;, + 0.988;0.012;, + 0.635;0.627;, + 0.299;0.5;, + 0.7;0.494;, + 0.504;0.298;, + 0.368;0.633;, + 0.976;0.012;, + 0.637;0.354;, + 0.69;0.495;, + 0.988;0.025;, + 0.98;0.971;, + 0.366;0.643;, + 0.311;0.512;, + 0.36;0.352;, + 0.506;0.299;, + 0.646;0.362;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + // Barrel_11 + 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.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;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.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;, + 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.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;, + // Barrel_1 + 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.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;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.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;, + 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.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;, + // Barrel_13 + 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.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;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.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;, + 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.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;, + // Barrel_14 + 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.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;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.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;, + 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.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;, + // Barrel_12 + 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.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;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.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;, + 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.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;, + // Barrel_16 + 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.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;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.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;, + 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.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;, + // Barrel_17 + 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.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;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.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;, + 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.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;, + // Barrel_15 + 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.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;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.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;, + 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.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;, + // Side_guns + 0.0;0.5;, + 0.5;1.0;, + 1.0;0.0;, + 1.0;1.0;, + 0.125;1.0;, + 0.625;1.0;, + 0.875;0.0;, + 0.25;0.0;, + 0.146;0.854;, + 0.25;1.0;, + 0.375;0.0;, + 0.5;0.0;, + 0.375;1.0;, + 0.5;0.5;, + 0.625;0.0;, + 0.75;0.0;, + 0.125;0.008;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.008;, + 0.0;0.0;, + 0.5;1.0;, + 0.854;0.146;, + 0.5;0.5;, + 0.146;0.854;, + 0.5;0.0;, + 0.146;0.146;, + 0.854;0.854;, + 0.146;0.854;, + 0.0;1.0;, + 0.375;0.008;, + 0.875;0.008;, + 0.625;0.008;, + 0.5;0.008;, + 0.875;0.008;, + 0.0;0.0;, + 0.75;0.008;, + 0.125;0.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.0;0.5;, + 0.5;1.0;, + 1.0;0.0;, + 1.0;1.0;, + 0.125;1.0;, + 0.625;1.0;, + 0.875;0.0;, + 0.25;0.0;, + 0.146;0.854;, + 0.25;1.0;, + 0.375;0.0;, + 0.5;0.0;, + 0.375;1.0;, + 0.5;0.5;, + 0.625;0.0;, + 0.75;0.0;, + 0.125;0.008;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.008;, + 0.0;0.0;, + 0.5;1.0;, + 0.854;0.146;, + 0.5;0.5;, + 0.146;0.854;, + 0.5;0.0;, + 0.146;0.146;, + 0.854;0.854;, + 0.146;0.854;, + 0.0;1.0;, + 0.375;0.008;, + 0.875;0.008;, + 0.625;0.008;, + 0.5;0.008;, + 0.875;0.008;, + 0.0;0.0;, + 0.75;0.008;, + 0.125;0.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + 0.008;1.0;, + // Frontal_aux_gun + 1.0;0.942;, + 0.5;0.942;, + 0.5;0.046;, + 1.0;0.046;, + 0.125;0.942;, + 0.625;0.942;, + 0.626;0.046;, + 0.124;0.046;, + 0.75;0.942;, + 0.25;0.942;, + 0.751;0.046;, + 0.249;0.046;, + 0.375;0.942;, + 0.875;0.942;, + 0.374;0.046;, + 0.876;0.046;, + 0.5;0.04;, + 0.0;0.04;, + 0.626;0.04;, + 0.124;0.04;, + 0.751;0.04;, + 0.249;0.04;, + 0.374;0.04;, + 0.876;0.04;, + 0.5;0.066;, + 1.0;0.066;, + 0.625;0.066;, + 0.125;0.066;, + 0.75;0.066;, + 0.25;0.066;, + 0.375;0.066;, + 0.875;0.066;, + 1.0;0.063;, + 0.125;0.063;, + 0.625;0.063;, + 0.75;0.063;, + 0.25;0.063;, + 0.375;0.063;, + 0.875;0.063;, + 0.5;0.063;, + 0.5;0.055;, + 0.625;0.055;, + 0.75;0.055;, + 0.875;0.055;, + 1.0;0.055;, + 0.125;0.055;, + 0.25;0.055;, + 0.375;0.055;, + 1.0;0.732;, + 1.0;0.688;, + 1.0;0.308;, + 1.0;0.274;, + 0.018;0.723;, + 0.986;0.693;, + 0.988;0.304;, + 1.014;0.28;, + 0.978;0.706;, + 0.022;0.706;, + 0.982;0.293;, + 0.018;0.293;, + 1.014;0.693;, + 0.982;0.723;, + 0.012;0.304;, + 0.986;0.28;, + 1.0;0.306;, + 1.0;0.276;, + 0.99;0.302;, + 0.012;0.281;, + 0.985;0.293;, + 0.015;0.293;, + 1.01;0.302;, + 0.988;0.281;, + 1.0;0.347;, + 1.0;0.312;, + 0.987;0.343;, + 1.015;0.319;, + 0.98;0.332;, + 0.02;0.332;, + 0.013;0.343;, + 0.985;0.319;, + 1.0;0.28;, + 0.018;0.288;, + 0.986;0.318;, + 0.978;0.305;, + 0.022;0.305;, + 1.014;0.318;, + 0.982;0.288;, + 1.0;0.323;, + 1.0;0.32;, + 0.987;0.316;, + 0.98;0.304;, + 0.985;0.29;, + 1.0;0.283;, + 1.015;0.29;, + 0.02;0.304;, + 0.013;0.316;, + // Jet + 0.199;0.796;, + 0.0;0.0;, + 0.452;0.296;, + 0.529;0.296;, + 0.389;0.792;, + 0.0;0.0;, + 0.448;0.304;, + 0.52;0.335;, + 0.385;0.852;, + 0.0;0.0;, + 0.437;0.312;, + 0.496;0.369;, + 0.363;0.91;, + 0.0;0.0;, + 0.419;0.318;, + 0.461;0.395;, + 0.322;0.962;, + 0.0;0.0;, + 0.398;0.321;, + 0.419;0.411;, + 0.26;0.987;, + 0.0;0.0;, + 0.374;0.323;, + 0.374;0.417;, + 0.198;0.991;, + 0.0;0.0;, + 0.35;0.321;, + 0.329;0.411;, + 0.137;0.977;, + 0.0;0.0;, + 0.329;0.318;, + 0.287;0.395;, + 0.086;0.947;, + 0.0;0.0;, + 0.311;0.312;, + 0.252;0.369;, + 0.046;0.905;, + 0.0;0.0;, + 0.3;0.304;, + 0.228;0.335;, + 0.02;0.853;, + 0.0;0.0;, + 0.296;0.296;, + 0.219;0.296;, + 0.009;0.796;, + 0.0;0.0;, + 0.3;0.288;, + 0.228;0.257;, + 0.014;0.737;, + 0.0;0.0;, + 0.311;0.28;, + 0.252;0.223;, + 0.038;0.679;, + 0.0;0.0;, + 0.329;0.274;, + 0.287;0.197;, + 0.079;0.628;, + 0.0;0.0;, + 0.35;0.271;, + 0.329;0.181;, + 0.14;0.605;, + 0.0;0.0;, + 0.374;0.269;, + 0.374;0.175;, + 0.202;0.601;, + 0.0;0.0;, + 0.398;0.271;, + 0.419;0.181;, + 0.259;0.614;, + 0.0;0.0;, + 0.419;0.274;, + 0.461;0.197;, + 0.31;0.643;, + 0.0;0.0;, + 0.437;0.28;, + 0.496;0.223;, + 0.35;0.684;, + 0.0;0.0;, + 0.448;0.288;, + 0.52;0.257;, + 0.377;0.735;, + 0.314;0.795;, + 0.31;0.832;, + 0.295;0.866;, + 0.27;0.893;, + 0.237;0.909;, + 0.203;0.913;, + 0.162;0.904;, + 0.132;0.888;, + 0.107;0.863;, + 0.09;0.83;, + 0.084;0.794;, + 0.089;0.757;, + 0.105;0.723;, + 0.13;0.697;, + 0.163;0.682;, + 0.199;0.678;, + 0.233;0.684;, + 0.264;0.701;, + 0.29;0.726;, + 0.307;0.759;, + 0.239;0.796;, + 0.237;0.81;, + 0.231;0.822;, + 0.222;0.832;, + 0.211;0.837;, + 0.198;0.839;, + 0.758;0.764;, + 0.176;0.831;, + 0.167;0.821;, + 0.161;0.809;, + 0.158;0.795;, + 0.16;0.781;, + 0.166;0.769;, + 0.175;0.76;, + 0.186;0.754;, + 0.198;0.752;, + 0.21;0.755;, + 0.222;0.76;, + 0.231;0.77;, + 0.237;0.782;, + 0.199;0.796;, + 0.452;0.296;, + 0.529;0.296;, + 0.389;0.792;, + 0.448;0.304;, + 0.52;0.335;, + 0.385;0.852;, + 0.437;0.312;, + 0.496;0.369;, + 0.363;0.91;, + 0.419;0.318;, + 0.461;0.395;, + 0.322;0.962;, + 0.398;0.321;, + 0.419;0.411;, + 0.26;0.987;, + 0.374;0.323;, + 0.374;0.417;, + 0.198;0.991;, + 0.35;0.321;, + 0.329;0.411;, + 0.137;0.977;, + 0.329;0.318;, + 0.287;0.395;, + 0.086;0.947;, + 0.311;0.312;, + 0.252;0.369;, + 0.046;0.905;, + 0.3;0.304;, + 0.228;0.335;, + 0.02;0.853;, + 0.296;0.296;, + 0.219;0.296;, + 0.009;0.796;, + 0.3;0.288;, + 0.228;0.257;, + 0.014;0.737;, + 0.311;0.28;, + 0.252;0.223;, + 0.038;0.679;, + 0.329;0.274;, + 0.287;0.197;, + 0.079;0.628;, + 0.35;0.271;, + 0.329;0.181;, + 0.14;0.605;, + 0.374;0.269;, + 0.374;0.175;, + 0.202;0.601;, + 0.398;0.271;, + 0.419;0.181;, + 0.259;0.614;, + 0.419;0.274;, + 0.461;0.197;, + 0.31;0.643;, + 0.437;0.28;, + 0.496;0.223;, + 0.35;0.684;, + 0.448;0.288;, + 0.52;0.257;, + 0.377;0.735;, + 0.314;0.795;, + 0.31;0.832;, + 0.295;0.866;, + 0.27;0.893;, + 0.237;0.909;, + 0.203;0.913;, + 0.162;0.904;, + 0.132;0.888;, + 0.107;0.863;, + 0.09;0.83;, + 0.084;0.794;, + 0.089;0.757;, + 0.105;0.723;, + 0.13;0.697;, + 0.163;0.682;, + 0.199;0.678;, + 0.233;0.684;, + 0.264;0.701;, + 0.29;0.726;, + 0.307;0.759;, + 0.239;0.796;, + 0.237;0.81;, + 0.231;0.822;, + 0.222;0.832;, + 0.211;0.837;, + 0.198;0.839;, + 0.758;0.764;, + 0.176;0.831;, + 0.167;0.821;, + 0.161;0.809;, + 0.158;0.795;, + 0.16;0.781;, + 0.166;0.769;, + 0.175;0.76;, + 0.186;0.754;, + 0.198;0.752;, + 0.21;0.755;, + 0.222;0.76;, + 0.231;0.77;, + 0.237;0.782;, + // Chassis + 0.222;0.87;, + 0.239;0.867;, + 0.287;0.848;, + 0.319;0.809;, + 0.228;0.895;, + 0.249;0.895;, + 0.324;0.891;, + 0.353;0.853;, + 0.371;0.833;, + 0.223;0.914;, + 0.249;0.935;, + 0.365;0.884;, + 0.384;0.853;, + 0.386;0.837;, + 0.213;0.928;, + 0.402;0.87;, + 0.405;0.847;, + 0.405;0.836;, + 0.362;0.819;, + 0.405;0.668;, + 0.447;0.644;, + 0.405;0.476;, + 0.447;0.318;, + 0.405;0.338;, + 0.447;0.229;, + 0.25;0.303;, + 0.38;0.303;, + 0.405;0.096;, + 0.552;0.324;, + 0.525;0.228;, + 0.129;0.183;, + 0.178;0.2;, + 0.396;0.319;, + 0.513;0.651;, + 0.335;0.163;, + 0.186;0.208;, + 0.489;0.111;, + 0.198;0.324;, + 0.283;0.171;, + 0.598;0.146;, + 0.62;0.079;, + 0.202;0.109;, + 0.04;0.018;, + 0.397;0.135;, + 0.204;0.327;, + 0.242;0.321;, + 0.611;0.62;, + 0.137;0.45;, + 0.195;0.44;, + 0.246;0.463;, + 0.448;0.861;, + 0.164;0.71;, + 0.224;0.695;, + 0.271;0.691;, + 0.317;0.68;, + 0.476;0.861;, + 0.213;0.814;, + 0.263;0.792;, + 0.288;0.73;, + 0.344;0.679;, + 0.29;0.476;, + 0.288;0.324;, + 0.383;0.669;, + 0.358;0.476;, + 0.345;0.321;, + 0.606;0.322;, + 0.614;0.577;, + 0.448;0.975;, + 0.076;0.455;, + 0.63;0.232;, + 0.08;0.17;, + 0.398;0.049;, + 0.024;0.215;, + 0.152;0.316;, + 0.011;0.234;, + 0.137;0.411;, + 0.673;0.296;, + 0.672;0.534;, + 0.041;0.413;, + 0.044;0.181;, + 0.02;0.237;, + 0.052;0.253;, + 0.066;0.408;, + 0.059;0.199;, + 0.098;0.218;, + 0.383;0.06;, + 0.515;0.146;, + 0.287;0.307;, + 0.067;0.26;, + 0.081;0.406;, + 0.073;0.246;, + 0.028;0.226;, + 0.142;0.237;, + 0.076;0.251;, + 0.031;0.418;, + 0.134;0.23;, + 0.716;0.169;, + 0.396;0.097;, + 0.34;0.307;, + 0.361;0.064;, + 0.281;0.066;, + 0.333;0.067;, + 0.377;0.113;, + 0.374;0.21;, + 0.336;0.217;, + 0.336;0.119;, + 0.248;0.226;, + 0.24;0.149;, + 0.28;0.13;, + 0.286;0.222;, + 0.405;0.087;, + 0.247;0.174;, + 0.373;0.156;, + 0.447;0.1;, + 0.401;0.079;, + 0.405;0.194;, + 0.397;0.197;, + 0.405;0.132;, + 0.94;0.186;, + 0.852;0.217;, + 0.939;0.144;, + 0.865;0.206;, + 0.884;0.068;, + 0.938;0.041;, + 0.447;0.43;, + 0.55;0.424;, + 0.931;0.185;, + 0.931;0.21;, + 0.931;0.143;, + 0.872;0.207;, + 0.892;0.07;, + 0.895;0.045;, + 0.2;0.832;, + 0.447;0.74;, + 0.497;0.103;, + 0.768;0.198;, + 0.613;0.082;, + 0.822;0.151;, + 0.494;0.021;, + 0.38;0.055;, + 0.515;0.138;, + 0.357;0.056;, + 0.298;0.058;, + 0.702;0.037;, + 0.744;0.121;, + 0.707;0.131;, + 0.718;0.123;, + 0.763;0.159;, + 0.706;0.158;, + 0.105;0.085;, + 0.105;0.027;, + 0.098;0.018;, + 0.447;0.556;, + 0.476;0.978;, + 0.533;0.575;, + 0.191;0.571;, + 0.155;0.634;, + 0.542;0.738;, + 0.48;0.744;, + 0.278;0.554;, + 0.321;0.559;, + 0.365;0.557;, + 0.405;0.555;, + 0.605;0.424;, + 0.23;0.553;, + 0.334;0.726;, + 0.346;0.757;, + 0.48;0.926;, + 0.186;0.762;, + 0.238;0.742;, + 0.354;0.787;, + 0.304;0.772;, + 0.331;0.837;, + 0.448;0.917;, + 0.382;0.784;, + 0.405;0.689;, + 0.389;0.807;, + 0.405;0.809;, + 0.377;0.748;, + 0.382;0.719;, + 0.395;0.698;, + 0.385;0.783;, + 0.381;0.748;, + 0.386;0.719;, + 0.399;0.7;, + 0.408;0.692;, + 0.392;0.804;, + 0.405;0.806;, + 0.384;0.784;, + 0.406;0.692;, + 0.39;0.805;, + 0.405;0.808;, + 0.379;0.748;, + 0.384;0.719;, + 0.397;0.699;, + 0.581;0.635;, + 0.181;0.898;, + 0.202;0.883;, + 0.463;0.921;, + 0.492;0.875;, + 0.473;0.97;, + 0.484;0.98;, + 0.134;0.71;, + 0.158;0.777;, + 0.241;0.95;, + 0.294;0.989;, + 0.302;0.876;, + 0.264;0.935;, + 0.15;0.867;, + 0.288;0.966;, + 0.458;0.97;, + 0.222;0.87;, + 0.239;0.867;, + 0.287;0.848;, + 0.319;0.809;, + 0.228;0.895;, + 0.249;0.895;, + 0.324;0.891;, + 0.353;0.853;, + 0.371;0.833;, + 0.223;0.914;, + 0.249;0.935;, + 0.365;0.884;, + 0.384;0.853;, + 0.386;0.837;, + 0.362;0.819;, + 0.25;0.303;, + 0.38;0.303;, + 0.552;0.324;, + 0.525;0.228;, + 0.129;0.183;, + 0.178;0.2;, + 0.396;0.319;, + 0.513;0.651;, + 0.335;0.163;, + 0.186;0.208;, + 0.489;0.111;, + 0.198;0.324;, + 0.283;0.171;, + 0.598;0.146;, + 0.62;0.079;, + 0.202;0.109;, + 0.04;0.018;, + 0.397;0.135;, + 0.204;0.327;, + 0.242;0.321;, + 0.611;0.62;, + 0.137;0.45;, + 0.195;0.44;, + 0.246;0.463;, + 0.164;0.71;, + 0.224;0.695;, + 0.271;0.691;, + 0.317;0.68;, + 0.476;0.861;, + 0.213;0.814;, + 0.263;0.792;, + 0.288;0.73;, + 0.344;0.679;, + 0.29;0.476;, + 0.288;0.324;, + 0.383;0.669;, + 0.358;0.476;, + 0.345;0.321;, + 0.606;0.322;, + 0.614;0.577;, + 0.076;0.455;, + 0.63;0.232;, + 0.08;0.17;, + 0.398;0.049;, + 0.024;0.215;, + 0.152;0.316;, + 0.011;0.234;, + 0.137;0.411;, + 0.673;0.296;, + 0.672;0.534;, + 0.041;0.413;, + 0.044;0.181;, + 0.02;0.237;, + 0.052;0.253;, + 0.066;0.408;, + 0.059;0.199;, + 0.098;0.218;, + 0.383;0.06;, + 0.515;0.146;, + 0.287;0.307;, + 0.067;0.26;, + 0.081;0.406;, + 0.073;0.246;, + 0.028;0.226;, + 0.142;0.237;, + 0.076;0.251;, + 0.031;0.418;, + 0.134;0.23;, + 0.716;0.169;, + 0.396;0.097;, + 0.34;0.307;, + 0.361;0.064;, + 0.281;0.066;, + 0.333;0.067;, + 0.377;0.113;, + 0.374;0.21;, + 0.336;0.217;, + 0.336;0.119;, + 0.248;0.226;, + 0.24;0.149;, + 0.28;0.13;, + 0.286;0.222;, + 0.247;0.174;, + 0.373;0.156;, + 0.401;0.079;, + 0.397;0.197;, + 0.94;0.186;, + 0.852;0.217;, + 0.939;0.144;, + 0.865;0.206;, + 0.884;0.068;, + 0.938;0.041;, + 0.55;0.424;, + 0.931;0.185;, + 0.931;0.21;, + 0.931;0.143;, + 0.872;0.207;, + 0.892;0.07;, + 0.895;0.045;, + 0.2;0.832;, + 0.497;0.103;, + 0.768;0.198;, + 0.613;0.082;, + 0.822;0.151;, + 0.494;0.021;, + 0.38;0.055;, + 0.515;0.138;, + 0.357;0.056;, + 0.298;0.058;, + 0.702;0.037;, + 0.744;0.121;, + 0.707;0.131;, + 0.718;0.123;, + 0.763;0.159;, + 0.706;0.158;, + 0.105;0.085;, + 0.105;0.027;, + 0.098;0.018;, + 0.476;0.978;, + 0.533;0.575;, + 0.191;0.571;, + 0.155;0.634;, + 0.542;0.738;, + 0.48;0.744;, + 0.278;0.554;, + 0.321;0.559;, + 0.365;0.557;, + 0.605;0.424;, + 0.23;0.553;, + 0.334;0.726;, + 0.346;0.757;, + 0.48;0.926;, + 0.186;0.762;, + 0.238;0.742;, + 0.354;0.787;, + 0.304;0.772;, + 0.331;0.837;, + 0.382;0.784;, + 0.389;0.807;, + 0.377;0.748;, + 0.382;0.719;, + 0.395;0.698;, + 0.385;0.783;, + 0.381;0.748;, + 0.386;0.719;, + 0.399;0.7;, + 0.392;0.804;, + 0.384;0.784;, + 0.39;0.805;, + 0.379;0.748;, + 0.384;0.719;, + 0.397;0.699;, + 0.581;0.635;, + 0.202;0.883;, + 0.463;0.921;, + 0.492;0.875;, + 0.473;0.97;, + 0.484;0.98;, + 0.134;0.71;, + 0.158;0.777;, + 0.302;0.876;, + 0.264;0.935;, + 0.288;0.966;, + 0.458;0.97;, + // Bubble + 1.0;1.0;, + 1.0;0.0;, + 1.0;0.0;, + 0.0;0.0;, + 0.544;0.601;, + 0.0;0.0;, + 0.0;1.0;, + 1.0;0.0;, + 0.0;1.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 1.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 0.0;1.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.0;0.0;, + 0.0;0.0;, + 0.0;0.0;, + 1.0;1.0;, + 1.0;0.0;, + 0.544;0.601;, + 0.0;0.0;, + 0.0;1.0;, + 0.0;1.0;, + 1.0;0.0;, + 0.0;0.0;; + } + MeshMaterialList { + 7; + 3000; + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4; + + Material C4DMAT_NONE { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + Material C4DMAT_metal_rough_gray { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + + Material C4DMAT_Tryska { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + + Material C4DMAT_Hull_-_metal { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + + Material C4DMAT_Okno_kokpitu { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + + Material C4DMAT_Metal { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + + Material C4DMAT_Turret_base { + 1.0;1.0;1.0;1.0;; + 1.0;; + 1.0;1.0;1.0;; + 0.0;0.0;0.0;; + + EffectInstance { + "/materials/solid_bump.xml"; + } + } + + } +} + +} \ No newline at end of file diff --git a/include/assertion.h b/include/assertion.h new file mode 100644 index 0000000..70dd1e6 --- /dev/null +++ b/include/assertion.h @@ -0,0 +1,51 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file assertion.h + * + * Assertion macros. + */ + +#pragma once + +/* + * Assertion macros + */ + +#ifdef DEBUG + +#include "platform.h" + +// assert, which invokes a break point +# ifdef PLATFORM_MSVC +# define BREAK_ASSERT(x) if ((x) == false) __asm{int 3}; +# else /* PLATFORM_MSVC */ +# define BREAK_ASSERT(x) if ((x) == false) asm("int $0x3"); +# endif /* PLATFORM_MSVC */ + +// debug assert +# include +# define DEBUG_ASSERT(x) assert(x) + +#else /* DEBUG */ + +# define BREAK_ASSERT(x) +# define DEBUG_ASSERT(x) + +#endif /* DEBUG */ diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..d57cc38 --- /dev/null +++ b/include/common.h @@ -0,0 +1,35 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file common.h + * + * Common includes. + */ + +#pragma once + +#include "platform.h" +#include "types.h" +#include "assertion.h" +#include "exception.h" + +#include "config.h" + +#include "stdtypes.h" +#include "vfs/logfile.h" diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..eaab4e8 --- /dev/null +++ b/include/config.h @@ -0,0 +1,36 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file config.h + * + * Tweakable configuration options. + */ + +#pragma once + +#define FONT_FORCE_AUTOHINT + +#ifdef DEBUG + +# define LOG_RESOURCES +// # define LOG_SINGLETONS + +# define MEM_MANAGER_ON + +#endif /* DEBUG */ diff --git a/include/core/application.h b/include/core/application.h new file mode 100644 index 0000000..2fd5f22 --- /dev/null +++ b/include/core/application.h @@ -0,0 +1,53 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file application.h + * + * blahblah + * + */ + +#pragma once + +#include "core/timer.h" + +namespace tre { + + class VirtualMachine; + + class Application { + public: + Timer timer; + bool running; + + public: + Application(); + virtual ~Application(); + + virtual void Run(void) = 0; + + void Quit(void) {running = false;} + + VirtualMachine * GetScriptVM(void) {return scriptVM_;} + + protected: + VirtualMachine * scriptVM_; + }; + +} diff --git a/include/core/client/display.h b/include/core/client/display.h new file mode 100644 index 0000000..239f5f8 --- /dev/null +++ b/include/core/client/display.h @@ -0,0 +1,67 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file display.h + * + * Ble. + */ + +#pragma once + +#include +#include + +#include "types.h" + +namespace tre { + + struct DisplayInfo { + uint width; + uint height; + uint bpp; + bool fullscreen; + bool stereo; + }; + + typedef std::vector DInfoVector; + + class Display { + public: + Display(); + + void Init(void); + + void SetDisplayMode(const DisplayInfo & info); + + const std::string GetDriverName(void) const; + const DisplayInfo GetDisplayInfo(void) const; + const DInfoVector ListModes(void) const; + + private: + bool fullscreen_; + bool stereo_; + }; + + inline Display & sDisplay(void) + { + static Display r; + return r; + } + +} diff --git a/include/core/conf_core.h b/include/core/conf_core.h new file mode 100644 index 0000000..ef84085 --- /dev/null +++ b/include/core/conf_core.h @@ -0,0 +1,31 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file conf_core.h + * + * Ble. + */ + +#pragma once + +namespace tre { + + void InitCoreConf(TiXmlElement & root); + +} diff --git a/include/core/init_sdl.cpp b/include/core/init_sdl.cpp new file mode 100644 index 0000000..9f28cb2 --- /dev/null +++ b/include/core/init_sdl.cpp @@ -0,0 +1,44 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file init_basic.cpp + * + * blahblah + */ + +#include + +namespace { + + class InitSDL { + public: + InitSDL() + { + SDL_Init(0); + } + + ~InitSDL() + { + SDL_Quit(); + } + }; + + InitSDL sInitSDL; + +} diff --git a/include/core/script_core.h b/include/core/script_core.h new file mode 100644 index 0000000..1e74fb9 --- /dev/null +++ b/include/core/script_core.h @@ -0,0 +1,39 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file script_core.h + * + * Ble. + */ + +#pragma once + +struct lua_State; + +namespace tre { + + class CoreInitializer { + public: + typedef lua_State * first_argument_type; + typedef void result_type; + + void operator () (lua_State * L) const; + }; + +} diff --git a/include/core/timer.h b/include/core/timer.h new file mode 100644 index 0000000..fe57730 --- /dev/null +++ b/include/core/timer.h @@ -0,0 +1,75 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file timer.h + * + * blabla + */ + +#pragma once + +#include "assertion.h" + +#include "cpair.h" + +#include +#include + +#include "types.h" + +namespace tre { + + class Timer { + public: + static uint32 GetSystemTime(void); + + public: + typedef boost::function TimerAction; + + public: + float mod; + + public: + Timer(); + + void UpdateTime(void); + uint GetTime(void) {return time_;} + + void Start(void); + void Stop(void); + bool IsRunning(void) {return running_;} + + // returns pointer as an id + const TimerAction * ScheduleAction(uint ms, const TimerAction & act); + bool RemoveAction(const TimerAction * act); + + private: + typedef cpair ActionPair; + typedef std::deque ActionQueue; + + private: + uint lastTime_; // last snapshot + uint time_; + + bool running_; + + ActionQueue actions_; + }; + +} diff --git a/include/core/vmachine.h b/include/core/vmachine.h new file mode 100644 index 0000000..6a513f5 --- /dev/null +++ b/include/core/vmachine.h @@ -0,0 +1,65 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file vmachine.h + * + * blahblahblah + * + */ + +#pragma once + +#include +#include + +#include "luabind/luabind.hpp" + +struct lua_State; + +namespace tre { + + class Application; + + typedef boost::function ModuleInit; + + class VirtualMachine { + public: + VirtualMachine(bool libs=true); + ~VirtualMachine(); + + template + void InitModule(const T & init) {init(luaState_);} + + bool RunFile(const std::string & filename); + bool RunString(const std::string & str); + bool RunGlobalFunction(const std::string & str, luabind::object *arg=NULL); + + template + const luabind::object WrapObject(T * obj) + { + return luabind::object(luaState_, obj); + } + + const luabind::object CompileScriptChunk + (const std::string & chunk, const std::string & name); + + private: + lua_State * luaState_; + }; +} diff --git a/include/cpair.h b/include/cpair.h new file mode 100644 index 0000000..eb56d56 --- /dev/null +++ b/include/cpair.h @@ -0,0 +1,114 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file cpair.h + * + * Comparable pair classes, based on SGI implementation of std::pair class. + */ + +#pragma once + +#include + +template +class cpair { + public: + typedef T first_type; + typedef U second_type; + + public: + T first; + U second; + + public: + // constructors + cpair() : first(), second() {} + cpair(const T & a, const U & b) : first(a), second(b) {} + + template + cpair(const cpair & p) : first(p.first), second(p.second) {} + + // also include copy constructors for equivalent std::pair + template + cpair(const std::pair & p) : first(p.first), second(p.second) {} +}; + +// operator == +template +inline bool operator == (const cpair & l, const cpair & r) +{ + return l.first == r.first && l.second == r.second; +} + +template +inline bool operator == (const cpair & l, const std::pair & r) +{ + return l.first == r.first && l.second == r.second; +} + +template +inline bool operator == (const std::pair & l, const cpair & r) +{ + return l.first == r.first && l.second == r.second; +} + +// operator != +template +inline bool operator != (const cpair & l, const cpair & r) +{ + return !(l == r); +} + +template +inline bool operator != (const cpair & l, const std::pair & r) +{ + return !(l == r); +} + +template +inline bool operator != (const std::pair & l, const cpair & r) +{ + return !(l == r); +} + +// operator < +template +inline bool operator < (const cpair & l, const cpair & r) +{ + return l.first < r.first; +} + +template +inline bool operator < (const T & l, const cpair & r) +{ + return l < r.first; +} + +template +inline bool operator < (const cpair & l, const T & r) +{ + return l.first < r; +} + +// A convenience wrapper for creating a pair from two objects. +// template +// inline cpair make_cpair(T l, U r) +// { +// return cpair(l, r); +// } diff --git a/include/exception.h b/include/exception.h new file mode 100644 index 0000000..e6dc2ef --- /dev/null +++ b/include/exception.h @@ -0,0 +1,58 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file exception.h + * + * This file contains custom exception interface + * + * Contains declaration of the Exception class, derived from std::exception. + */ + +#pragma once + +#include +#include + +/** + * @class Exception + * + * Custom exception class. Used for every non-standard exception. + */ +class Exception : public std::exception { + public: + /** Gets description of the thrown exception. */ + virtual const char * what() const throw() + { + return whatString.c_str(); + } + + /** Copy constructor. */ + Exception(const std::string & str) + { + whatString = str; + } + + virtual ~Exception() throw() + { + } + + private: + /** String briefly describing the cause of the exception. */ + std::string whatString; +}; diff --git a/include/gui/basic.h b/include/gui/basic.h new file mode 100644 index 0000000..85ec5c5 --- /dev/null +++ b/include/gui/basic.h @@ -0,0 +1,255 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file basic.h + * + * Provides collection of basic widgets. + */ + +#pragma once + +#include + +#include "gui.h" +#include "widget.h" +#include "pixmap.h" +#include "richtext.h" +#include "plaintext.h" + +namespace tre { + + /* + * Abstract widgets + */ + class AbstractStatic : virtual public Widget { + public: + AbstractStatic(Gui & g, Widget * p); + + void OnMouseEnter(void) {} + void OnMouseExit(void) {} + }; + + class AbstractButton : virtual public Widget { + public: + // public signals + boost::signal clicked; + + public: + AbstractButton(Gui & g, Widget * p); + + void OnMouseEnter(void); + void OnMouseExit(void); + + private: + // slots + class OnButtonPressed; + class OnButtonReleased; + + // connections + boost::signals::connection buttonCon1; + boost::signals::connection buttonCon2; + }; + + class AbstractEdit : virtual public Widget { + public: + AbstractEdit(Gui & g, Widget * p); + + void OnMouseEnter(void); + + private: + // slots + class OnButtonPressed; + class OnKeyPressed; + + // connections + boost::signals::connection buttonCon; + boost::signals::connection keyCon; + + private: + virtual void InsertCharacter(wchar_t chr) = 0; + }; + + /* + * Static text widget (without frame-like parent) + */ + class StaticText : public Widget { + public: + static Widget * CreateWidget(Gui & gui, Widget * parent); + + public: + PlainText text; + + public: + StaticText(Gui & g, Widget * p); + + void OnMouseEnter(void) {} + void OnMouseExit(void) {} + void OnGuiResize(const Vector2f & scale); + + void Draw(void); + void LoadFromXml(TiXmlElement & root); + }; + + class StaticRichText : public Widget { + public: + static Widget * CreateWidget(Gui & gui, Widget * parent); + + public: + RichText text; + + public: + StaticRichText(Gui & g, Widget * p); + + void OnMouseEnter(void) {} + void OnMouseExit(void) {} + void OnGuiResize(const Vector2f & scale); + + void Draw(void); + void LoadFromXml(TiXmlElement & root); + }; + + /* + * Parent class for most pixmap based widgets + */ + class PixmapWidget : virtual public Widget, private boost::noncopyable { + public: + PixmapWidget(Pixmap * pix) : pixmap_(pix) {} + ~PixmapWidget(); + + void OnGuiResize(const Vector2f & scale); + + void SetSize(const Vector2f & sz); + void Draw(void); + + protected: + Pixmap * pixmap_; + + protected: + void SetState(uint u, WidgetState w); + }; + + /* + * Basic widgets + */ + class Frame : public AbstractStatic, public PixmapWidget { + public: + static Widget * CreateWidget(Gui & gui, Widget * parent); + + public: + Frame(Gui & g, Widget * p); + + void LoadFromXml(TiXmlElement & root); + }; + + class FrameRaised : public Frame { + public: + static Widget * CreateWidget(Gui & gui, Widget * parent); + + public: + FrameRaised(Gui & g, Widget * p) : Frame(g, p) {} + + void LoadFromXml(TiXmlElement & root); + }; + + class FrameSunken : public Frame { + public: + static Widget * CreateWidget(Gui & gui, Widget * parent); + + public: + FrameSunken(Gui & g, Widget * p) : Frame(g, p) {} + + void LoadFromXml(TiXmlElement & root); + }; + +// class StaticLine : public Pixmap2x1L { +// public: +// StaticLine(Gui & g, Widget * p); +// StaticLine(Gui & g, Widget * p, Mesh & pm); +// +// void LoadFromXml(TiXmlElement & root); +// }; + + class PushButton : public AbstractButton, public PixmapWidget { + public: + static Widget * CreateWidget(Gui & gui, Widget * parent); + + public: + PushButton(Gui & g, Widget * p); + + void OnGuiResize(const Vector2f & scale); + + const std::wstring GetCaption(void) const {return caption_.GetText();} + void SetCaption(const std::string & text) {caption_.SetText(text);} + + void SetSize(const Vector2f & sz); + void Draw(void); + void LoadFromXml(TiXmlElement & root); + + private: + class EventBinder; + + private: + PlainText caption_; + }; + +// class EditBox : public Pixmap3x1 { +// public: +// EditBox(Gui & g, Widget * p); +// EditBox(Gui & g, Widget * p, Mesh & pm); +// +// void LoadFromXml(TiXmlElement & root); +// }; +// +// class CheckBox : public Pixmap1x1 { +// public: +// CheckBox(Gui & g, Widget * p); +// CheckBox(Gui & g, Widget * p, Mesh & pm); +// +// void LoadFromXml(TiXmlElement & root); +// }; +// +// class RadioButton : public Pixmap1x1 { +// public: +// RadioButton(Gui & g, Widget * p); +// RadioButton(Gui & g, Widget * p, Mesh & pm); +// +// void LoadFromXml(TiXmlElement & root); +// }; +// +// class DropDownList : public Pixmap3x1 { +// public: +// DropDownList(Gui & g, Widget * p); +// DropDownList(Gui & g, Widget * p, Mesh & pm); +// +// void LoadFromXml(TiXmlElement & root); +// }; +// +// class ListBox : public Widget { +// }; +// +// class TabWidget : public Widget { +// }; +// +// class Window : public Widget { +// }; +// +// class RenderView : public Widget { +// }; + +} diff --git a/include/gui/font/font.h b/include/gui/font/font.h new file mode 100644 index 0000000..1c19f8b --- /dev/null +++ b/include/gui/font/font.h @@ -0,0 +1,117 @@ +// +// Copyright (C) 2007-2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file font.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "types.h" + +#include "math/vector.h" +#include "renderer/texture.h" + +namespace tre { + + struct GlyphInfo { + wchar_t code; + + int bearing_x; + int bearing_y; + uint width; + uint height; + + uint advance_x; + + TexturePtr texture; + Vector4f texCoords; // [left, top, right, bottom] + }; + + struct FaceInfo { + uint height; + int ascender; + int descender; + }; + + typedef uint FontStyle; + const FontStyle fsRegular = 0; + const FontStyle fsBold = 1; + const FontStyle fsItalic = 2; + const FontStyle fsBoldItalic = 3; + const FontStyle fsLast = 4; + + class FontFace; + class Font; + + typedef boost::shared_ptr FontPtr; + typedef boost::weak_ptr FontRef; + + class FontFactory { + public: + const FontPtr CreateInstance(const std::string & name); + + private: + typedef std::tr1::unordered_map FontMap; + + private: + FontMap map_; + }; + + class Font : public boost::noncopyable { + public: + static FontFactory & Factory(void) + { + static FontFactory fac; + return fac; + } + + static const GlyphInfo * GetFillerGlyph(void); + + static const uint defTextSize = 12; + + public: + Font(); + ~Font(); + + const GlyphInfo * GetGlyph(wchar_t chr, FontStyle style=fsRegular); + + int GetKerning(wchar_t chr1, wchar_t chr2, FontStyle style=fsRegular); + + void SetSize(uint size) {size_ = size;} + void SetAntialias(bool on) {aalias_ = on;} + + const FaceInfo GetFaceInfo(FontStyle style=fsRegular); + + void LoadFromXml(const std::string & path); + + private: + FontFace * faces_[fsLast]; + std::string files_[fsLast]; + + bool aalias_; + uint size_; + }; + +} diff --git a/include/gui/gui.h b/include/gui/gui.h new file mode 100644 index 0000000..1b7a3cf --- /dev/null +++ b/include/gui/gui.h @@ -0,0 +1,183 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file gui.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include +#include + +#include "platform.h" + +#ifdef PLATFORM_MSVC +# include +#else /* PLATFORM_MSVC */ +# include +#endif /* PLATFORM_MSVC */ + +#include "math/volumes.h" +#include "input/input.h" + +class TiXmlElement; + +namespace tre { + + class Widget; + class Application; + class Gui; + class GuiSkin; + class Canvas; + class Cursor; + class CursorSet; + + class EventCombiner; + + typedef boost::shared_ptr GuiSkinPtr; + typedef boost::shared_ptr CanvasPtr; + typedef boost::shared_ptr CursorSetPtr; + + typedef boost::shared_ptr GuiPtr; + typedef boost::weak_ptr GuiRef; + + class GuiFactory { + public: + GuiPtr CreateInstance(Application & app, const CanvasPtr & canvas, + const std::string & filename, const std::string & skin); + }; + + class Gui : private boost::noncopyable { + public: + static GuiFactory & Factory(void) + { + static GuiFactory fac; + return fac; + } + + public: + class EventCombiner { + public: + typedef bool result_type; + + template + bool operator () (InputIterator first, InputIterator last) const + { + while(first != last) { + if(*first) + return true; + ++first; + } + return false; + } + }; + + public: + // public signals + boost::signal buttonOn; + boost::signal buttonOff; + boost::signal keyOn; + boost::signal keyOff; + boost::signal mouseMove; + + public: + Gui(Application & app, const CanvasPtr & cnv); + ~Gui(); + + Application & GetApplication(void) {return app_;} + + // size & scale + Vector2f GetSize(void) const {return size_;} + Vector2f GetScaleFactor(void) const; + + void SetCanvas(const CanvasPtr & cnv); + + const GuiSkinPtr & GetSkin(void) const {return skin_;} + const Vector3f GetMousePosition(void) const + {return mousePos_.GetWPosition();}; + + // widget queries + const Widget * GetRootWidget(void) const {return rootWdg_;} + Widget * GetRootWidget(void) {return rootWdg_;} + + const Widget * FindWidget(const std::string & name) const; + Widget * FindWidget(const std::string & name); + + bool RegisterWidget(Widget * wdg, const std::string & name); + void UnregisterWidget(const std::string & name); + + // skin manipulation + bool UseSkin(const std::string & filename); + void ResetSkin(void); + + // cursor manipulation + void ShowCursor(bool on); + void SetCursor(const std::string & name); + + // input handling + void MouseMove(const Vector2f & abs, const Vector2f & rel); + bool ProcessInput(const InputEvent & event); + + // draws recursively the entire gui + void Draw(void); + + void LoadFromFile(const std::string & filename); + +// TODO: drag & drop - StartDrag(dragwidget) + + private: + typedef std::tr1::unordered_map WidgetMap; + + private: + Application & app_; + CanvasPtr canvas_; + + // dimensions & scaling + bool scale_; /// gui scales to fit the canvas, keeping it's proportions + Vector2f size_; + Vector2f scaleBase_; + + // widget templates & cursor set + GuiSkinPtr skin_; + CursorSetPtr cursors_; + + // root widget + Widget * rootWdg_; + + // various states + Widget * lastTop_; + Transformf mousePos_; + + // default 2d camera + PVolume cam_; + + // cursor + const Cursor * actCursor_; + std::string curName_; + bool showCursor_; + + // widget map + WidgetMap wdgRegistry_; + }; + +} diff --git a/include/gui/init_basic.cpp b/include/gui/init_basic.cpp new file mode 100644 index 0000000..470edef --- /dev/null +++ b/include/gui/init_basic.cpp @@ -0,0 +1,61 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file init_basic.cpp + * + * blahblah + */ + +#include "widget.h" +#include "basic.h" + +namespace { + + class InitBasicWidgets { + public: + InitBasicWidgets() + { + tre::Widget::Factory().RegisterClass("Frame", + &tre::Frame::CreateWidget); + tre::Widget::Factory().RegisterClass("FrameRaised", + &tre::FrameRaised::CreateWidget); + tre::Widget::Factory().RegisterClass("FrameSunken", + &tre::FrameSunken::CreateWidget); + tre::Widget::Factory().RegisterClass("PushButton", + &tre::PushButton::CreateWidget); +// tre::Widget::Factory().RegisterClass("EditBox", +// &tre::EditBox::CreateWidget); +// tre::Widget::Factory().RegisterClass("CheckBox", +// &tre::CheckBox::CreateWidget); +// tre::Widget::Factory().RegisterClass("RadioButton", +// &tre::RadioButton::CreateWidget); +// tre::Widget::Factory().RegisterClass("DropDownList", +// &tre::DropDownList::CreateWidget); +// tre::Widget::Factory().RegisterClass("ListBox", +// &tre::ListBox::CreateWidget); + tre::Widget::Factory().RegisterClass("StaticText", + &tre::StaticText::CreateWidget); + tre::Widget::Factory().RegisterClass("StaticRichText", + &tre::StaticRichText::CreateWidget); + } + }; + + InitBasicWidgets sInitBasicWidgets; + +} diff --git a/include/gui/pixmap.h b/include/gui/pixmap.h new file mode 100644 index 0000000..515a697 --- /dev/null +++ b/include/gui/pixmap.h @@ -0,0 +1,144 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file pixmap.h + * + * Ble. + */ + +#pragma once + +#include + +#include "renderer/buffers.h" +#include "renderer/effect.h" + +#include "math/transform.h" +#include "gui/widget.h" + +class TiXmlElement; + +namespace tre { + + class WidgetTemplate; + + class Pixmap { + public: + Pixmap(Transformf & t, float scale); + ~Pixmap(); + + void SetMap(uint u, WidgetState w); + + void DrawPixmap(void); + virtual void ResizePixmap(const Vector2f & sz) = 0; + + void SetScaleFactor(const Vector2f & scale) {scaleFactor_ = scale;} + + void LoadFromXmlTemplate(TiXmlElement & root, + const GuiSkinPtr & skin, const std::string & name, const Vector2f & sz); + + protected: + // ustate x wstate -> texture maps + TexturePtr maps_[Widget::maxUState][wsLast]; + + // geometry info + AttribBufferSet * attribs_; + IndexBuffer * indices_; + EffectPtr effect_; + EffectVars vars_; + + Vector2f scaleFactor_; + + protected: + virtual void SetUpFromTemplate( + const WidgetTemplate & tmpl, const Vector2f & sz) = 0; + + private: + Transformf & trans_; + + private: + void LoadStateMaps(const WidgetTemplate & tmpl); + }; + + class Pixmap3x3 : public Pixmap { + public: + Pixmap3x3(Transformf & t, float scale) : Pixmap(t, scale) {} + + void ResizePixmap(const Vector2f & sz); + + void SetUpFromTemplate(const WidgetTemplate & tmpl, const Vector2f & sz); + + private: + // padding + float pLeft_; + float pRight_; + float pTop_; + float pBottom_; + }; + + class Pixmap3x1 : public Pixmap { + public: + Pixmap3x1(Transformf & t, float scale) : Pixmap(t, scale) {} + + float GetHeight(void) const {return pHeight_;} + + void ResizePixmap(const Vector2f & sz); + + void SetUpFromTemplate(const WidgetTemplate & tmpl, const Vector2f & sz); + + private: + // padding + float pLeft_; + float pRight_; + float pHeight_; + }; + + class Pixmap2x1L : public Pixmap { + public: + Pixmap2x1L(Transformf & t, float scale) : Pixmap(t, scale) {} + + float GetHeight(void) const {return pHeight_;} + + void ResizePixmap(const Vector2f & sz); + + void SetUpFromTemplate(const WidgetTemplate & tmpl, const Vector2f & sz); + + private: + // padding + float pLeft_; + float pHeight_; + }; + + class Pixmap1x1 : public Pixmap { + public: + Pixmap1x1(Transformf & t, float scale) : Pixmap(t, scale) {} + + float GetHeight(void) const {return pHeight_;} + float GetWidth(void) const {return pWidth_;} + + void ResizePixmap(const Vector2f & sz); + + void SetUpFromTemplate(const WidgetTemplate & tmpl, const Vector2f &); + + private: + float pWidth_; + float pHeight_; + }; + +} diff --git a/include/gui/plaintext.h b/include/gui/plaintext.h new file mode 100644 index 0000000..cc5f5e0 --- /dev/null +++ b/include/gui/plaintext.h @@ -0,0 +1,76 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file plaintext.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "types.h" +#include "math/vector.h" + +#include "text.h" + +namespace tre { + + class PlainText : public Text { + public: + PlainText(); + ~PlainText(); + + void SetStyle(const TextStyle & style); + const TextStyle & GetStyle(void) const {return style_;} + + void SetText(const std::string & text); + void SetText(const std::wstring & text); + + void ClearText(void); + + protected: + void RedrawText(bool reset); + + private: + // structure used for text processing + struct GlyphLine { + GlyphPrepVector glyphs; + int offset; + int baseline; + uint height; + uint width; + }; + + typedef std::vector GLineVector; + + typedef std::vector GlyphVector; + + private: + TextStyle style_; + GlyphVector glyphs_; + + private: + void WriteText(const GLineVector & lines, uint width, uint height); + }; + +} diff --git a/include/gui/richtext.h b/include/gui/richtext.h new file mode 100644 index 0000000..dafb79d --- /dev/null +++ b/include/gui/richtext.h @@ -0,0 +1,264 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file richtext.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "types.h" +#include "math/vector.h" + +#include "text.h" + +class TiXmlElement; + +namespace tre { + + enum StyleSheet { + ssBase = 0, + ssLink, + ssLinkHover, + ssLinkPressed, + ssEmph, + ssLast + }; + + enum CaretTarget { + ctTextStart, + ctTextEnd, + ctLineStart, + ctLineEnd, + ctWordLeft, + ctWordRight, + ctLeft, + ctRight, + ctUp, + ctDown + }; + + class RichText : public Text { + public: + static const uint caretWidth = 3; + + public: + RichText(); + ~RichText(); + + void SetStyleSheet(StyleSheet sheet, const TextStyle & style); + const TextStyle & GetStyleSheet(StyleSheet sheet) const + {return styles_[sheet];} + + void ResetStyles(void); + + void SetStyle(const TextStyle & style); + const TextStyle & GetStyle(void) const {return styles_[ssBase];} + + void SetText(const std::string & text); + void SetText(const std::wstring & text); + + void ClearText(void); + const std::wstring GetText(void) const; + + // auto-format + bool GetWrap(void) const {return wrap_;} + void SetWrap(bool wrap); + + void SetParagraphSpacing(int space); + void SetLineSpacing(int space); + + const std::wstring GetWord(const Vector2f & pos) const; + const std::string GetLink(const Vector2f & pos) const; + + void SetHoverLink(const std::string & id); + void SetPressedLink(const std::string & id); + + void ShowCaret(bool show); + bool IsCaretVisible(void) const {return showCaret_;} + void SetCaretToCursor(const Vector2f & pos); + void MoveCaret(CaretTarget pos); + + protected: + void RedrawText(bool reset); + + /* + * Datatypes for the tree used to store the styled rich text + */ + private: + struct RichNode; + + typedef std::vector GlyphVector; + + struct RichLeaf { + RichNode * parent; + std::wstring text; + GlyphVector glyphs; + TextStyle style; + + RichLeaf() : parent(NULL) {} + RichLeaf(RichNode * p); + + void ResetStyle(void); + }; + + typedef std::list LeavesList; + + struct RichNodeChild { + union { + RichNode * node; + RichLeaf * leaf; + }; + bool isNode; + + RichNodeChild() : node(NULL), isNode(true) {} + RichNodeChild(RichNode * n) : node(n), isNode(true) {} + RichNodeChild(RichLeaf * l) : leaf(l), isNode(false) {} + }; + + typedef std::vector NodeChildVector; + + enum NodeType { + ntPreDef, // TODO: custom styles? extra would contain style name + ntLink, /// the same as ntPreDef, but extra contains link id + ntColour, + ntSize, + ntFontStyle + }; + + struct RichNode { + union { + TextStyle * predef; + float colour[4]; + float size; + FontStyle fstyle; + }; + NodeType type; + + std::string extra; /// depends on the node type (link = id) + + RichNode * parent; + NodeChildVector children; + + ~RichNode(); + }; + + /* + * Datatypes for the look-up table + */ + private: + /// [text chunk, letter number] + typedef std::pair LetterPair; + typedef std::vector LetterPairVector; + + struct Letter { + int start; + uint width; + + LetterPair letter; + + Letter(uint s, uint w, LetterPair p) : start(s), width(w), letter(p) {} + + bool operator < (const Letter & r) const + { + return start < r.start; + } + + friend bool operator < (const Letter & l, int r) + { + return l.start < r; + } + + friend bool operator < (int l, const Letter & r) + { + return l < r.start; + } + }; + + typedef std::vector LetterVector; + + /// letters x [line offset, line height] + typedef std::pair LinePair; + typedef std::vector LineVector; + + class LineLess; + + /* + * Text processing + */ + private: + struct GlyphLine { + GlyphPrepVector glyphs; + LetterPairVector letters; // needed to create the look-up table + int offset; + int baseline; + uint height; + uint width; + uint wspace; // number of spaces on line (for stretching) + HorizAlign align; // line alignment + }; + + typedef std::vector GLineVector; + + /* + * Private attributes + */ + private: + /// predefined styles + TextStyle styles_[ssLast]; + + // auto-format parameters + bool wrap_; /// word wrap + int lineSpace_; /// distance between two lines + int parSpace_; /// distance between two paragraphs + + // style tree + RichNode root_; /// root node of the style tree + LeavesList leaves_; /// list of leaves of the style tree + + LineVector lines_; /// look-up table for position (x,y) based search + + // caret + Vector2u caret_; /// caret position (row, col) in lines_ + bool showCaret_; + + const GlyphInfo * fillerGlyph_; + AttribBufferSet * caretAttribs_; + IndexBuffer * caretIndices_; + EffectVars * caretVars_; + + private: + const LetterPair * GetLetter(const Vector2f & pos) const; + + void ParseText(TiXmlElement & root, RichNode * rnode, bool & prev_spc); + + void RedrawCaret(void); + + void CalcLineHeight(GlyphLine & line); + void WriteText(const GLineVector & lines, uint width, uint height); + void WriteLine(const GlyphPrepVector & glyphs, const LetterPairVector + & letters, int x_off, int y_off, uint ws_fill, uint ws); + }; + +} diff --git a/include/gui/text.h b/include/gui/text.h new file mode 100644 index 0000000..b96cdcd --- /dev/null +++ b/include/gui/text.h @@ -0,0 +1,164 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file text.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include +#include + +#include "types.h" +#include "math/vector.h" +#include "math/matrix.h" + +#include "font/font.h" + +#include "renderer/renderer.h" +#include "renderer/buffers.h" +#include "renderer/effect.h" + +namespace tre { + + struct GlyphInfo; + class Font; + + enum HorizAlign { + haLeft, + haCenter, + haRight, + haStretch + }; + + enum VertAlign { + vaTop, + vaMiddle, + vaBottom + }; + + struct TextStyle { + uint size; + FontStyle fstyle; + Vector4f colour; + + TextStyle() {} + TextStyle(uint s, FontStyle t, const Vector4f & c) + : size(s), fstyle(t), colour(c) {} + }; + + class Text : private boost::noncopyable { + public: + Text(); + virtual ~Text(); + + void SetRect(uint width, uint height); + void SetHAlign(HorizAlign align); + void SetVAlign(VertAlign align); + + void SetFont(const std::string & font); + + void SetEffect(const std::string & fx); + + void SetAntialias(bool on); + void SetScaleFactor(const Vector2f scale); + + virtual void SetStyle(const TextStyle & style) = 0; + virtual const TextStyle & GetStyle(void) const = 0; + + virtual void SetText(const std::string & text) = 0; + virtual void SetText(const std::wstring & text) = 0; + + virtual void ClearText(void) = 0; + virtual const std::wstring GetText(void) const {return text_;} + + const Vector4i & GetTextRect(void) const {return textRect_;} + + void SetTransform(const Matrix4x4f * mat); + GeometryBatch & GetGeometry(void) {return batch_;} + + protected: + // structures for text parsing and mesh creation + struct GlyphPrep { + const GlyphInfo * glyph; + TextStyle * style; + int offset; + + GlyphPrep() {} + GlyphPrep(const GlyphInfo * g, TextStyle * ts, int o) + : glyph(g), style(ts), offset(o) {} + }; + + typedef std::vector GlyphPrepVector; + + // geometry + typedef std::pair PagePrepPair; + typedef std::deque PagePrepQueue; + + struct MeshPage { + IndexBuffer * indices; + EffectVars * vars; + + // used for refilling + PagePrepQueue prep; + }; + + typedef std::vector PageVector; + + protected: + FontPtr font_; + + std::wstring text_; + + // determines, whether font will be rendered via blending or alpha testing + bool antialias_; + + // alignment + Vector2u bounds_; + HorizAlign halign_; + VertAlign valign_; + + Vector4i textRect_; // [left, top, right, bottom] + + // scale factor - for matching different resolutions + Vector2f scaleFactor_; + + // render batch related info + EffectPtr effect_; + const Matrix4x4f * trans_; + + GeometryBatch batch_; // pre-built batch + + protected: + virtual void RedrawText(bool reset) = 0; + + void ResetPages(void); + MeshPage & GetPageByTexture(const TexturePtr & texture); + + private: + // geometry information + AttribBufferSet * abuffers_; + PageVector pages_; // pages in texture cache + }; + +} diff --git a/include/gui/widget.h b/include/gui/widget.h new file mode 100644 index 0000000..ede4ed8 --- /dev/null +++ b/include/gui/widget.h @@ -0,0 +1,174 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file widget.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "types.h" + +#include "input/input.h" +#include "math/transform.h" + +// TODO: minimal constraints (perhaps constraints stuct + max) +// for internal use, filled in constructor (according to pixmap) + +class TiXmlElement; + +namespace tre { + + enum WidgetState { + wsNormal = 0, + wsDisabled, + wsPressed, + wsHover, + wsLast + }; + + typedef byte WidgetAnchor; + const WidgetAnchor waNone = 0x00; + const WidgetAnchor waLeft = 0x01; + const WidgetAnchor waTop = 0x02; + const WidgetAnchor waRight = 0x04; + const WidgetAnchor waBottom = 0x08; + const WidgetAnchor waWidth = 0x10; + const WidgetAnchor waHeight = 0x20; + const WidgetAnchor waSize = 0x30; + + class Gui; + class Widget; + + typedef Widget*(CreateWidgetPtr(Gui & gui, Widget * parent)); + + class WidgetFactory { + public: + Widget * CreateInstance(const std::string & filename, Gui & gui, + Widget * parent=NULL); + Widget * CreateInstance(TiXmlElement & root, Gui & gui, + Widget * parent=NULL); + + void RegisterClass(const std::string & classname, CreateWidgetPtr * func); + + private: + typedef std::map FactoryMap; + + private: + FactoryMap ptrMap_; + }; + + class Widget { + public: + static WidgetFactory & Factory(void) + { + static WidgetFactory fac; + return fac; + } + + static const uint maxUState = 3; + + public: + typedef std::vector WdgVector; + + public: + Widget * parent; + WdgVector children; // the last is the topmost + + bool visible; + + public: + Widget(); + virtual ~Widget(); + + // initialization + void Init(Gui & g, Widget * p); + + // widget names + const std::string & GetName(void) const {return name_;} + void SetName(const std::string & nm); + + // position and size + const Vector2f GetPosition(void) const; + const Vector2f GetAbsPosition(void) const; + + void SetPosition(const Vector2f & pos); + + const Vector2f & GetSize(void) const {return size_;} + virtual void SetSize(const Vector2f & sz); + + // child manipulation routines (for export) + Widget * GetChild(uint n); + void AppendChild(Widget * wdg); + void InsertChild(Widget * wdg, uint pos); + + // rect test + bool IsInRegion(const Vector2f & pos) const; + + // state + void Enable(bool state); + void SetUserState(uint state); + + void RaiseChild(Widget * child); + + virtual void Draw(void) = 0; + + // hardcoded internal events + virtual void OnMouseEnter(void); + virtual void OnMouseExit(void); + virtual void OnGuiResize(const Vector2f & scale); + + virtual void LoadFromXml(TiXmlElement & root); + void LoadChildrenFromXml(TiXmlElement & root); + + protected: + // gui this widget belongs to + Gui * gui_; + + // widget id + std::string name_; + + // size & pos + Vector2f size_; + WidgetAnchor anchor_; + + bool floating_; // may move up/down the Z axis (when receiving focus) + + Transformf trans_; + + // state + uint ustate_; + WidgetState wstate_; + + // widget is locked by it's parent when it gets disabled + bool locked_; + WidgetState prevState_; + + protected: + void DrawChildren(void); + + virtual void SetState(uint u, WidgetState w); + }; + +} diff --git a/include/input/input.h b/include/input/input.h new file mode 100644 index 0000000..be3b50d --- /dev/null +++ b/include/input/input.h @@ -0,0 +1,207 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file input.h + * + * Encapsulates chosen input subsystem + */ + +#pragma once + +#include "types.h" +#include "math/vector.h" + +namespace tre { + + /* + * Common input related data types + */ + + typedef unsigned int KeyMod; + const KeyMod kmLShift = 0x0001; + const KeyMod kmRShift = 0x0002; + const KeyMod kmLCtrl = 0x0040; + const KeyMod kmRCtrl = 0x0080; + const KeyMod kmLAlt = 0x0100; + const KeyMod kmRAlt = 0x0200; + const KeyMod kmLMeta = 0x0400; + const KeyMod kmRMeta = 0x0800; + const KeyMod kmNum = 0x1000; + const KeyMod kmCaps = 0x2000; + const KeyMod kmMode = 0x4000; + const KeyMod kmShift = kmLShift | kmRShift; + const KeyMod kmCtrl = kmLCtrl | kmRCtrl; + const KeyMod kmAlt = kmLAlt | kmRAlt; + const KeyMod kmMeta = kmLMeta | kmRMeta; + + // keysymbols for control characters + enum KeySym { + ksNone, + ksEscape, + ks1, ks2, ks3, ks4, ks5, ks6, ks7, ks8, ks9, ks0, + ksMinus, // - on main keyboard + ksEquals, + ksBack, // backspace + ksTab, + ksQ, ksW, ksE, ksR, ksT, ksY, ksU, ksI, ksO, ksP, + ksLBrack, // [ + ksRBrack, // ] + ksReturn, // enter on main keyboard + ksLCtrl, + ksA, ksS, ksD, ksF, ksG, ksH, ksJ, ksK, ksL, + ksSemicol, // semicolon + ksApos, // apostrophe + ksGrave, // accent + ksLShift, + ksBacksl, // backslash + ksZ, ksX, ksC, ksV, ksB, ksN, ksM, + ksComma, + ksPer, // . on main keyboard + ksSlash, // / on main keyboard + ksRShift, + ksKpMul, // * on numeric keypad + ksLMenu, // left alt + ksSpace, + ksCap, // capital + ksF1, ksF2, ksF3, ksF4, ksF5, ksF6, ksF7, ksF8, ksF9, ksF10, + ksNum, // num lock + ksScroll, // scroll lock + ksKp7, ksKp8, ksKp9, + ksKpSub, // - on numeric keypad + ksKp4, ksKp5, ksKp6, + ksKpAdd, // + on numeric keypad + ksKp1, ksKp2, ksKp3, ksKp0, + ksKpDec, // . on numeric keypad + ksOem_102, // < > | on UK/Germany keyboards + ksF11, ksF12, + ksF13, ksF14, ksF15, // (NEC PC98) + ksKana, // (Japanese keyboard) + ksAbnt_C1, // / ? on Portugese (Brazilian) keyboards + ksConvert, // (Japanese keyboard) + ksNoconvert, // (Japanese keyboard) + ksYen, // (Japanese keyboard) + ksAbnt_C2, // Numpad . on Portugese (Brazilian) keyboards + ksKpEquals, // = on numeric keypad (NEC PC98) + ksPrevTrack, // Previous Track (ksCIRCUMFLEX on Japanese keyboard) + ksAt, // (NEC PC98) + ksColon, // (NEC PC98) + ksUnderline, // (NEC PC98) + ksKanji, // (Japanese keyboard) + ksStop, // (NEC PC98) + ksAx, // (Japan AX) + ksUnlabeled, // (J3100) + ksNextTrack, // Next Track + ksKpEnter, // Enter on numeric keypad + ksRCtrl, + ksMute, // Mute + ksCalc, // Calculator + ksPlayPause, // Play / Pause + ksMediaStop, // Media Stop + ksVolDown, // Volume - + ksVolUp, // Volume + + ksWebHome, // Web home + ksKpComma, // , on numeric keypad (NEC PC98) + ksKpDiv, // / on numeric keypad + ksSysRq, + ksRMenu, // right Alt + ksPause, // Pause + ksHome, // Home on arrow keypad + ksUp, // UpArrow on arrow keypad + ksPgUp, // PgUp on arrow keypad + ksLeft, // LeftArrow on arrow keypad + ksRight, // RightArrow on arrow keypad + ksEnd, // End on arrow keypad + ksDown, // DownArrow on arrow keypad + ksPgDown, // PgDn on arrow keypad + ksIns, // Insert on arrow keypad + ksDel, // Delete on arrow keypad + ksLWin, // Left Windows key + ksRWin, // Right Windows key + ksApps, // AppMenu key + ksPower, // System Power + ksSleep, // System Sleep + ksWake, // System Wake + ksWebSearch, // Web Search + ksWebFav, // Web Favorites + ksWebRefresh, // Web Refresh + ksWebStop, // Web Stop + ksWebForward, // Web Forward + ksWebBack, // Web Back + ksMyComp, // My Computer + ksMail, // Mail + ksMediaSelect, // Media Select + // last value + ksLast + }; + + enum EventType { + etNone, + etQuit, + etButtonOn, + etButtonOff, + etKeyOn, + etKeyOff + }; + + struct InputEvent { + EventType type; + + union { + uint button; + + struct { + char chr; + KeySym sym; + } key; + }; + }; + + /* + * Input interface + */ + + class InputDevices; + + class Input { + public: + Input(); + ~Input(); + + const Vector2f GetPosition(void); + const Vector2f GetPositionChange(void); + void SetPosition(const Vector2f & v); + + bool GetButtonState(uint id); + bool GetCharacterState(char chr); + bool GetKeysymState(KeySym sym); + KeyMod GetKeyMod(void); + + void PumpEvents(void); + void DropEvents(void); + + InputEvent GetNextEvent(void); + + private: + class InputInternals; + + InputInternals * internals_; + }; + + Input & sInput(void); +} diff --git a/include/lua/lauxlib.h b/include/lua/lauxlib.h new file mode 100644 index 0000000..d943153 --- /dev/null +++ b/include/lua/lauxlib.h @@ -0,0 +1,171 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + +#include "lua.h" + +#include "vfs/export.h" + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/include/lua/lua.h b/include/lua/lua.h new file mode 100644 index 0000000..5bc97b7 --- /dev/null +++ b/include/lua/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.4 2008/01/03 15:41:15 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.3" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. +* +* 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. +******************************************************************************/ + + +#endif diff --git a/include/lua/luaconf.h b/include/lua/luaconf.h new file mode 100644 index 0000000..cbabaea --- /dev/null +++ b/include/lua/luaconf.h @@ -0,0 +1,744 @@ +/* +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + +/* Terra changes: + * + * POPEN: Support for popen has been removed! The game should not be + * be allowed to call other processes (there's no reason to). + * + * LUA_DIRSEP: "/" for all OS + * + * TMPNAM/MKSTMP: Change into single call of vfs_tmpnam + * + * ISATTY: Also removed, stdin is always virtual terminal. + * + * LUA_DIRSEP + */ + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + +/* Terra settings */ + +#define LUA_ANSI + +#ifdef _MSC_VER +# pragma warning( disable : 4996 ) +/*# define LUA_WIN */ +#else +# define LUA_USE_ULONGJMP +#endif + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#define LUA_DIRSEP "/" + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE VFS_BUFSIZ + +/* }================================================================== */ + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#define LUA_TMPNAMBUFSIZE VFS_L_tmpnam +#define lua_tmpnam(b,e) { e = (vfs_tmpnam(b) == NULL); } + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (VFS_FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif diff --git a/include/lua/lualib.h b/include/lua/lualib.h new file mode 100644 index 0000000..469417f --- /dev/null +++ b/include/lua/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/include/luabind/adopt_policy.hpp b/include/luabind/adopt_policy.hpp new file mode 100644 index 0000000..0d41efd --- /dev/null +++ b/include/luabind/adopt_policy.hpp @@ -0,0 +1,156 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_ADOPT_POLICY_HPP_INCLUDED +#define LUABIND_ADOPT_POLICY_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace luabind { namespace detail +{ + template + struct adopt_pointer + { + typedef adopt_pointer type; + + template + T* apply(lua_State* L, by_pointer, int index) + { + // preconditions: + // lua_isuserdata(L, index); + // getmetatable().__lua_class is true + // object_rep->flags() & object_rep::constant == 0 + + int offset = 0; + object_rep* obj = static_cast(lua_touserdata(L, index)); + assert((obj != 0) && "internal error, please report"); + const class_rep* crep = obj->crep(); + + int steps = implicit_cast(crep, LUABIND_TYPEID(T), offset); + (void)steps; + + assert((steps >= 0) && "adopt_pointer used with type that cannot be converted"); + obj->remove_ownership(); + T* ptr = reinterpret_cast(obj->ptr(offset)); + + return ptr; + } + + template + static int match(lua_State* L, by_pointer, int index) + { + object_rep* obj = is_class_object(L, index); + if (obj == 0) return -1; + // cannot cast a constant object to nonconst + if (obj->flags() & object_rep::constant) return -1; + if (!(obj->flags() & object_rep::owner)) return -1; + int d; + return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d); + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + template<> + struct adopt_pointer + { + typedef adopt_pointer type; + + template + void apply(lua_State* L, T* ptr) + { + if (ptr == 0) + { + lua_pushnil(L); + return; + } + + // if there is a back_reference, then the + // ownership will be removed from the + // back reference and put on the lua stack. + if (luabind::move_back_reference(L, ptr)) + { + object_rep* obj = static_cast(lua_touserdata(L, -1)); + obj->set_flags(obj->flags() | object_rep::owner); + return; + } + + class_registry* registry = class_registry::get_registry(L); + class_rep* crep = registry->find_class(LUABIND_TYPEID(T)); + +/* // create the struct to hold the object + void* obj = lua_newuserdata(L, sizeof(object_rep)); + // we send 0 as destructor since we know it will never be called + new(obj) object_rep(ptr, crep, object_rep::owner, delete_s::apply);*/ + + void* obj; + void* held; + + boost::tie(obj,held) = crep->allocate(L); + + new(obj) object_rep(ptr, crep, object_rep::owner, delete_s::apply); + + // set the meta table + detail::getref(L, crep->metatable_ref()); + lua_setmetatable(L, -2); + } + }; + + template +// struct adopt_policy : converter_policy_tag + struct adopt_policy : conversion_policy + { +// BOOST_STATIC_CONSTANT(int, index = N); + + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_pointers {}; + + template + struct apply + { + typedef luabind::detail::is_nonconst_pointer is_nonconst_p; + typedef typename boost::mpl::if_, only_accepts_nonconst_pointers>::type type; + }; + }; + +}} + +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + adopt(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } +} + +#endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE + diff --git a/include/luabind/back_reference.hpp b/include/luabind/back_reference.hpp new file mode 100755 index 0000000..56036c2 --- /dev/null +++ b/include/luabind/back_reference.hpp @@ -0,0 +1,112 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_BACK_REFERENCE_040510_HPP +#define LUABIND_BACK_REFERENCE_040510_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace luabind { + +namespace detail +{ + namespace mpl = boost::mpl; + + template + wrap_base const* get_back_reference_aux0(T const* p, mpl::true_) + { + return dynamic_cast(p); + } + + template + wrap_base const* get_back_reference_aux0(T const* p, mpl::false_) + { + return 0; + } + + template + wrap_base const* get_back_reference_aux1(T const* p) + { + return get_back_reference_aux0(p, boost::is_polymorphic()); + } + + template + wrap_base const* get_back_reference_aux2(T const& x, mpl::true_) + { + return get_back_reference_aux1(get_pointer(x)); + } + + template + wrap_base const* get_back_reference_aux2(T const& x, mpl::false_) + { + return get_back_reference_aux1(&x); + } + + template + wrap_base const* get_back_reference(T const& x) + { + return detail::get_back_reference_aux2( + x + , has_get_pointer() + ); + } + +} // namespace detail + +template +bool get_back_reference(lua_State* L, T const& x) +{ +#ifndef LUABIND_NO_RTTI + if (wrap_base const* w = detail::get_back_reference(x)) + { + detail::wrap_access::ref(*w).get(L); + return true; + } +#endif + return false; +} + +template +bool move_back_reference(lua_State* L, T const& x) +{ +#ifndef LUABIND_NO_RTTI + if (wrap_base* w = const_cast(detail::get_back_reference(x))) + { + assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); + detail::wrap_access::ref(*w).get(L); + detail::wrap_access::ref(*w).m_strong_ref.reset(); + return true; + } +#endif + return false; +} + +} // namespace luabind + +#endif // LUABIND_BACK_REFERENCE_040510_HPP + diff --git a/include/luabind/back_reference_fwd.hpp b/include/luabind/back_reference_fwd.hpp new file mode 100755 index 0000000..ffe141d --- /dev/null +++ b/include/luabind/back_reference_fwd.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_BACK_REFERENCE_FWD_040510_HPP +#define LUABIND_BACK_REFERENCE_FWD_040510_HPP + +namespace luabind { + +template +bool get_back_reference(lua_State* L, T const& x); + +template +bool move_back_reference(lua_State* L, T const& x); + +} // namespace luabind + +#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP + diff --git a/include/luabind/class.hpp b/include/luabind/class.hpp new file mode 100644 index 0000000..3da0a72 --- /dev/null +++ b/include/luabind/class.hpp @@ -0,0 +1,1462 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CLASS_HPP_INCLUDED +#define LUABIND_CLASS_HPP_INCLUDED + +/* + ISSUES: + ------------------------------------------------------ + + * solved for member functions, not application operator * + if we have a base class that defines a function a derived class must be able to + override that function (not just overload). Right now we just add the other overload + to the overloads list and will probably get an ambiguity. If we want to support this + each method_rep must include a vector of type_info pointers for each parameter. + Operators do not have this problem, since operators always have to have + it's own type as one of the arguments, no ambiguity can occur. Application + operator, on the other hand, would have this problem. + Properties cannot be overloaded, so they should always be overridden. + If this is to work for application operator, we really need to specify if an application + operator is const or not. + + If one class registers two functions with the same name and the same + signature, there's currently no error. The last registered function will + be the one that's used. + How do we know which class registered the function? If the function was + defined by the base class, it is a legal operation, to override it. + we cannot look at the pointer offset, since it always will be zero for one of the bases. + + + + TODO: + ------------------------------------------------------ + + finish smart pointer support + * the adopt policy should not be able to adopt pointers to held_types. This + must be prohibited. + * name_of_type must recognize holder_types and not return "custom" + + document custom policies, custom converters + + store the instance object for policies. + + support the __concat metamethod. This is a bit tricky, since it cannot be + treated as a normal operator. It is a binary operator but we want to use the + __tostring implementation for both arguments. + +*/ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// to remove the 'this' used in initialization list-warning +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4355) +#endif + +namespace boost +{ + + template class shared_ptr; + +} // namespace boost + +namespace luabind +{ + namespace detail + { + struct unspecified {}; + + template struct operator_; + + struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {}; + } + + template + struct class_; + + // TODO: this function will only be invoked if the user hasn't defined a correct overload + // maybe we should have a static assert in here? + inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr* + get_const_holder(...) + { + return 0; + } + + template + boost::shared_ptr* get_const_holder(boost::shared_ptr*) + { + return 0; + } + + namespace detail + { + template + double is_bases_helper(const bases&); + +#ifndef BOOST_MSVC + template + char is_bases_helper(const T&); +#else + char is_bases_helper(...); +#endif + + template + struct is_bases + { + static const T& t; + + BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double)); + typedef boost::mpl::bool_ type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T)) + }; + + double is_not_unspecified_helper(const unspecified*); + char is_not_unspecified_helper(...); + + template + struct is_not_unspecified + { + BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast(0))) == sizeof(char)); + typedef boost::mpl::bool_ type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T)) + }; + + template + struct get_predicate + { + typedef typename boost::mpl::and_< + is_not_unspecified + , Predicate + > type; + }; + + template + struct extract_parameter + { + typedef typename get_predicate::type pred; + typedef typename boost::mpl::find_if::type iterator; + typedef typename boost::mpl::eval_if< + boost::is_same< + iterator + , typename boost::mpl::end::type + > + , boost::mpl::identity + , boost::mpl::deref + >::type type; + }; + + template + struct mem_fn_callback + { + typedef int result_type; + + int operator()(lua_State* L) const + { + return invoke(L, fn, deduce_signature(fn, (Class*)0), Policies()); + } + + mem_fn_callback(Fn fn_) + : fn(fn_) + { + } + + Fn fn; + }; + + template + struct mem_fn_matcher + { + typedef int result_type; + + int operator()(lua_State* L) const + { + return compute_score(L, deduce_signature(fn, (Class*)0), Policies()); + } + + mem_fn_matcher(Fn fn_) + : fn(fn_) + { + } + + Fn fn; + }; + + struct pure_virtual_tag + { + static void precall(lua_State*, index_map const&) {} + static void postcall(lua_State*, index_map const&) {} + }; + + template + struct has_pure_virtual + { + typedef typename boost::mpl::eval_if< + boost::is_same + , boost::mpl::true_ + , has_pure_virtual + >::type type; + + BOOST_STATIC_CONSTANT(bool, value = type::value); + }; + + template<> + struct has_pure_virtual + { + BOOST_STATIC_CONSTANT(bool, value = false); + typedef boost::mpl::bool_ type; + }; + + // prints the types of the values on the stack, in the + // range [start_index, lua_gettop()] + + LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); + + struct LUABIND_API create_class + { + static int stage1(lua_State* L); + static int stage2(lua_State* L); + }; + + // if the class is held by a smart pointer, we need to be able to + // implicitly dereference the pointer when needed. + + template + struct extract_underlying_type + { + static void* extract(void* ptr) + { + HeldT& held_obj = *reinterpret_cast(ptr); + UnderlyingT* underlying_ptr = static_cast(get_pointer(held_obj)); + return underlying_ptr; + } + }; + + template + struct extract_underlying_const_type + { + static const void* extract(void* ptr) + { + HeldT& held_obj = *reinterpret_cast(ptr); + const UnderlyingT* underlying_ptr = static_cast(get_pointer(held_obj)); + return underlying_ptr; + } + }; + + template + struct internal_holder_extractor + { + typedef void*(*extractor_fun)(void*); + + template + static extractor_fun apply(detail::type_) + { + return &detail::extract_underlying_type::extract; + } + }; + + template<> + struct internal_holder_extractor + { + typedef void*(*extractor_fun)(void*); + + template + static extractor_fun apply(detail::type_) + { + return 0; + } + }; + + + template + struct convert_holder + { + static void apply(void* holder, void* target) + { + new(target) ConstHolderType(*reinterpret_cast(holder)); + }; + }; + + + template + struct const_converter + { + typedef void(*converter_fun)(void*, void*); + + template + static converter_fun apply(ConstHolderType*) + { + return &detail::convert_holder::apply; + } + }; + + template<> + struct const_converter + { + typedef void(*converter_fun)(void*, void*); + + template + static converter_fun apply(T*) + { + return 0; + } + }; + + + + + template + struct internal_const_holder_extractor + { + typedef const void*(*extractor_fun)(void*); + + template + static extractor_fun apply(detail::type_) + { + return get_extractor(detail::type_(), get_const_holder(static_cast(0))); + } + private: + template + static extractor_fun get_extractor(detail::type_, ConstHolderType*) + { + return &detail::extract_underlying_const_type::extract; + } + }; + + template<> + struct internal_const_holder_extractor + { + typedef const void*(*extractor_fun)(void*); + + template + static extractor_fun apply(detail::type_) + { + return 0; + } + }; + + + + // this is simply a selector that returns the type_info + // of the held type, or invalid_type_info if we don't have + // a held_type + template + struct internal_holder_type + { + static LUABIND_TYPE_INFO apply() + { + return LUABIND_TYPEID(HeldType); + } + }; + + template<> + struct internal_holder_type + { + static LUABIND_TYPE_INFO apply() + { + return LUABIND_INVALID_TYPE_INFO; + } + }; + + + // this is the actual held_type constructor + template + struct internal_construct_holder + { + static void apply(void* target, void* raw_pointer) + { + new(target) HeldType(static_cast(raw_pointer)); + } + }; + + // this is the actual held_type default constructor + template + struct internal_default_construct_holder + { + static void apply(void* target) + { + new(target) HeldType(); + } + }; + + // the following two functions are the ones that returns + // a pointer to a held_type_constructor, or 0 if there + // is no held_type + template + struct holder_constructor + { + typedef void(*constructor)(void*,void*); + template + static constructor apply(detail::type_) + { + return &internal_construct_holder::apply; + } + }; + + template<> + struct holder_constructor + { + typedef void(*constructor)(void*,void*); + template + static constructor apply(detail::type_) + { + return 0; + } + }; + + // the following two functions are the ones that returns + // a pointer to a const_held_type_constructor, or 0 if there + // is no held_type + template + struct const_holder_constructor + { + typedef void(*constructor)(void*,void*); + template + static constructor apply(detail::type_) + { + return get_const_holder_constructor(detail::type_(), get_const_holder(static_cast(0))); + } + + private: + + template + static constructor get_const_holder_constructor(detail::type_, ConstHolderType*) + { + return &internal_construct_holder::apply; + } + }; + + template<> + struct const_holder_constructor + { + typedef void(*constructor)(void*,void*); + template + static constructor apply(detail::type_) + { + return 0; + } + }; + + + // the following two functions are the ones that returns + // a pointer to a held_type_constructor, or 0 if there + // is no held_type. The holder_type is default constructed + template + struct holder_default_constructor + { + typedef void(*constructor)(void*); + template + static constructor apply(detail::type_) + { + return &internal_default_construct_holder::apply; + } + }; + + template<> + struct holder_default_constructor + { + typedef void(*constructor)(void*); + template + static constructor apply(detail::type_) + { + return 0; + } + }; + + + // the following two functions are the ones that returns + // a pointer to a const_held_type_constructor, or 0 if there + // is no held_type. The constructed held_type is default + // constructed + template + struct const_holder_default_constructor + { + typedef void(*constructor)(void*); + template + static constructor apply(detail::type_) + { + return get_const_holder_default_constructor(detail::type_(), get_const_holder(static_cast(0))); + } + + private: + + template + static constructor get_const_holder_default_constructor(detail::type_, ConstHolderType*) + { + return &internal_default_construct_holder::apply; + } + }; + + template<> + struct const_holder_default_constructor + { + typedef void(*constructor)(void*); + template + static constructor apply(detail::type_) + { + return 0; + } + }; + + + + + // this is a selector that returns the size of the held_type + // or 0 if we don't have a held_type + template + struct internal_holder_size + { + static int apply() { return get_internal_holder_size(get_const_holder(static_cast(0))); } + private: + template + static int get_internal_holder_size(ConstHolderType*) + { + return max_c::value; + } + }; + + template <> + struct internal_holder_size + { + static int apply() { return 0; } + }; + + + // if we have a held type, return the destructor to it + // note the difference. The held_type should only be destructed (not deleted) + // since it's constructed in the lua userdata + template + struct internal_holder_destructor + { + typedef void(*destructor_t)(void*); + template + static destructor_t apply(detail::type_) + { + return &detail::destruct_only_s::apply; + } + }; + + // if we don't have a held type, return the destructor of the raw type + template<> + struct internal_holder_destructor + { + typedef void(*destructor_t)(void*); + template + static destructor_t apply(detail::type_) + { + return &detail::delete_s::apply; + } + }; + + + // if we have a held type, return the destructor to it's const version + template + struct internal_const_holder_destructor + { + typedef void(*destructor_t)(void*); + template + static destructor_t apply(detail::type_) + { + return const_holder_type_destructor(get_const_holder(static_cast(0))); + } + + private: + + template + static destructor_t const_holder_type_destructor(ConstHolderType*) + { + return &detail::destruct_only_s::apply; + } + + }; + + // if we don't have a held type, return the destructor of the raw type + template<> + struct internal_const_holder_destructor + { + typedef void(*destructor_t)(void*); + template + static destructor_t apply(detail::type_) + { + return 0; + } + }; + + + + + template + struct get_holder_alignment + { + static int apply() + { + return internal_alignment(get_const_holder(static_cast(0))); + } + + private: + + template + static int internal_alignment(ConstHolderType*) + { + return detail::max_c::value + , boost::alignment_of::value>::value; + } + }; + + template<> + struct get_holder_alignment + { + static int apply() + { + return 1; + } + }; + + + } // detail + + namespace detail { + + template + struct static_scope + { + static_scope(T& self_) : self(self_) + { + } + + T& operator[](scope s) const + { + self.add_inner_scope(s); + return self; + } + + private: + template void operator,(U const&) const; + void operator=(static_scope const&); + + T& self; + }; + + struct class_registration; + + struct LUABIND_API class_base : scope + { + public: + class_base(char const* name); + + struct base_desc + { + LUABIND_TYPE_INFO type; + int ptr_offset; + }; + + void init( + LUABIND_TYPE_INFO type + , LUABIND_TYPE_INFO holder_type + , LUABIND_TYPE_INFO const_holder_type + , void*(*extractor)(void*) + , const void*(*const_extractor)(void*) + , void(*const_converter)(void*,void*) + , void(*holder_constructor)(void*,void*) + , void(*const_holder_constructor)(void*,void*) + , void(*holder_default_constructor)(void*) + , void(*const_holder_default_constructor)(void*) + , void(*adopt_fun)(void*) + , void(*destructor)(void*) + , void(*const_holder_destructor)(void*) + , int holder_size + , int holder_alignment); + + void add_getter( + const char* name + , const boost::function2& g); + +#ifdef LUABIND_NO_ERROR_CHECKING + void add_setter( + const char* name + , const boost::function2& s); +#else + void add_setter( + const char* name + , const boost::function2& s + , int (*match)(lua_State*, int) + , void (*get_sig_ptr)(lua_State*, std::string&)); +#endif + + void add_base(const base_desc& b); + void add_constructor(const detail::construct_rep::overload_t& o); + +#ifndef LUABIND_NO_ERROR_CHECKING + void add_operator( + int op_id + , int(*func)(lua_State*) + , int(*matcher)(lua_State*) + , void(*sig)(lua_State* + , std::string&) + , int arity); +#else + void add_operator( + int op_id + , int(*func)(lua_State*) + , int(*matcher)(lua_State*) + , int arity); +#endif + + void add_member(registration* member); + void add_default_member(registration* member); + + const char* name() const; + + void add_static_constant(const char* name, int val); + void add_inner_scope(scope& s); + + private: + class_registration* m_registration; + }; + + template + struct adopt_function + { + static void execute(void* p) + { + wrapped_self_t& self = wrap_access::ref( + *static_cast(static_cast(p)) + ); + + LUABIND_CHECK_STACK(self.state()); + + self.get(self.state()); + self.m_strong_ref.set(self.state()); + } + }; + + template + struct memfun_registration : registration + { + memfun_registration(char const* name, F f, Policies const& policies) + : name(name) + , f(f) + , policies(policies) + {} + + void register_(lua_State* L) const + { + object fn = make_function( + L, f, deduce_signature(f, (Class*)0), policies); + + add_overload( + object(from_stack(L, -1)) + , name + , fn + ); + } + + char const* name; + F f; + Policies policies; + }; + + template + struct constructor_registration : registration + { + constructor_registration(Policies const& policies) + : policies(policies) + {} + + void register_(lua_State* L) const + { + object fn = make_function( + L, construct(), Signature(), policies); + + add_overload( + object(from_stack(L, -1)) + , "__init" + , fn + ); + } + + Policies policies; + }; + + template + struct reference_result + : mpl::if_< + mpl::or_, is_primitive > + , T + , typename boost::add_reference::type + > + {}; + + template + struct inject_dependency_policy + : mpl::if_< + is_primitive + , Policies + , policy_cons, Policies> + > + {}; + + template < + class Class + , class Get, class GetPolicies + , class Set = null_type, class SetPolicies = null_type + > + struct property_registration : registration + { + property_registration( + char const* name + , Get const& get + , GetPolicies const& get_policies + , Set const& set = Set() + , SetPolicies const& set_policies = SetPolicies() + ) + : name(name) + , get(get) + , get_policies(get_policies) + , set(set) + , set_policies(set_policies) + {} + + void register_(lua_State* L) const + { + object context(from_stack(L, -1)); + register_aux( + L + , context + , make_get(L, get, boost::is_member_object_pointer()) + , set + ); + } + + template + object make_get(lua_State* L, F const& f, mpl::false_) const + { + return make_function( + L, f, deduce_signature(f, (Class*)0), get_policies); + } + + template + object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const + { + typedef typename reference_result::type result_type; + typedef typename inject_dependency_policy< + D, GetPolicies>::type policies; + + return make_function( + L + , access_member_ptr(mem_ptr) + , mpl::vector2() + , policies() + ); + } + + template + object make_set(lua_State* L, F const& f, mpl::false_) const + { + return make_function( + L, f, deduce_signature(f, (Class*)0), set_policies); + } + + template + object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const + { + return make_function( + L + , access_member_ptr(mem_ptr) + , mpl::vector3() + , set_policies + ); + } + + template + void register_aux( + lua_State* L, object const& context + , object const& get_, S const&) const + { + context[name] = property( + get_ + , make_set(L, set, boost::is_member_object_pointer()) + ); + } + + void register_aux( + lua_State* L, object const& context + , object const& get_, null_type) const + { + context[name] = property(get_); + } + + char const* name; + Get get; + GetPolicies get_policies; + Set set; + SetPolicies set_policies; + }; + + } // namespace detail + + // registers a class in the lua environment + template + struct class_: detail::class_base + { + typedef class_ self_t; + + private: + + template + class_(const class_&); + + public: + + // WrappedType MUST inherit from T + typedef typename detail::extract_parameter< + boost::mpl::vector3 + , boost::is_base_and_derived + , detail::null_type + >::type WrappedType; + + typedef typename detail::extract_parameter< + boost::mpl::list3 + , boost::mpl::not_< + boost::mpl::or_< + boost::mpl::or_< + detail::is_bases + , boost::is_base_and_derived + > + , boost::is_base_and_derived + > + > + , detail::null_type + >::type HeldType; + + // this function generates conversion information + // in the given class_rep structure. It will be able + // to implicitly cast to the given template type + template + void gen_base_info(detail::type_) + { + // fist, make sure the given base class is registered. + // if it's not registered we can't push it's lua table onto + // the stack because it doesn't have a table + + // try to cast this type to the base type and remember + // the pointer offset. For multiple inheritance the pointer + // may change when casting. Since we need to be able to + // cast we need this pointer offset. + // store the information in this class' base class-vector + base_desc base; + base.type = LUABIND_TYPEID(To); + base.ptr_offset = detail::ptr_offset(detail::type_(), detail::type_()); + add_base(base); + } + + void gen_base_info(detail::type_) + {} + +#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_()); + + template + void generate_baseclass_list(detail::type_ >) + { + BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _) + } + +#undef LUABIND_GEN_BASE_INFO + + class_(const char* name): class_base(name), scope(*this) + { +#ifndef NDEBUG + detail::check_link_compatibility(); +#endif + init(); + } + + template + class_& def(const char* name, F f) + { + return this->virtual_def( + name, f, detail::null_type() + , detail::null_type(), boost::mpl::true_()); + } + + // virtual functions + template + class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies) + { + return this->virtual_def( + name, fn, default_or_policies, detail::null_type() + , LUABIND_MSVC_TYPENAME detail::is_policy_cons::type()); + } + + template + class_& def(char const* name, F fn + , Default default_, Policies const& policies) + { + return this->virtual_def( + name, fn, default_ + , policies, boost::mpl::false_()); + } + + template + class_& def(constructor sig) + { + return this->def_constructor(&sig, detail::null_type()); + } + + template + class_& def(constructor sig, const Policies& policies) + { + return this->def_constructor(&sig, policies); + } + + template + class_& property(const char* name, Getter g) + { + this->add_member( + new detail::property_registration( + name, g, detail::null_type())); + return *this; + } + + template + class_& property(const char* name, Getter g, MaybeSetter s) + { + return property_impl( + name, g, s + , boost::mpl::bool_::value>() + ); + } + + template + class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies) + { + typedef detail::property_registration< + T, Getter, GetPolicies, Setter, detail::null_type + > registration_type; + + this->add_member( + new registration_type(name, g, get_policies, s)); + return *this; + } + + template + class_& property( + const char* name + , Getter g, Setter s + , GetPolicies const& get_policies + , SetPolicies const& set_policies) + { + typedef detail::property_registration< + T, Getter, GetPolicies, Setter, SetPolicies + > registration_type; + + this->add_member( + new registration_type(name, g, get_policies, s, set_policies)); + return *this; + } + + template + class_& def_readonly(const char* name, D C::*mem_ptr) + { + typedef detail::property_registration + registration_type; + + this->add_member( + new registration_type(name, mem_ptr, detail::null_type())); + return *this; + } + + template + class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies) + { + typedef detail::property_registration + registration_type; + + this->add_member( + new registration_type(name, mem_ptr, policies)); + return *this; + } + + template + class_& def_readwrite(const char* name, D C::*mem_ptr) + { + typedef detail::property_registration< + T, D C::*, detail::null_type, D C::* + > registration_type; + + this->add_member( + new registration_type( + name, mem_ptr, detail::null_type(), mem_ptr)); + return *this; + } + + template + class_& def_readwrite( + const char* name, D C::*mem_ptr, GetPolicies const& get_policies) + { + typedef detail::property_registration< + T, D C::*, GetPolicies, D C::* + > registration_type; + + this->add_member( + new registration_type( + name, mem_ptr, get_policies, mem_ptr)); + return *this; + } + + template + class_& def_readwrite( + const char* name + , D C::*mem_ptr + , GetPolicies const& get_policies + , SetPolicies const& set_policies + ) + { + typedef detail::property_registration< + T, D C::*, GetPolicies, D C::*, SetPolicies + > registration_type; + + this->add_member( + new registration_type( + name, mem_ptr, get_policies, mem_ptr, set_policies)); + return *this; + } + + template + class_& def(detail::operator_, Policies const& policies) + { + return this->def( + Derived::name() + , &Derived::template apply::execute + , raw(_1) + policies + ); + } + + template + class_& def(detail::operator_) + { + return this->def( + Derived::name() + , &Derived::template apply::execute + , raw(_1) + ); + } + +/* + template + class_& def(detail::operator_, const Policies& policies) + { + typedef typename detail::operator_unwrapper op_type; +#ifndef LUABIND_NO_ERROR_CHECKING + add_operator(op_type::get_id() + , &op_type::execute + , &op_type::match + , &detail::get_signature >::apply + , detail::is_unary(op_type::get_id()) ? 1 : 2); +#else + add_operator(op_type::get_id() + , &op_type::execute + , &op_type::match + , detail::is_unary(op_type::get_id()) ? 1 : 2); +#endif + return *this; + } + + template + class_& def(detail::operator_) + { + typedef typename detail::operator_unwrapper op_type; + +#ifndef LUABIND_NO_ERROR_CHECKING + add_operator(op_type::get_id() + , &op_type::execute + , &op_type::match + , &detail::get_signature >::apply + , detail::is_unary(op_type::get_id()) ? 1 : 2); +#else + add_operator(op_type::get_id() + , &op_type::execute + , &op_type::match + , detail::is_unary(op_type::get_id()) ? 1 : 2); +#endif + return *this; + } + + template + class_& def(detail::application_operator*) + { + typedef detail::application_operator op_t; + + int arity = detail::calc_arity::apply( + Signature(), static_cast(0)); + +#ifndef LUABIND_NO_ERROR_CHECKING + add_operator( + detail::op_call + , &op_t::template apply::execute + , &op_t::match + , &detail::get_signature::apply + , arity + 1); +#else + add_operator( + detail::op_call + , &op_t::template apply::execute + , &op_t::match + , arity + 1); +#endif + + return *this; + } + + template + class_& def(detail::application_operator*, const Policies& policies) + { + typedef detail::application_operator op_t; + + int arity = detail::calc_arity::apply(Signature(), static_cast(0)); + +#ifndef LUABIND_NO_ERROR_CHECKING + add_operator( + detail::op_call + , &op_t::template apply::execute + , &op_t::match + , &detail::get_signature::apply + , arity + 1); +#else + add_operator( + detail::op_call + , &op_t::template apply::execute + , &op_t::match + , arity + 1); +#endif + + return *this; + } +*/ + detail::enum_maker enum_(const char*) + { + return detail::enum_maker(*this); + } + + detail::static_scope scope; + + private: + void operator=(class_ const&); + + void init() + { + typedef typename detail::extract_parameter< + boost::mpl::list3 + , boost::mpl::or_< + detail::is_bases + , boost::is_base_and_derived + > + , no_bases + >::type bases_t; + + typedef typename + boost::mpl::if_ + , bases_t + , bases + >::type Base; + + class_base::init(LUABIND_TYPEID(T) + , detail::internal_holder_type::apply() + , detail::pointee_typeid( + get_const_holder(static_cast(0))) + , detail::internal_holder_extractor::apply(detail::type_()) + , detail::internal_const_holder_extractor::apply(detail::type_()) + , detail::const_converter::apply( + get_const_holder((HeldType*)0)) + , detail::holder_constructor::apply(detail::type_()) + , detail::const_holder_constructor::apply(detail::type_()) + , detail::holder_default_constructor::apply(detail::type_()) + , detail::const_holder_default_constructor::apply(detail::type_()) + , get_adopt_fun((WrappedType*)0) // adopt fun + , detail::internal_holder_destructor::apply(detail::type_()) + , detail::internal_const_holder_destructor::apply(detail::type_()) + , detail::internal_holder_size::apply() + , detail::get_holder_alignment::apply()); + + generate_baseclass_list(detail::type_()); + } + + template + class_& property_impl(const char* name, + Getter g, + GetPolicies policies, + boost::mpl::bool_) + { + this->add_member( + new detail::property_registration( + name, g, policies)); + return *this; + } + + template + class_& property_impl(const char* name, + Getter g, + Setter s, + boost::mpl::bool_) + { + typedef detail::property_registration< + T, Getter, detail::null_type, Setter, detail::null_type + > registration_type; + + this->add_member( + new registration_type(name, g, detail::null_type(), s)); + return *this; + } + + // these handle default implementation of virtual functions + template + class_& virtual_def(char const* name, F const& fn + , Policies const&, detail::null_type, boost::mpl::true_) + { + this->add_member( + new detail::memfun_registration( + name, fn, Policies())); + return *this; + } + + template + class_& virtual_def(char const* name, F const& fn + , Default const& default_, Policies const&, boost::mpl::false_) + { + this->add_member( + new detail::memfun_registration( + name, fn, Policies())); + + this->add_default_member( + new detail::memfun_registration( + name, default_, Policies())); + + return *this; + } + + template + class_& def_constructor(Signature*, Policies const&) + { + typedef typename Signature::signature signature; + + typedef typename boost::mpl::if_< + boost::is_same + , T + , WrappedType + >::type construct_type; + + this->add_member( + new detail::constructor_registration< + construct_type, signature, Policies>( + Policies())); + + this->add_default_member( + new detail::constructor_registration< + construct_type, signature, Policies>( + Policies())); + + return *this; + } + + typedef void(*adopt_fun_t)(void*); + + template + adopt_fun_t get_adopt_fun(W*) + { + return &detail::adopt_function::execute; + } + + adopt_fun_t get_adopt_fun(detail::null_type*) + { + return 0; + } + }; + + detail::policy_cons< + detail::pure_virtual_tag, detail::null_type> const pure_virtual = {}; + + namespace detail + { + inline void ignore_unused_pure_virtual() + { + (void)pure_virtual; + } + } +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // LUABIND_CLASS_HPP_INCLUDED + diff --git a/include/luabind/class_info.hpp b/include/luabind/class_info.hpp new file mode 100755 index 0000000..92c9acf --- /dev/null +++ b/include/luabind/class_info.hpp @@ -0,0 +1,47 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CLASS_INFO_HPP_INCLUDED +#define LUABIND_CLASS_INFO_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind +{ + struct class_info + { + std::string name; + object methods; + object attributes; + }; + + class_info get_class_info(const object&); + + void bind_class_info(lua_State*); +} + +#endif + diff --git a/include/luabind/config.hpp b/include/luabind/config.hpp new file mode 100644 index 0000000..a91ac77 --- /dev/null +++ b/include/luabind/config.hpp @@ -0,0 +1,161 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CONFIG_HPP_INCLUDED +#define LUABIND_CONFIG_HPP_INCLUDED + +#include + +#ifdef BOOST_MSVC + #define LUABIND_ANONYMOUS_FIX static +#else + #define LUABIND_ANONYMOUS_FIX +#endif + +#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) + +#define for if (false) {} else for + +#include + +namespace std +{ + using ::strlen; + using ::strcmp; + using ::type_info; +} + +#endif + + +#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1300) + #define LUABIND_MSVC_TYPENAME +#else + #define LUABIND_MSVC_TYPENAME typename +#endif + +// the maximum number of arguments of functions that's +// registered. Must at least be 2 +#ifndef LUABIND_MAX_ARITY + #define LUABIND_MAX_ARITY 10 +#elif LUABIND_MAX_ARITY <= 1 + #undef LUABIND_MAX_ARITY + #define LUABIND_MAX_ARITY 2 +#endif + +// the maximum number of classes one class +// can derive from +// max bases must at least be 1 +#ifndef LUABIND_MAX_BASES + #define LUABIND_MAX_BASES 4 +#elif LUABIND_MAX_BASES <= 0 + #undef LUABIND_MAX_BASES + #define LUABIND_MAX_BASES 1 +#endif + +// LUABIND_NO_ERROR_CHECKING +// define this to remove all error checks +// this will improve performance and memory +// footprint. +// if it is defined matchers will only be called on +// overloaded functions, functions that's +// not overloaded will be called directly. The +// parameters on the lua stack are assumed +// to match those of the function. +// exceptions will still be catched when there's +// no error checking. + +// LUABIND_NOT_THREADSAFE +// this define will make luabind non-thread safe. That is, +// it will rely on a static variable. You can still have +// multiple lua states and use coroutines, but only +// one of your real threads may run lua code. + +// If you don't want to use the rtti supplied by C++ +// you can supply your own type-info structure with the +// LUABIND_TYPE_INFO define. Your type-info structure +// must be copyable and it must be able to compare itself +// against other type-info structures. You supply the compare +// function through the LUABIND_TYPE_INFO_EQUAL() +// define. It should compare the two type-info structures +// it is given and return true if they represent the same type +// and false otherwise. You also have to supply a function +// to generate your type-info structure. You do this through +// the LUABIND_TYPEID() define. It takes a type as it's +// parameter. That is, a compile time parameter. To use it +// you probably have to make a traits class with specializations +// for all classes that you have type-info for. + +#ifndef LUABIND_TYPE_INFO + #define LUABIND_TYPE_INFO const std::type_info* + #define LUABIND_TYPEID(t) &typeid(t) + #define LUABIND_TYPE_INFO_EQUAL(i1, i2) *i1 == *i2 + #define LUABIND_INVALID_TYPE_INFO &typeid(detail::null_type) +#include +#endif + +// LUABIND_NO_EXCEPTIONS +// this define will disable all usage of try, catch and throw in +// luabind. This will in many cases disable runtime-errors, such +// as invalid casts, when calling lua-functions that fails or +// returns values that cannot be converted by the given policy. +// Luabind requires that no function called directly or indirectly +// by luabind throws an exception (throwing exceptions through +// C code has undefined behavior, lua is written in C). + +// LUABIND_EXPORT +// LUABIND_IMPORT +// If you're building luabind as a dll on windows with devstudio +// you can set LUABIND_EXPORT to __declspec(dllexport) +// and LUABIND_IMPORT to __declspec(dllimport) + +#if _GNUC_ >= 4 +#define LUABIND_API __attribute__ ((visibility("default"))) +#else + +// this define is set if we're currently building a luabind file +// select import or export depending on it +#ifdef LUABIND_BUILDING + #ifdef LUABIND_EXPORT + #define LUABIND_API LUABIND_EXPORT + #else + #define LUABIND_API + #endif +#else + #ifdef LUABIND_IMPORT + #define LUABIND_API LUABIND_IMPORT + #else + #define LUABIND_API + #endif +#endif + +#endif + +namespace luabind { + +LUABIND_API void disable_super_deprecation(); + +} // namespace luabind + +#endif // LUABIND_CONFIG_HPP_INCLUDED + diff --git a/include/luabind/container_policy.hpp b/include/luabind/container_policy.hpp new file mode 100644 index 0000000..38cfaec --- /dev/null +++ b/include/luabind/container_policy.hpp @@ -0,0 +1,138 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CONTAINER_POLICY_HPP_INCLUDED +#define LUABIND_CONTAINER_POLICY_HPP_INCLUDED + +#include +#include +#include + +namespace luabind { namespace detail { + + namespace mpl = boost::mpl; + + template + struct container_converter_lua_to_cpp + { + template + T apply(lua_State* L, by_const_reference, int index) + { + typedef typename T::value_type value_type; + + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + T container; + + lua_pushnil(L); + while (lua_next(L, index)) + { + container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1)); + lua_pop(L, 1); // pop value + } + + return container; + } + + template + T apply(lua_State* L, by_value, int index) + { + return apply(L, by_const_reference(), index); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + if (lua_istable(L, index)) return 0; else return -1; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + template + struct container_converter_cpp_to_lua + { + template + void apply(lua_State* L, const T& container) + { + typedef typename T::value_type value_type; + + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + lua_newtable(L); + + int index = 1; + + for (typename T::const_iterator i = container.begin(); i != container.end(); ++i) + { + converter.apply(L, *i); + lua_rawseti(L, -2, index); + ++index; + } + } + }; + + template +// struct container_policy : converter_policy_tag + struct container_policy : conversion_policy + { +// BOOST_STATIC_CONSTANT(int, index = N); + + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_pointers {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , container_converter_lua_to_cpp + , container_converter_cpp_to_lua + >::type type; + }; + }; + +}} + +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + container(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + container(LUABIND_PLACEHOLDER_ARG(N), const Policies&) + { + return detail::policy_cons, detail::null_type>(); + } +} + +#endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED diff --git a/include/luabind/copy_policy.hpp b/include/luabind/copy_policy.hpp new file mode 100644 index 0000000..1a18b72 --- /dev/null +++ b/include/luabind/copy_policy.hpp @@ -0,0 +1,61 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_COPY_POLICY_081021_HPP +# define LUABIND_COPY_POLICY_081021_HPP + +# include + +namespace luabind { + +namespace detail +{ + + struct copy_converter + { + template + void apply(lua_State* L, T const& x) + { + value_converter().apply(L, x); + } + + template + void apply(lua_State* L, T* x) + { + if (!x) + lua_pushnil(L); + else + apply(L, *x); + } + }; + + template + struct copy_policy : conversion_policy + { + static void precall(lua_State*, index_map const&) + {} + + static void postcall(lua_State*, index_map const&) + {} + + template + struct apply + { + typedef copy_converter type; + }; + }; + +} // namespace detail + +template +detail::policy_cons, detail::null_type> +copy(LUABIND_PLACEHOLDER_ARG(N)) +{ + return detail::policy_cons, detail::null_type>(); +} + +} // namespace luabind + +#endif // LUABIND_COPY_POLICY_081021_HPP + diff --git a/include/luabind/dependency_policy.hpp b/include/luabind/dependency_policy.hpp new file mode 100644 index 0000000..cafa49a --- /dev/null +++ b/include/luabind/dependency_policy.hpp @@ -0,0 +1,119 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED +#define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail +{ + // makes A dependent on B, meaning B will outlive A. + // internally A stores a reference to B + template + struct dependency_policy + { + static void postcall(lua_State* L, const index_map& indices) + { + int nurse_index = indices[A]; + int patient = indices[B]; + + object_rep* nurse = static_cast(lua_touserdata(L, nurse_index)); + + // If the nurse isn't an object_rep, just make this a nop. + if (nurse == 0) + return; + + nurse->add_dependency(L, patient); + } + }; + +}} + +#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) + +namespace luabind +{ + // most absurd workaround of all time? + namespace detail + { + template + struct size_char_array + { + char storage[N + 2]; + }; + + template + size_char_array deduce_size(LUABIND_PLACEHOLDER_ARG(N)); + + template + struct get_index_workaround + { + static T t; + BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2); + }; + } + + template + detail::policy_cons::value + , detail::get_index_workaround::value>, detail::null_type> dependency(A,B) + { + return detail::policy_cons::value, detail::get_index_workaround::value> + , detail::null_type>(); + } + + template + detail::policy_cons::value>, detail::null_type> + return_internal_reference(A) + { + return detail::policy_cons::value>, detail::null_type>(); + } +} + +#else + +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + return_internal_reference(LUABIND_PLACEHOLDER_ARG(A)) + { + return detail::policy_cons, detail::null_type>(); + } +} + +#endif + +#endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED + diff --git a/include/luabind/detail/calc_arity.hpp b/include/luabind/detail/calc_arity.hpp new file mode 100644 index 0000000..c2e0aad --- /dev/null +++ b/include/luabind/detail/calc_arity.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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. + +#if !BOOST_PP_IS_ITERATING + +# include + +#ifndef LUABIND_CALC_ARITY_HPP_INCLUDED +#define LUABIND_CALC_ARITY_HPP_INCLUDED + +#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy::type p##n; +#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg + +namespace luabind { namespace detail +{ + template struct calc_arity; + + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() +}} + +#undef LUABIND_CALC_ARITY +#undef LUABIND_FIND_CONV + + +#endif // LUABIND_CALC_ARITY_HPP_INCLUDED + +#else // BOOST_PP_ITERATE + + template<> + struct calc_arity + { + template + static int apply(constructor, Policies*) + { + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _) + return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _); + } + }; + +#endif + diff --git a/include/luabind/detail/call.hpp b/include/luabind/detail/call.hpp new file mode 100644 index 0000000..beeab7d --- /dev/null +++ b/include/luabind/detail/call.hpp @@ -0,0 +1,214 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !BOOST_PP_IS_ITERATING + +# ifndef LUABIND_CALL2_080911_HPP +# define LUABIND_CALL2_080911_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include +# include + +namespace luabind { namespace detail { + +template +int invoke0( + lua_State* L, F const& f, Signature + , Policies const& policies, IsVoid, mpl::true_) +{ + return invoke_member( + L, f, Signature(), policies + , mpl::long_::value - 1>(), IsVoid() + ); +} + +template +int invoke0( + lua_State* L, F const& f, Signature + , Policies const& policies, IsVoid, mpl::false_) +{ + return invoke_normal( + L, f, Signature(), policies + , mpl::long_::value - 1>(), IsVoid() + ); +} + +template +int invoke(lua_State* L, F const& f, Signature, Policies const& policies) +{ + return invoke0( + L, f, Signature(), policies + , boost::is_void::type>() + , boost::is_member_function_pointer() + ); +} + +inline int maybe_yield_aux(lua_State*, int results, mpl::false_) +{ + return results; +} + +inline int maybe_yield_aux(lua_State* L, int results, mpl::true_) +{ + return lua_yield(L, results); +} + +template +int maybe_yield(lua_State* L, int results, Policies*) +{ + return maybe_yield_aux( + L, results, mpl::bool_::value>()); +} + +# define LUABIND_INVOKE_NEXT_ITER(n) \ + typename mpl::next< \ + BOOST_PP_IF( \ + n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \ + >::type + +# define LUABIND_INVOKE_NEXT_INDEX(n) \ + BOOST_PP_IF( \ + n \ + , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \ + (BOOST_PP_CAT(p,BOOST_PP_DEC(n))::has_arg ? 1 : 0) \ + , 1 \ + ) + +# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \ + typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \ + typedef typename mpl::deref::type \ + BOOST_PP_CAT(a,n); \ + typedef typename find_conversion_policy::type \ + BOOST_PP_CAT(p,n); \ + typename mpl::apply_wrap2< \ + BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \ + int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n); + +# define LUABIND_INVOKE_ARG(z, n, base) \ + BOOST_PP_CAT(c,base(n)).apply( \ + L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n))) + +# define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \ + BOOST_PP_CAT(c,n).converter_postcall( \ + L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)); + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# define LUABIND_INVOKE_VOID +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# undef LUABIND_INVOKE_VOID +# define LUABIND_INVOKE_MEMBER +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# define LUABIND_INVOKE_VOID +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}} // namespace luabind::detail + +# endif // LUABIND_CALL2_080911_HPP + +#else // BOOST_PP_IS_ITERATING + +# ifdef LUABIND_INVOKE_MEMBER +# define N BOOST_PP_INC(BOOST_PP_ITERATION()) +# else +# define N BOOST_PP_ITERATION() +# endif + +template +int +# ifdef LUABIND_INVOKE_MEMBER +invoke_member +# else +invoke_normal +# endif +( + lua_State* L, F const& f, Signature, Policies const&, mpl::long_ +# ifdef LUABIND_INVOKE_VOID + , mpl::true_ +# else + , mpl::false_ +# endif +) +{ + typedef typename mpl::begin::type first; +# ifndef LUABIND_INVOKE_VOID + typedef typename mpl::deref::type result_type; + typedef typename find_conversion_policy<0, Policies>::type result_policy; + typename mpl::apply_wrap2< + result_policy, result_type, cpp_to_lua>::type result_converter; +# endif + +# if N > 0 +# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n) +# define BOOST_PP_LOCAL_LIMITS (0,N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + + int const arguments = lua_gettop(L); + +# ifndef LUABIND_INVOKE_VOID + result_converter.apply( + L, +# endif +# ifdef LUABIND_INVOKE_MEMBER + (c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)( + BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC) + ) +# else +# define LUABIND_INVOKE_IDENTITY(x) x + f( + BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY) + ) +# undef LUABIND_INVOKE_IDENTITY +# endif +# ifndef LUABIND_INVOKE_VOID + ) +# endif + ; + +# if N > 0 +# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n) +# define BOOST_PP_LOCAL_LIMITS (0,N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + + int const results = lua_gettop(L) - arguments; + + int const indices[] = { + arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index) + }; + + policy_list_postcall::apply(L, indices); + + return maybe_yield(L, results, (Policies*)0); +} + +# undef N + +#endif + diff --git a/include/luabind/detail/call_function.hpp b/include/luabind/detail/call_function.hpp new file mode 100644 index 0000000..edf2459 --- /dev/null +++ b/include/luabind/detail/call_function.hpp @@ -0,0 +1,443 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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. + + +#if !BOOST_PP_IS_ITERATING + +#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED +#define LUABIND_CALL_FUNCTION_HPP_INCLUDED + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace luabind +{ + namespace detail + { + + // if the proxy_function_caller returns non-void + template + class proxy_function_caller + { +// friend class luabind::object; + public: + + typedef int(*function_t)(lua_State*, int, int); + + proxy_function_caller( + lua_State* L + , int params + , function_t fun + , const Tuple args) + : m_state(L) + , m_params(params) + , m_fun(fun) + , m_args(args) + , m_called(false) + { + } + + proxy_function_caller(const proxy_function_caller& rhs) + : m_state(rhs.m_state) + , m_params(rhs.m_params) + , m_fun(rhs.m_fun) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_function_caller() + { + if (m_called) return; + + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + push_args_from_tuple<1>::apply(L, m_args); + if (m_fun(L, boost::tuples::length::value, 0)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); + +#endif + } + + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + operator Ret() + { + typename mpl::apply_wrap2::type converter; + + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + push_args_from_tuple<1>::apply(L, m_args); + if (m_fun(L, boost::tuples::length::value, 1)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, LUABIND_TYPEID(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, LUABIND_TYPEID(Ret)); + + assert(0 && "the lua function's return value could not be converted." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); + +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } + + template + Ret operator[](const Policies& p) + { + typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (m_fun(L, boost::tuples::length::value, 1)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, LUABIND_TYPEID(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, LUABIND_TYPEID(Ret)); + + assert(0 && "the lua function's return value could not be converted." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); + +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } + + private: + + lua_State* m_state; + int m_params; + function_t m_fun; + Tuple m_args; + mutable bool m_called; + + }; + + // if the proxy_member_caller returns void + template + class proxy_function_void_caller + { + friend class luabind::object; + public: + + typedef int(*function_t)(lua_State*, int, int); + + proxy_function_void_caller( + lua_State* L + , int params + , function_t fun + , const Tuple args) + : m_state(L) + , m_params(params) + , m_fun(fun) + , m_args(args) + , m_called(false) + { + } + + proxy_function_void_caller(const proxy_function_void_caller& rhs) + : m_state(rhs.m_state) + , m_params(rhs.m_params) + , m_fun(rhs.m_fun) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_function_void_caller() + { + if (m_called) return; + + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + push_args_from_tuple<1>::apply(L, m_args); + if (m_fun(L, boost::tuples::length::value, 0)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + template + void operator[](const Policies& p) + { + m_called = true; + lua_State* L = m_state; + + int top = lua_gettop(L); + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (m_fun(L, boost::tuples::length::value, 0)) + { + assert(lua_gettop(L) == top - m_params + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + private: + + lua_State* m_state; + int m_params; + function_t m_fun; + Tuple m_args; + mutable bool m_called; + + }; + + } + + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + +} + +#endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED + +#elif BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + assert(name && "luabind::call_function() expects a function name"); + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + lua_pushstring(L, name); + lua_gettable(L, LUA_GLOBALSINDEX); + + return proxy_type(L, 1, &detail::pcall, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + call_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + obj.push(obj.interpreter()); + return proxy_type(obj.interpreter(), 1, &detail::pcall, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + resume_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + assert(name && "luabind::resume_function() expects a function name"); + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + lua_pushstring(L, name); + lua_gettable(L, LUA_GLOBALSINDEX); + + return proxy_type(L, 1, &detail::resume_impl, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + resume_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + obj.push(obj.interpreter()); + return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args); + } + + template + typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type + resume(lua_State* L BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + typedef typename boost::mpl::if_ + , luabind::detail::proxy_function_void_caller > + , luabind::detail::proxy_function_caller > >::type proxy_type; + + return proxy_type(L, 0, &detail::resume_impl, args); + } + + +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + + +#endif + diff --git a/include/luabind/detail/call_member.hpp b/include/luabind/detail/call_member.hpp new file mode 100644 index 0000000..4d3a5dc --- /dev/null +++ b/include/luabind/detail/call_member.hpp @@ -0,0 +1,362 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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. + + +#if !BOOST_PP_IS_ITERATING + +#ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED +#define LUABIND_CALL_MEMBER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include // TODO: REMOVE DEPENDENCY + +#include + +#include +#include + +#include + +namespace luabind +{ + namespace detail + { + + namespace mpl = boost::mpl; + + // if the proxy_member_caller returns non-void + template + class proxy_member_caller + { +// friend class luabind::object; + public: + + proxy_member_caller(lua_State* L_, const Tuple args) + : L(L_) + , m_args(args) + , m_called(false) + { + } + + proxy_member_caller(const proxy_member_caller& rhs) + : L(rhs.L) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_member_caller() + { + if (m_called) return; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + push_args_from_tuple<1>::apply(L, m_args); + if (pcall(L, boost::tuples::length::value + 1, 0)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } + + operator Ret() + { + typename mpl::apply_wrap2::type converter; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + push_args_from_tuple<1>::apply(L, m_args); + if (pcall(L, boost::tuples::length::value + 1, 1)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, LUABIND_TYPEID(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, LUABIND_TYPEID(Ret)); + + assert(0 && "the lua function's return value could not be converted." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } + + template + Ret operator[](const Policies& p) + { + typedef typename find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (pcall(L, boost::tuples::length::value + 1, 1)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, LUABIND_TYPEID(Ret)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, LUABIND_TYPEID(Ret)); + + assert(0 && "the lua function's return value could not be converted." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } +#endif + return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); + } + + private: + + lua_State* L; + Tuple m_args; + mutable bool m_called; + + }; + + // if the proxy_member_caller returns void + template + class proxy_member_void_caller + { + friend class luabind::object; + public: + + proxy_member_void_caller(lua_State* L_, const Tuple args) + : L(L_) + , m_args(args) + , m_called(false) + { + } + + proxy_member_void_caller(const proxy_member_void_caller& rhs) + : L(rhs.L) + , m_args(rhs.m_args) + , m_called(rhs.m_called) + { + rhs.m_called = true; + } + + ~proxy_member_void_caller() + { + if (m_called) return; + + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + push_args_from_tuple<1>::apply(L, m_args); + if (pcall(L, boost::tuples::length::value + 1, 0)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } + + template + void operator[](const Policies& p) + { + m_called = true; + + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; + + // pcall will pop the function and self reference + // and all the parameters + + detail::push_args_from_tuple<1>::apply(L, m_args, p); + if (pcall(L, boost::tuples::length::value + 1, 0)) + { + assert(lua_gettop(L) == top + 1); +#ifndef LUABIND_NO_EXCEPTIONS + throw error(L); +#else + error_callback_fun e = get_error_callback(); + if (e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } + + private: + lua_State* L; + Tuple m_args; + mutable bool m_called; + + }; + + } // detail + + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + +} + +#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED + +#elif BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + template + typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type + call_member(object const& obj, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) + { + typedef boost::tuples::tuple tuple_t; +#if BOOST_PP_ITERATION() == 0 + tuple_t args; +#else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); +#endif + + typedef typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type proxy_type; + + // this will be cleaned up by the proxy object + // once the call has been made + + // get the function + obj.push(obj.interpreter()); + lua_pushstring(obj.interpreter(), name); + lua_gettable(obj.interpreter(), -2); + // duplicate the self-object + lua_pushvalue(obj.interpreter(), -2); + // remove the bottom self-object + lua_remove(obj.interpreter(), -3); + + // now the function and self objects + // are on the stack. These will both + // be popped by pcall + return proxy_type(obj.interpreter(), args); + } + +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + +#endif + diff --git a/include/luabind/detail/call_operator_iterate.hpp b/include/luabind/detail/call_operator_iterate.hpp new file mode 100755 index 0000000..c6f95a1 --- /dev/null +++ b/include/luabind/detail/call_operator_iterate.hpp @@ -0,0 +1,66 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#define N BOOST_PP_ITERATION() + +#define LUABIND_UNWRAP_PARAMETER(z, n, _) \ + typename detail::unwrap_parameter_type::type \ + BOOST_PP_CAT(_, n) + +template +struct BOOST_PP_CAT(call_operator, N) + : detail::operator_< + BOOST_PP_CAT(call_operator, N)< + Self BOOST_PP_ENUM_TRAILING_PARAMS(N, A) + > + > +{ + BOOST_PP_CAT(call_operator, N)(int) {} + + template + struct apply + { + static void execute( + lua_State* L + , typename detail::unwrap_parameter_type::type self + BOOST_PP_ENUM_TRAILING(N, LUABIND_UNWRAP_PARAMETER, _) + ) + { + using namespace detail; + operator_result( + L +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + , self(BOOST_PP_ENUM_PARAMS(N, _)) +#else + , (self(BOOST_PP_ENUM_PARAMS(N, _)), detail::operator_void_return()) +#endif + , (Policies*)0 + ); + } + }; + + static char const* name() { return "__call"; } +}; + +#undef LUABIND_UNWRAP_PARAMETER +#undef N + diff --git a/include/luabind/detail/class_cache.hpp b/include/luabind/detail/class_cache.hpp new file mode 100755 index 0000000..17d3a44 --- /dev/null +++ b/include/luabind/detail/class_cache.hpp @@ -0,0 +1,89 @@ +// Copyright (c) 2004 Daniel Wallin + +// 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 CLASS_CACHE_040218_HPP +#define CLASS_CACHE_040218_HPP + +#include +#include +#include + +namespace luabind { namespace detail { + +#ifdef LUABIND_NOT_THREADSAFE + + class class_rep; + + template + struct class_cache_impl + { + static lua_State* state; + static class_rep* class_; + }; + + template + lua_State* class_cache_impl::state = 0; + + template + class_rep* class_cache_impl::class_ = 0; + + template + struct class_cache + : class_cache_impl< + typename boost::add_reference< + typename boost::add_const< + T + >::type + >::type + > + { + }; + + template + class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) + { + if (class_cache::state != L) + { + class_cache::state = L; + + class_registry* registry = class_registry::get_registry(L); + class_cache::class_ = registry->find_class(LUABIND_TYPEID(T)); + } + + return class_cache::class_; + } + +#else + + template + class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) + { + class_registry* registry = class_registry::get_registry(L); + return registry->find_class(LUABIND_TYPEID(T)); + } + +#endif + +}} // namespace luabind::detail + +#endif // CLASS_CACHE_040218_HPP + diff --git a/include/luabind/detail/class_registry.hpp b/include/luabind/detail/class_registry.hpp new file mode 100644 index 0000000..766c939 --- /dev/null +++ b/include/luabind/detail/class_registry.hpp @@ -0,0 +1,99 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CLASS_REGISTRY_HPP_INCLUDED +#define LUABIND_CLASS_REGISTRY_HPP_INCLUDED + +#include +#include + +#include +#include + +namespace luabind { namespace detail +{ + class class_rep; + + struct LUABIND_API class_registry + { + class_registry(lua_State* L); + + static class_registry* get_registry(lua_State* L); + + int cpp_instance() const { return m_cpp_instance_metatable; } + int cpp_class() const { return m_cpp_class_metatable; } + + int lua_instance() const { return m_lua_instance_metatable; } + int lua_class() const { return m_lua_class_metatable; } + int lua_function() const { return m_lua_function_metatable; } + + void add_class(LUABIND_TYPE_INFO info, class_rep* crep); + + struct cmp + { + bool operator()(const std::type_info* a, const std::type_info* b) const + { + return a->before(*b) != 0; + } + + template + bool operator()(const T& a, const T& b) const + { + return a < b; + } + }; + + class_rep* find_class(LUABIND_TYPE_INFO info) const; + + private: + + std::map m_classes; + + // this is a lua reference that points to the lua table + // that is to be used as meta table for all C++ class + // instances. It is a kind of v-table. + int m_cpp_instance_metatable; + + // this is a lua reference to the metatable to be used + // for all classes defined in C++. + int m_cpp_class_metatable; + + // this is a lua reference that points to the lua table + // that is to be used as meta table for all lua class + // instances. It is a kind of v-table. + int m_lua_instance_metatable; + + // this is a lua reference to the metatable to be used + // for all classes defined in lua + int m_lua_class_metatable; + + // this metatable only contains a destructor + // for luabind::Detail::free_functions::function_rep + int m_lua_function_metatable; + + }; + +}} + +#endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED + diff --git a/include/luabind/detail/class_rep.hpp b/include/luabind/detail/class_rep.hpp new file mode 100644 index 0000000..b158081 --- /dev/null +++ b/include/luabind/detail/class_rep.hpp @@ -0,0 +1,384 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CLASS_REP_HPP_INCLUDED +#define LUABIND_CLASS_REP_HPP_INCLUDED + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace luabind +{ + + template + struct bases {}; + typedef bases no_bases; +} + +namespace luabind { namespace detail +{ + + LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); + + struct class_registration; + + struct conversion_storage; + + // This function is used as a tag to identify "properties". + LUABIND_API int property_tag(lua_State*); + + // this is class-specific information, poor man's vtable + // this is allocated statically (removed by the compiler) + // a pointer to this structure is stored in the lua tables' + // metatable with the name __classrep + // it is used when matching parameters to function calls + // to determine possible implicit casts + // it is also used when finding the best match for overloaded + // methods + + class LUABIND_API class_rep + { + friend struct class_registration; + friend int super_callback(lua_State*); +//TODO: avoid the lua-prefix + friend int lua_class_gettable(lua_State*); + friend int lua_class_settable(lua_State*); + friend int static_class_gettable(lua_State*); + public: + + enum class_type + { + cpp_class = 0, + lua_class = 1 + }; + + // destructor is a lua callback function that is hooked as garbage collector event on every instance + // of this class (including those that is not owned by lua). It gets an object_rep as argument + // on the lua stack. It should delete the object pointed to by object_rep::ptr if object_pre::flags + // is object_rep::owner (which means that lua owns the object) + + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(LUABIND_TYPE_INFO type + , const char* name + , lua_State* L + , void(*destructor)(void*) + , void(*const_holder_destructor)(void*) + , LUABIND_TYPE_INFO holder_type + , LUABIND_TYPE_INFO const_holder_type + , void*(*extractor)(void*) + , const void*(*const_extractor)(void*) + , void(*const_converter)(void*,void*) + , void(*construct_holder)(void*,void*) + , void(*construct_const_holder)(void*,void*) + , void(*default_construct_holder)(void*) + , void(*default_construct_const_holder)(void*) + , void(*adopt_fun)(void*) + , int holder_size + , int holder_alignment); + + // used when creating a lua class + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(lua_State* L, const char* name); + + ~class_rep(); + + std::pair allocate(lua_State* L) const; + + // called from the metamethod for __index + // the object pointer is passed on the lua stack + int gettable(lua_State* L); + + // called from the metamethod for __newindex + // the object pointer is passed on the lua stack + bool settable(lua_State* L); + + // this is called as __index metamethod on every instance of this class + static int gettable_dispatcher(lua_State* L); + + // this is called as __newindex metamethod on every instance of this class + static int settable_dispatcher(lua_State* L); + static int operator_dispatcher(lua_State* L); + + // this is called as metamethod __call on the class_rep. + static int constructor_dispatcher(lua_State* L); + + static int function_dispatcher(lua_State* L); + + struct base_info + { + int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) + class_rep* base; + }; + + void add_base_class(const base_info& binfo); + + const std::vector& bases() const throw() { return m_bases; } + + void set_type(LUABIND_TYPE_INFO t) { m_type = t; } + LUABIND_TYPE_INFO type() const throw() { return m_type; } + LUABIND_TYPE_INFO holder_type() const throw() { return m_holder_type; } + LUABIND_TYPE_INFO const_holder_type() const throw() { return m_const_holder_type; } + bool has_holder() const throw() { return m_construct_holder != 0; } + + const char* name() const throw() { return m_name; } + + // the lua reference to this class_rep + // TODO: remove +// int self_ref() const throw() { return m_self_ref; } + // the lua reference to the metatable for this class' instances + int metatable_ref() const throw() { return m_instance_metatable; } + + void get_table(lua_State* L) const { m_table.push(L); } + void get_default_table(lua_State* L) const { m_default_table.push(L); } + + void(*construct_holder() const)(void*, void*) { return m_construct_holder; } + void(*destructor() const)(void*) { return m_destructor; } + void(*const_holder_destructor() const)(void*) { return m_const_holder_destructor; } + typedef const void*(*t_const_extractor)(void*); + t_const_extractor const_extractor() const { return m_const_extractor; } + typedef void*(*t_extractor)(void*); + t_extractor extractor() const { return m_extractor; } + + void(*const_converter() const)(void*,void*) { return m_const_converter; } + + class_type get_class_type() const { return m_class_type; } + + void add_static_constant(const char* name, int val); + + // takes a pointer to the instance object + // and if it has a wrapper, the wrapper + // will convert its weak_ptr into a strong ptr. + void adopt(bool const_obj, void* obj); + + static int super_callback(lua_State* L); + + static int lua_settable_dispatcher(lua_State* L); + + // called from the metamethod for __index + // obj is the object pointer + static int lua_class_gettable(lua_State* L); + + // called from the metamethod for __newindex + // obj is the object pointer + static int lua_class_settable(lua_State* L); + + // called from the metamethod for __index + // obj is the object pointer + static int static_class_gettable(lua_State* L); + + void* convert_to( + LUABIND_TYPE_INFO target_type + , const object_rep* obj, conversion_storage&) const; + + bool has_operator_in_lua(lua_State*, int id); + + // this is used to describe setters and getters + struct callback + { + boost::function2 func; +#ifndef LUABIND_NO_ERROR_CHECKING + int (*match)(lua_State*, int); + + typedef void(*get_sig_ptr)(lua_State*, std::string&); + get_sig_ptr sig; +#endif + int pointer_offset; + }; + + const std::map& properties() const; + typedef std::map property_map; + + int holder_alignment() const + { + return m_holder_alignment; + } + + int holder_size() const + { + return m_holder_size; + } + + + void set_holder_alignment(int n) + { + m_holder_alignment = n; + } + + void set_holder_size(int n) + { + m_holder_size = n; + } + + void derived_from(const class_rep* base) + { + m_holder_alignment = base->m_holder_alignment; + m_holder_size = base->m_holder_size; + m_holder_type = base->m_holder_type; + m_const_holder_type = base->m_const_holder_type; + m_extractor = base->m_extractor; + m_const_extractor = base->m_const_extractor; + m_const_converter = base->m_const_converter; + m_construct_holder = base->m_construct_holder; + m_construct_const_holder = base->m_construct_const_holder; + m_default_construct_holder = base->m_default_construct_holder; + m_default_construct_const_holder = base->m_default_construct_const_holder; + } + + struct operator_callback: public overload_rep_base + { + inline void set_fun(int (*f)(lua_State*)) { func = f; } + inline int call(lua_State* L) { return func(L); } + inline void set_arity(int arity) { m_arity = arity; } + + private: + int(*func)(lua_State*); + }; + + private: + + void cache_operators(lua_State*); + + // this is a pointer to the type_info structure for + // this type + // warning: this may be a problem when using dll:s, since + // typeid() may actually return different pointers for the same + // type. + LUABIND_TYPE_INFO m_type; + LUABIND_TYPE_INFO m_holder_type; + LUABIND_TYPE_INFO m_const_holder_type; + + // this function pointer is used if the type is held by + // a smart pointer. This function takes the type we are holding + // (the held_type, the smart pointer) and extracts the actual + // pointer. + void*(*m_extractor)(void*); + const void*(*m_const_extractor)(void*); + + void(*m_const_converter)(void*, void*); + + // this function is used to construct the held_type + // (the smart pointer). The arguments are the memory + // in which it should be constructed (with placement new) + // and the raw pointer that should be wrapped in the + // smart pointer + typedef void(*construct_held_type_t)(void*,void*); + construct_held_type_t m_construct_holder; + construct_held_type_t m_construct_const_holder; + + typedef void(*default_construct_held_type_t)(void*); + default_construct_held_type_t m_default_construct_holder; + default_construct_held_type_t m_default_construct_const_holder; + + typedef void(*adopt_t)(void*); + adopt_t m_adopt_fun; + + // this is the size of the userdata chunk + // for each object_rep of this class. We + // need this since held_types are constructed + // in the same memory (to avoid fragmentation) + int m_holder_size; + int m_holder_alignment; + + // a list of info for every class this class derives from + // the information stored here is sufficient to do + // type casts to the base classes + std::vector m_bases; + + // the class' name (as given when registered to lua with class_) + const char* m_name; + + // contains signatures and construction functions + // for all constructors + construct_rep m_constructor; + + // a reference to this structure itself. Since this struct + // is kept inside lua (to let lua collect it when lua_close() + // is called) we need to lock it to prevent collection. + // the actual reference is not currently used. + detail::lua_reference m_self_ref; + + // this should always be used when accessing + // members in instances of a class. + // this table contains c closures for all + // member functions in this class, they + // may point to both static and virtual functions + handle m_table; + + // this table contains default implementations of the + // virtual functions in m_table. + handle m_default_table; + + // the type of this class.. determines if it's written in c++ or lua + class_type m_class_type; + + // this is a lua reference that points to the lua table + // that is to be used as meta table for all instances + // of this class. + int m_instance_metatable; + + // ***** the maps below contains all members in this class ***** + + // datamembers, some members may be readonly, and + // only have a getter function + std::map m_getters; + std::map m_setters; + + std::vector m_operators[number_of_operators]; // the operators in lua + + void(*m_destructor)(void*); + void(*m_const_holder_destructor)(void*); + + std::map m_static_constants; + + // the first time an operator is invoked + // we check the associated lua table + // and cache the result + int m_operator_cache; + }; + + bool is_class_rep(lua_State* L, int index); + +}} + +//#include + +#endif // LUABIND_CLASS_REP_HPP_INCLUDED diff --git a/include/luabind/detail/compute_score.hpp b/include/luabind/detail/compute_score.hpp new file mode 100644 index 0000000..91f1d7a --- /dev/null +++ b/include/luabind/detail/compute_score.hpp @@ -0,0 +1,106 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_COMPUTE_RANK_081006_HPP +# define LUABIND_COMPUTE_RANK_081006_HPP + +# include +# include +# include +# include +# include +# include + +namespace luabind { namespace detail { + +namespace mpl = boost::mpl; + +template +int compute_score_aux( + lua_State*L, int index, Idx, Iter, End end, Policies const& policies) +{ + typedef typename Iter::type arg_type; + typedef typename find_conversion_policy::type + conversion_policy; + typedef typename mpl::apply_wrap2< + conversion_policy, arg_type, lua_to_cpp>::type converter; + + int score = converter::match(L, LUABIND_DECORATE_TYPE(arg_type), index); + + if (score < 0) + return score; + + if (conversion_policy::has_arg) + ++index; + + int next = compute_score_aux( + L + , index + , typename mpl::next::type() + , typename mpl::next::type() + , end + , policies + ); + + if (next < 0) + return next; + + return score + next; +} + +template +int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&) +{ + return 0; +} + +template +int compute_score(lua_State* L, Signature, Policies const& policies) +{ + return compute_score_aux( + L + , 1 + , mpl::int_<1>() + , typename mpl::next::type>::type() + , typename mpl::end::type() + , policies + ); +} + +template +int compute_arity_aux(Iter, End end, Idx, Policies const& policies) +{ + typedef typename find_conversion_policy::type + conversion_policy; + + int next = compute_arity_aux( + typename mpl::next::type() + , end + , typename mpl::next::type() + , policies + ); + + return (conversion_policy::has_arg ? 1 : 0) + next; +} + +template +int compute_arity_aux(End, End, Idx, Policies const&) +{ + return 0; +} + +template +int compute_arity(Signature, Policies const& policies) +{ + return compute_arity_aux( + typename mpl::next::type>::type() + , typename mpl::end::type() + , mpl::int_<1>() + , policies + ); +} + +}} // namespace luabind::detail + +#endif // LUABIND_COMPUTE_RANK_081006_HPP diff --git a/include/luabind/detail/construct_rep.hpp b/include/luabind/detail/construct_rep.hpp new file mode 100644 index 0000000..a7729bb --- /dev/null +++ b/include/luabind/detail/construct_rep.hpp @@ -0,0 +1,86 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CONSTRUCT_REP_HPP_INCLUDED +#define LUABIND_CONSTRUCT_REP_HPP_INCLUDED + +#include + +#include +#include + +#include +#include +#include + +//#include +#include +#include + +namespace luabind { namespace detail +{ + + + struct construct_rep + { + struct overload_t: public overload_rep_base + { + overload_t(): wrapped_construct_fun(0) + { + } + + typedef void*(*construct_ptr)(lua_State*, weak_ref const&); + typedef void*(*wrapped_construct_ptr)(lua_State*, weak_ref const&); + typedef void(*get_signature_ptr)(lua_State*, std::string&); + + inline void set_constructor(construct_ptr f) { construct_fun = f; } + inline void set_wrapped_constructor(wrapped_construct_ptr f) { wrapped_construct_fun = f; } + + inline void* construct(lua_State* L, weak_ref const& backref) + { + return construct_fun(L, backref); + } + + inline void* construct_wrapped(lua_State* L, weak_ref const& ref) { return wrapped_construct_fun(L, ref); } + inline bool has_wrapped_construct() { return wrapped_construct_fun != 0; } + + inline void set_arity(int arity) { m_arity = arity; } + + private: + + construct_ptr construct_fun; + wrapped_construct_ptr wrapped_construct_fun; + + }; + + void swap(construct_rep& x) + { + std::swap(x.overloads, overloads); + } + + std::vector overloads; + }; + +}} + +#endif // LUABIND_CONSTRUCT_REP_HPP_INCLUDED diff --git a/include/luabind/detail/constructor.hpp b/include/luabind/detail/constructor.hpp new file mode 100644 index 0000000..d4f57de --- /dev/null +++ b/include/luabind/detail/constructor.hpp @@ -0,0 +1,111 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !BOOST_PP_IS_ITERATING + +# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP + +# include +# include + +# include +# include +# include +# include + +namespace luabind { namespace detail { + +inline void inject_backref(lua_State* L, void*, void*) +{} + +template +void inject_backref(lua_State* L, T* p, wrap_base*) +{ + weak_ref(L, -1).swap(wrap_access::ref(*p)); +} + +template +struct construct_aux; + +template +struct construct + : construct_aux::value - 2, T, Signature> +{}; + +template +struct construct_aux<0, T, Signature> +{ + void operator()(argument const& self_) const + { + object_rep* self = touserdata(self_); + class_rep* cls = self->crep(); + + std::auto_ptr instance(new T); + inject_backref(self_.interpreter(), instance.get(), instance.get()); + + if (cls->has_holder()) + { + cls->construct_holder()(self->ptr(), instance.get()); + } + else + { + self->set_object(instance.get()); + } + + self->set_destructor(cls->destructor()); + instance.release(); + } +}; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (1, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}} // namespace luabind::detail + +# endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP + +#else // !BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() + +template +struct construct_aux +{ + typedef typename mpl::begin::type first; + typedef typename mpl::next::type iter0; + +# define BOOST_PP_LOCAL_MACRO(n) \ + typedef typename mpl::next< \ + BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \ + typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n)); + +# define BOOST_PP_LOCAL_LIMITS (1,N) +# include BOOST_PP_LOCAL_ITERATE() + + void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const + { + object_rep* self = touserdata(self_); + class_rep* cls = self->crep(); + + std::auto_ptr instance(new T(BOOST_PP_ENUM_PARAMS(N,_))); + inject_backref(self_.interpreter(), instance.get(), instance.get()); + + if (cls->has_holder()) + { + cls->construct_holder()(self->ptr(), instance.get()); + } + else + { + self->set_object(instance.get()); + } + + self->set_destructor(cls->destructor()); + instance.release(); + } +}; + +#endif + diff --git a/include/luabind/detail/conversion_storage.hpp b/include/luabind/detail/conversion_storage.hpp new file mode 100644 index 0000000..153112d --- /dev/null +++ b/include/luabind/detail/conversion_storage.hpp @@ -0,0 +1,41 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_CONVERSION_STORAGE_080930_HPP +# define LUABIND_CONVERSION_STORAGE_080930_HPP + +# include +# include + +namespace luabind { namespace detail { + +typedef void(*destruction_function)(void*); + +// This is used by the converters in policy.hpp, and +// class_rep::convert_to as temporary storage when constructing +// holders. + +struct conversion_storage +{ + conversion_storage() + : destructor(0) + {} + + ~conversion_storage() + { + if (destructor) + destructor(&data); + } + + // Unfortunately the converters currently doesn't have access to + // the actual type being converted when this is instantiated, so + // we have to guess a max size. + boost::aligned_storage<128> data; + destruction_function destructor; +}; + +}} // namespace luabind::detail + +#endif // LUABIND_CONVERSION_STORAGE_080930_HPP + diff --git a/include/luabind/detail/convert_to_lua.hpp b/include/luabind/detail/convert_to_lua.hpp new file mode 100644 index 0000000..f5aa89a --- /dev/null +++ b/include/luabind/detail/convert_to_lua.hpp @@ -0,0 +1,92 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_CONVERT_TO_LUA_HPP_INCLUDED +#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED + +#include +#include +#include + +#include + +namespace luabind { namespace detail +{ + template + struct unwrap_ref + { + template + static const T& get(const T& r) { return r; } + + template + struct apply + { + typedef T type; + }; + }; + + template<> + struct unwrap_ref + { + template + static T& get(const boost::reference_wrapper& r) { return r.get(); } + + template + struct apply + { + typedef typename T::type& type; + }; + }; + + namespace mpl = boost::mpl; + + template + void convert_to_lua(lua_State* L, const T& v) + { + typedef typename mpl::apply_wrap1< + unwrap_ref::value> + , T + >::type value_type; + + typename mpl::apply_wrap2::type converter; + + converter.apply(L, unwrap_ref::value>::get(v)); + } + + template + void convert_to_lua_p(lua_State* L, const T& v, const Policies&) + { + typedef typename mpl::apply_wrap1< + unwrap_ref::value> + , T + >::type value_type; + + typedef typename find_conversion_policy::type converter_policy; + typename mpl::apply_wrap2::type converter; + + converter.apply(L, unwrap_ref::value>::get(v)); + } +}} + +#endif + diff --git a/include/luabind/detail/debug.hpp b/include/luabind/detail/debug.hpp new file mode 100755 index 0000000..ef13bc8 --- /dev/null +++ b/include/luabind/detail/debug.hpp @@ -0,0 +1,55 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_DEBUG_HPP_INCLUDED +#define LUABIND_DEBUG_HPP_INCLUDED + +#ifndef NDEBUG + +#include +#include + +namespace luabind { namespace detail +{ + struct stack_checker_type + { + stack_checker_type(lua_State* L) + : m_L(L) + , m_stack(lua_gettop(m_L)) + {} + + ~stack_checker_type() + { + assert(m_stack == lua_gettop(m_L)); + } + + lua_State* m_L; + int m_stack; + }; + +}} +#define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) +#else +#define LUABIND_CHECK_STACK(L) do {} while (0) +#endif + +#endif // LUABIND_DEBUG_HPP_INCLUDED diff --git a/include/luabind/detail/decorate_type.hpp b/include/luabind/detail/decorate_type.hpp new file mode 100644 index 0000000..bb144c4 --- /dev/null +++ b/include/luabind/detail/decorate_type.hpp @@ -0,0 +1,266 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_DECORATE_TYPE_HPP_INCLUDED +#define LUABIND_DECORATE_TYPE_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail +{ + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct decorated_type + { + static by_value t; + static inline by_value& get() { return /*by_value()*/t; } + }; + + template + by_value decorated_type::t; + + template + struct decorated_type + { + static by_pointer t; + static inline by_pointer& get() { return /*by_pointer()*/t; } + }; + + template + by_pointer decorated_type::t; + + template + struct decorated_type + { + static by_const_pointer t; + static inline by_const_pointer get() { return /*by_const_pointer()*/t; } + }; + + template + by_const_pointer decorated_type::t; + + template + struct decorated_type + { + static by_const_pointer t; + static inline by_const_pointer& get() { return /*by_const_pointer()*/t; } + }; + + template + by_const_pointer decorated_type::t; + + template + struct decorated_type + { + static by_reference t; + static inline by_reference& get() { return /*by_reference()*/t; } + }; + + template + by_reference decorated_type::t; + + template + struct decorated_type + { + static by_const_reference t; + static inline by_const_reference& get() { return /*by_const_reference()*/t; } + }; + + template + by_const_reference decorated_type::t; + + #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get() + +#else + +#include + + namespace + { + LUABIND_ANONYMOUS_FIX char decorated_type_array[64]; + } + + template + struct decorated_type_cref_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_const_reference get(const U&) + { + return by_const_reference(); + } + static T data() { return reinterpret_cast(decorated_type_array); } +#else + + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_const_reference get(void(*f)(const U&)) + { return by_const_reference(); } +#endif + }; + + template + struct decorated_type_ref_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_reference get(U&) + { + return by_reference(); + } + static T data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_reference get(void(*)(U&)) + { return by_reference(); } +#endif + }; + + template + struct decorated_type_cptr_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_const_pointer get(const U*) + { + return by_const_pointer(); + } + static T& data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_const_pointer get(void(*)(const U*)) + { return by_const_pointer(); } +#endif + }; + + template + struct decorated_type_ptr_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_pointer get(U*) + { + return by_pointer(); + } + static T& data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T) + { return (void(*)(T))0; } + + template + static by_pointer get(void(*)(U*)) + { return by_pointer(); } +#endif + }; + + template + struct decorated_type_value_impl + { +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + template + static by_value get(U&) + { + return by_value(); + } + static T& data() { return reinterpret_cast(decorated_type_array); } +#else + static void(*data())(T&) + { return (void(*)(T&))0; } + + template + static by_value get(void(*)(U&)) + { return by_value(); } +#endif + }; + + template<> + struct decorated_type_value_impl + { + static by_value get(int) + { + return by_value(); + } + static int data() { return 0; } + }; + + template + struct decorated_type_array_impl + { + template + static by_pointer get(U*) + { + return by_pointer(); + } + + template + static by_pointer get(void(*)(U)) + { return by_pointer(); } + + static T& data() { return reinterpret_cast(decorated_type_array); } + }; + + template + struct decorated_type +// : boost::mpl::if_ +// , decorated_type_array_impl + : boost::mpl::if_ + , decorated_type_cref_impl + , typename boost::mpl::if_ + , decorated_type_ref_impl + , typename boost::mpl::if_ + , decorated_type_ptr_impl + , typename boost::mpl::if_ + , decorated_type_cptr_impl + , decorated_type_value_impl + >::type + >::type + >::type + >::type +// >::type + { + }; + +#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 + #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) +#else +// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get((void(*)(type))0) + #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) + //#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(type()) +#endif + +#endif + +}} + +#endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED diff --git a/include/luabind/detail/deduce_signature.hpp b/include/luabind/detail/deduce_signature.hpp new file mode 100644 index 0000000..e47e22f --- /dev/null +++ b/include/luabind/detail/deduce_signature.hpp @@ -0,0 +1,118 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !BOOST_PP_IS_ITERATING + +# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP +# define LUABIND_DEDUCE_SIGNATURE_080911_HPP + +# include + +# if LUABIND_MAX_ARITY <= 8 +# include +# else +# include +# endif +# include +# include +# include + +namespace luabind { namespace detail { + +namespace mpl = boost::mpl; + +template +mpl::vector1 deduce_signature(R(*)(), ...) +{ + return mpl::vector1(); +} + +template +mpl::vector2 deduce_signature(R(T::*)()) +{ + return mpl::vector2(); +} + +template +mpl::vector2::type&> +deduce_signature(R(T::*)(), Wrapped*) +{ + return mpl::vector2::type&>(); +} + +template +mpl::vector2 deduce_signature(R(T::*)() const) +{ + return mpl::vector2(); +} + +template +mpl::vector2::type const&> +deduce_signature(R(T::*)() const, Wrapped*) +{ + return mpl::vector2::type const&>(); +} + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (1, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}} // namespace luabind::detail + +# endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP + +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() +# define NPLUS1 BOOST_PP_INC(N) + +template +BOOST_PP_CAT(mpl::vector,NPLUS1) +deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS1)(); +} + +# define NPLUS2 BOOST_PP_INC(NPLUS1) + +template +BOOST_PP_CAT(mpl::vector,NPLUS2) +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A))) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)(); +} + +template +BOOST_PP_CAT(mpl::vector,NPLUS2)< + R, typename most_derived::type&, BOOST_PP_ENUM_PARAMS(N,A) +> +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)< + R,typename most_derived::type&,BOOST_PP_ENUM_PARAMS(N,A)>(); +} + +template +BOOST_PP_CAT(mpl::vector,NPLUS2) +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)(); +} + +template +BOOST_PP_CAT(mpl::vector,NPLUS2)< + R, typename most_derived::type const&, BOOST_PP_ENUM_PARAMS(N,A) +> +deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*) +{ + return BOOST_PP_CAT(mpl::vector,NPLUS2)< + R,typename most_derived::type const&,BOOST_PP_ENUM_PARAMS(N,A)>(); +} + +# undef NPLUS2 +# undef NPLUS1 +# undef N + +#endif // BOOST_PP_IS_ITERATING + diff --git a/include/luabind/detail/enum_maker.hpp b/include/luabind/detail/enum_maker.hpp new file mode 100644 index 0000000..9d5e261 --- /dev/null +++ b/include/luabind/detail/enum_maker.hpp @@ -0,0 +1,122 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_ENUM_MAKER_HPP_INCLUDED +#define LUABIND_ENUM_MAKER_HPP_INCLUDED + +#include +#include + +#include +#include + +namespace luabind +{ + struct value; + + struct value_vector : public std::vector + { + // a bug in intel's compiler forces us to declare these constructors explicitly. + value_vector(); + virtual ~value_vector(); + value_vector(const value_vector& v); + value_vector& operator,(const value& rhs); + }; + + struct value + { + friend class std::vector; + template + value(const char* name, T v) + : name_(name) + , val_(v) + {} + + const char* name_; + int val_; + + value_vector operator,(const value& rhs) const + { + value_vector v; + + v.push_back(*this); + v.push_back(rhs); + + return v; + } + + private: + + value() {} + }; + + inline value_vector::value_vector() + : std::vector() + { + } + + inline value_vector::~value_vector() {} + + inline value_vector::value_vector(const value_vector& rhs) + : std::vector(rhs) + { + } + + inline value_vector& value_vector::operator,(const value& rhs) + { + push_back(rhs); + return *this; + } + + namespace detail + { + template + struct enum_maker + { + explicit enum_maker(From& from): from_(from) {} + + From& operator[](const value& val) + { + from_.add_static_constant(val.name_, val.val_); + return from_; + } + + From& operator[](const value_vector& values) + { + for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i) + { + from_.add_static_constant(i->name_, i->val_); + } + + return from_; + } + + From& from_; + + private: + template void operator,(T const&) const; + }; + } +} + +#endif // LUABIND_ENUM_MAKER_HPP_INCLUDED diff --git a/include/luabind/detail/find_best_match.hpp b/include/luabind/detail/find_best_match.hpp new file mode 100644 index 0000000..2612e95 --- /dev/null +++ b/include/luabind/detail/find_best_match.hpp @@ -0,0 +1,59 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_FIND_BEST_MATCH_HPP_INCLUDED +#define LUABIND_FIND_BEST_MATCH_HPP_INCLUDED + +#include + +#include + +namespace luabind { namespace detail +{ + + // expects that a match function can be accesed through the iterator + // as int match_fun(lua_State*) + // returns true if it found a match better than the given. If it finds a + // better match match_index is updated to contain the new index to the best + // match (this index now refers to the list given to this call). + // orep_size is supposed to tell the size of the actual structures that + // start and end points to ambiguous is set to true if the match was + // ambiguous min_match should be initialized to the currently best match + // value (the number of implicit casts to get a perfect match). If there + // are no previous matches, set min_match to + // std::numeric_limits::max() + + LUABIND_API bool find_best_match(lua_State* L + , detail::overload_rep_base const* start, int num_overloads + , size_t orep_size, bool& ambiguous, int& min_match, int& match_index + , int num_params); + + LUABIND_API void find_exact_match(lua_State* L + , detail::overload_rep_base const* start, int num_overloads + , size_t orep_size, int cmp_match, int num_params + , std::vector& dest); + +}} + +#endif // LUABIND_FIND_BEST_MATCH_HPP_INCLUDED + diff --git a/include/luabind/detail/format_signature.hpp b/include/luabind/detail/format_signature.hpp new file mode 100644 index 0000000..df40ce1 --- /dev/null +++ b/include/luabind/detail/format_signature.hpp @@ -0,0 +1,136 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP +# define LUABIND_FORMAT_SIGNATURE_081014_HPP + +# include +# include + +# include +# include +# include + +namespace luabind { + +class object; +class argument; + +} // namespace luabind + +namespace luabind { namespace detail { + +LUABIND_API std::string get_class_name(lua_State* L, LUABIND_TYPE_INFO i); + +template +struct type_to_string +{ + static void get(lua_State* L) + { + lua_pushstring(L, get_class_name(L, LUABIND_TYPEID(T)).c_str()); + } +}; + +template +struct type_to_string +{ + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "*"); + lua_concat(L, 2); + } +}; + +template +struct type_to_string +{ + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "&"); + lua_concat(L, 2); + } +}; + +template +struct type_to_string +{ + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, " const"); + lua_concat(L, 2); + } +}; + +# define LUABIND_TYPE_TO_STRING(x) \ + template <> \ + struct type_to_string \ + { \ + static void get(lua_State* L) \ + { \ + lua_pushstring(L, #x); \ + } \ + }; + +# define LUABIND_INTEGRAL_TYPE_TO_STRING(x) \ + LUABIND_TYPE_TO_STRING(x) \ + LUABIND_TYPE_TO_STRING(unsigned x) + +LUABIND_INTEGRAL_TYPE_TO_STRING(char) +LUABIND_INTEGRAL_TYPE_TO_STRING(short) +LUABIND_INTEGRAL_TYPE_TO_STRING(int) +LUABIND_INTEGRAL_TYPE_TO_STRING(long) + +LUABIND_TYPE_TO_STRING(void) +LUABIND_TYPE_TO_STRING(bool) +LUABIND_TYPE_TO_STRING(std::string) +LUABIND_TYPE_TO_STRING(lua_State) + +LUABIND_TYPE_TO_STRING(luabind::object) +LUABIND_TYPE_TO_STRING(luabind::argument) + +# undef LUABIND_INTEGRAL_TYPE_TO_STRING +# undef LUABIND_TYPE_TO_STRING + +template +void format_signature_aux(lua_State*, bool, End, End) +{} + +template +void format_signature_aux(lua_State* L, bool first, Iter, End end) +{ + if (!first) + lua_pushstring(L, ","); + type_to_string::get(L); + format_signature_aux(L, false, typename mpl::next::type(), end); +} + +template +void format_signature(lua_State* L, char const* function, Signature) +{ + typedef typename mpl::begin::type first; + + type_to_string::get(L); + + lua_pushstring(L, " "); + lua_pushstring(L, function); + + lua_pushstring(L, "("); + format_signature_aux( + L + , true + , typename mpl::next::type() + , typename mpl::end::type() + ); + lua_pushstring(L, ")"); + + lua_concat(L, mpl::size() * 2 + 2); +} + +}} // namespace luabind::detail + +#endif // LUABIND_FORMAT_SIGNATURE_081014_HPP + diff --git a/include/luabind/detail/garbage_collector.hpp b/include/luabind/detail/garbage_collector.hpp new file mode 100644 index 0000000..c0d68aa --- /dev/null +++ b/include/luabind/detail/garbage_collector.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED +#define LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED + +#include + +namespace luabind { namespace detail +{ + // function that is used as __gc metafunction on several objects + template + inline int garbage_collector(lua_State* L) + { + T* obj = static_cast(lua_touserdata(L, -1)); + obj->~T(); + return 0; + } + + template + struct garbage_collector_s + { + static int apply(lua_State* L) + { + T* obj = static_cast(lua_touserdata(L, -1)); + obj->~T(); + return 0; + } + }; + +}} + +#endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED diff --git a/include/luabind/detail/get_overload_signature.hpp b/include/luabind/detail/get_overload_signature.hpp new file mode 100644 index 0000000..f4c151c --- /dev/null +++ b/include/luabind/detail/get_overload_signature.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_GET_OVERLOAD_SIGNATURE_HPP_INCLUDED +#define LUABIND_GET_OVERLOAD_SIGNATURE_HPP_INCLUDED + +#include + +namespace luabind { namespace detail +{ + + template + std::string get_overload_signatures(lua_State* L, It start, It end, std::string name) + { + std::string s; + for (; start != end; ++start) + { + s += name; + start->get_signature(L, s); + s += "\n"; + } + return s; + } + + +#ifndef LUABIND_NO_ERROR_CHECKING + + std::string get_overload_signatures_candidates(lua_State* L, std::vector::iterator start, std::vector::iterator end, std::string name); + +#endif + +}} + +#endif // LUABIND_GET_OVERLOAD_SIGNATURE_HPP_INCLUDED + diff --git a/include/luabind/detail/get_signature.hpp b/include/luabind/detail/get_signature.hpp new file mode 100644 index 0000000..6e33041 --- /dev/null +++ b/include/luabind/detail/get_signature.hpp @@ -0,0 +1,215 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_NO_ERROR_CHECKING + +#if !BOOST_PP_IS_ITERATING + +#ifndef LUABIND_GET_SIGNATURE_HPP_INCLUDED +#define LUABIND_GET_SIGNATURE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace luabind { namespace detail +{ + + std::string LUABIND_API get_class_name(lua_State* L, LUABIND_TYPE_INFO i); + + template + std::string name_of_type(by_value, lua_State* L, int) { return luabind::detail::get_class_name(L, LUABIND_TYPEID(T)); } + template + std::string name_of_type(by_reference, lua_State* L, int) { return name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "&"; } + template + std::string name_of_type(by_pointer, lua_State* L, int) { return name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "*"; } + template + std::string name_of_type(by_const_reference, lua_State* L, int) { return "const " + name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "&"; } + template + std::string name_of_type(by_const_pointer, lua_State* L, int) { return "const " + name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + "*"; } + + inline std::string name_of_type(by_value, lua_State*, int) { return "object"; } + inline std::string name_of_type(by_const_reference, lua_State*, int) { return "object"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "boolean"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + + inline std::string name_of_type(by_value, lua_State*, int) { return "boolean"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + inline std::string name_of_type(by_value, lua_State*, int) { return "number"; } + +// template +// inline std::string name_of_type(by_value >, lua_State* L, long) { return "function<" + name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L) + ">"; } + + inline std::string name_of_type(by_value, lua_State*, int) { return "string"; } + inline std::string name_of_type(by_const_pointer, lua_State*, int) { return "string"; } + inline std::string name_of_type(by_pointer, lua_State*, int) { return "lua_State*"; } + + template + struct type_name_unless_void + { + inline static void apply(std::string& s, lua_State* L, bool first) + { + if (!first) s += ", "; + s += name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L); + } + }; + + template<> + struct type_name_unless_void + { + inline static void apply(std::string&, lua_State*, bool) {} + }; + +#define LUABIND_ADD_LUA_TYPE_NAME(z, n, _) type_name_unless_void::apply(s, L, false); + + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + + template + struct get_member_signature + { + static inline void apply(lua_State* L, std::string& s) + { + get_member_signature_impl(static_cast(0), L, s); + } + }; + + template + struct get_free_function_signature + { + static inline void apply(lua_State* L, std::string& s) + { + get_free_function_signature_impl(static_cast(0), L, s); + } + }; + + + template + struct get_signature + { + static inline void apply(lua_State* L, std::string& s) + { + get_signature_impl(static_cast(0), L, s); + } + }; + + template + inline void get_signature_impl(const constructor*, lua_State* L, std::string& s) + { + s += "("; + type_name_unless_void::apply(s, L, true); + BOOST_PP_REPEAT(BOOST_PP_DEC(LUABIND_MAX_ARITY), LUABIND_ADD_LUA_TYPE_NAME, _) + s += ")"; + } + +#undef LUABIND_ADD_LUA_TYPE_NAME + + template + struct get_setter_signature + { + static void apply(lua_State* L, std::string& s) + { + s += "("; + s += name_of_type(LUABIND_DECORATE_TYPE(T), L, 0L); + s += ")"; + } + }; + +}} + +#endif // LUABIND_GET_SIGNATURE_HPP_INCLUDED + +#elif BOOST_PP_ITERATION_FLAGS() == 1 + + // member functions + template + inline void get_member_signature_impl(T(C::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), lua_State* L, std::string& s) + { + s += "("; +#if BOOST_PP_ITERATION() > 0 + s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); + BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) +#endif + s += ")"; + } + + template + inline void get_member_signature_impl(T(C::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)) const, lua_State* L, std::string& s) + { + (void)L; + s += "("; +#if BOOST_PP_ITERATION() > 0 + s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); + BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) +#endif + s += ") const"; + } + + // const C& obj + template + inline void get_member_signature_impl(T(*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), lua_State* L, std::string& s) + { + s += "("; +#if BOOST_PP_ITERATION() > 0 + s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); + BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) +#endif + s += ")"; + } + + // free functions + template + inline void get_free_function_signature_impl(T(*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), lua_State* L, std::string& s) + { + (void)f; + s += "("; +#if BOOST_PP_ITERATION() > 0 + s += name_of_type(LUABIND_DECORATE_TYPE(A0), L, 0L); + BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_ITERATION()), LUABIND_ADD_LUA_TYPE_NAME, _) +#endif + s += ")"; + } + +#endif + +#endif // LUABIND_NO_ERROR_CHECKING diff --git a/include/luabind/detail/has_get_pointer.hpp b/include/luabind/detail/has_get_pointer.hpp new file mode 100755 index 0000000..8a001dd --- /dev/null +++ b/include/luabind/detail/has_get_pointer.hpp @@ -0,0 +1,107 @@ +// Copyright (c) 2005 Daniel Wallin + +// 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 LUABIND_HAS_GET_POINTER_051022_HPP +# define LUABIND_HAS_GET_POINTER_051022_HPP + +# include + +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# include +# endif + +namespace luabind { namespace detail { + +namespace has_get_pointer_ +{ + + struct any + { + template any(T const&); + }; + + struct no_overload_tag + {}; + + typedef char (&yes)[1]; + typedef char (&no)[2]; + + no_overload_tag operator,(no_overload_tag, int); + +// +// On compilers with ADL, we need these generic overloads in this +// namespace as well as in luabind::. Otherwise get_pointer(any) +// will be found before them. +// +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + + template + T* get_pointer(T const volatile*); + + template + T* get_pointer(std::auto_ptr const&); + +# endif + +// +// On compilers that doesn't support ADL, the overload below has to +// live in luabind::. +// +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +}} // namespace detail::has_get_pointer_ +# endif + +detail::has_get_pointer_::no_overload_tag + get_pointer(detail::has_get_pointer_::any); + +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +namespace detail { namespace has_get_pointer_ +{ +# endif + + template + yes check(T const&); + no check(no_overload_tag); + + template + struct impl + { + static typename boost::add_reference::type x; + + BOOST_STATIC_CONSTANT(bool, + value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1 + ); + + typedef boost::mpl::bool_ type; + }; + +} // namespace has_get_pointer_ + +template +struct has_get_pointer + : has_get_pointer_::impl::type +{}; + +}} // namespace luabind::detail + +#endif // LUABIND_HAS_GET_POINTER_051022_HPP + diff --git a/include/luabind/detail/implicit_cast.hpp b/include/luabind/detail/implicit_cast.hpp new file mode 100644 index 0000000..e906289 --- /dev/null +++ b/include/luabind/detail/implicit_cast.hpp @@ -0,0 +1,51 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_IMPLICIT_CAST_HPP_INCLUDED +#define LUABIND_IMPLICIT_CAST_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail +{ + // returns -1 if there exists no implicit cast from the given class_rep + // to T. If there exists an implicit cast to T, the number of steps times 2 + // is returned and pointer_offset is filled with the number of bytes + // the pointer have to be offseted to perform the cast + // the reason why we return the number of cast-steps times two, instead of + // just the number of steps is to be consistent with the function matchers. They + // have to give one matching-point extra to match const functions. There may be + // two functions that match their parameters exactly, but there is one const + // function and one non-const function, then (if the this-pointer is non-const) + // both functions will match. To avoid amiguaties, the const version will get + // one penalty point to make the match-selector select the non-const version. It + // the this-pointer is const, there's no problem, since the non-const function + // will not match at all. + + LUABIND_API int implicit_cast(const class_rep*, LUABIND_TYPE_INFO const&, int&); + +}} + +#endif // LUABIND_IMPLICIT_CAST_HPP_INCLUDED + diff --git a/include/luabind/detail/is_indirect_const.hpp b/include/luabind/detail/is_indirect_const.hpp new file mode 100755 index 0000000..b6c1282 --- /dev/null +++ b/include/luabind/detail/is_indirect_const.hpp @@ -0,0 +1,70 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 IS_INDIRECT_CONST_040211_HPP +#define IS_INDIRECT_CONST_040211_HPP + +#include +#include +#include + +namespace luabind { + + namespace detail { + + template + typename boost::is_const::type + is_indirect_const_check(T(*)(), int); + + template + typename boost::is_const::type + is_indirect_const_check(T*(*)(), long); + + template + typename boost::is_const::type + is_indirect_const_check(T&(*)(), long); + + yes_t to_yes_no(boost::mpl::true_); + no_t to_yes_no(boost::mpl::false_); + + } // namespace detail + + // returns true for: + // T = U* is_const + // T = U& is_const + // T = U is_const + template + struct is_indirect_const + { + BOOST_STATIC_CONSTANT(int, value = ( + sizeof( + detail::to_yes_no( + detail::is_indirect_const_check((T(*)())0, 0L) + )) + == sizeof(detail::yes_t) + )); + }; + +} // namespace luabind + +#endif // IS_INDIRECT_CONST_040211_HPP + diff --git a/include/luabind/detail/link_compatibility.hpp b/include/luabind/detail/link_compatibility.hpp new file mode 100755 index 0000000..6f0006a --- /dev/null +++ b/include/luabind/detail/link_compatibility.hpp @@ -0,0 +1,60 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_LINK_COMPATIBILITY_HPP_INCLUDED +#define LUABIND_LINK_COMPATIBILITY_HPP_INCLUDED + +#include + +namespace luabind { namespace detail +{ + +#ifdef LUABIND_NOT_THREADSAFE + LUABIND_API void not_threadsafe_defined_conflict(); +#else + LUABIND_API void not_threadsafe_not_defined_conflict(); +#endif + +#ifdef LUABIND_NO_ERROR_CHECKING + LUABIND_API void no_error_checking_defined_conflict(); +#else + LUABIND_API void no_error_checking_not_defined_conflict(); +#endif + + inline void check_link_compatibility() + { + #ifdef LUABIND_NOT_THREADSAFE + not_threadsafe_defined_conflict(); + #else + not_threadsafe_not_defined_conflict(); + #endif + + #ifdef LUABIND_NO_ERROR_CHECKING + no_error_checking_defined_conflict(); + #else + no_error_checking_not_defined_conflict(); + #endif + } + +}} + +#endif diff --git a/include/luabind/detail/most_derived.hpp b/include/luabind/detail/most_derived.hpp new file mode 100755 index 0000000..4dd9d91 --- /dev/null +++ b/include/luabind/detail/most_derived.hpp @@ -0,0 +1,44 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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 MOST_DERIVED_051018_HPP +# define MOST_DERIVED_051018_HPP + +# include +# include + +namespace luabind { namespace detail { + +template +struct most_derived +{ + typedef typename boost::mpl::if_< + boost::is_base_and_derived + , WrappedClass + , Class + >::type type; +}; + +}} // namespace luabind::detail + +#endif // MOST_DERIVED_051018_HPP + diff --git a/include/luabind/detail/object_call.hpp b/include/luabind/detail/object_call.hpp new file mode 100755 index 0000000..46ab0d9 --- /dev/null +++ b/include/luabind/detail/object_call.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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. + +#if !BOOST_PP_IS_ITERATING +# error Do not include object_call.hpp directly! +#endif + +#include +#include +#include + +#define N BOOST_PP_ITERATION() + +template +call_proxy< + Derived + , boost::tuples::tuple< + BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) + > +> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) +{ + typedef boost::tuples::tuple< + BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) + > arguments; + + return call_proxy( + derived() + , arguments(BOOST_PP_ENUM_PARAMS(N, &a)) + ); +} + +#undef N + diff --git a/include/luabind/detail/object_funs.hpp b/include/luabind/detail/object_funs.hpp new file mode 100644 index 0000000..bfecf12 --- /dev/null +++ b/include/luabind/detail/object_funs.hpp @@ -0,0 +1,224 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OBJECT_PROXY_HPP_INCLUDED +#define LUABIND_OBJECT_PROXY_HPP_INCLUDED + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace luabind +{ + + namespace detail + { + + namespace mpl = boost::mpl; + + template + inline T object_cast_impl(const Obj& obj, const Policies&) + { + if (obj.lua_state() == 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(0, LUABIND_TYPEID(T)); +#else + lua_State* L = obj.lua_state(); + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, LUABIND_TYPEID(T)); + + assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + LUABIND_CHECK_STACK(obj.lua_state()); + + typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + obj.pushvalue(); + + lua_State* L = obj.lua_state(); + detail::stack_pop p(L, 1); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, LUABIND_TYPEID(T)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(L, LUABIND_TYPEID(T)); + + assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } +#endif + + return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1); + } + + template + boost::optional object_cast_nothrow_impl(const Obj& obj, const Policies&) + { + typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + + if (obj.lua_state() == 0) return boost::optional(); + LUABIND_CHECK_STACK(obj.lua_state()); + + obj.pushvalue(); + + lua_State* L = obj.lua_state(); + detail::stack_pop p(L, 1); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) + return boost::optional(); +#endif + + return boost::optional(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1)); + } + } + + template + T object_cast(const object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + template + T object_cast(const detail::proxy_object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const detail::proxy_object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const detail::proxy_object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const detail::proxy_object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + template + T object_cast(const detail::proxy_raw_object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const detail::proxy_raw_object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + template + T object_cast(const detail::proxy_array_object& obj) + { return detail::object_cast_impl(obj, detail::null_type()); } + + template + T object_cast(const detail::proxy_array_object& obj, const Policies& p) + { return detail::object_cast_impl(obj, p); } + + template + boost::optional object_cast_nothrow(const detail::proxy_array_object& obj) + { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } + + template + boost::optional object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p) + { return detail::object_cast_nothrow_impl(obj, p); } + + + + + inline object get_globals(lua_State* L) + { + lua_pushvalue(L, LUA_GLOBALSINDEX); + detail::lua_reference ref; + ref.set(L); + return object(L, ref, true/*object::reference()*/); + } + + inline object get_registry(lua_State* L) + { + lua_pushvalue(L, LUA_REGISTRYINDEX); + detail::lua_reference ref; + ref.set(L); + return object(L, ref, true/*object::reference()*/); + } + + inline object newtable(lua_State* L) + { + lua_newtable(L); + detail::lua_reference ref; + ref.set(L); + return object(L, ref, true/*object::reference()*/); + } +} + +/* + +struct A +{ +}; + +object f = class_(); + +A* ptr = object_cast(f(), adopt(_1)); + +delete ptr; + +*/ + +#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED diff --git a/include/luabind/detail/object_rep.hpp b/include/luabind/detail/object_rep.hpp new file mode 100644 index 0000000..8c65e3f --- /dev/null +++ b/include/luabind/detail/object_rep.hpp @@ -0,0 +1,131 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OBJECT_REP_HPP_INCLUDED +#define LUABIND_OBJECT_REP_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail +{ + class class_rep; + + void finalize(lua_State* L, class_rep* crep); + + // this class is allocated inside lua for each pointer. + // it contains the actual c++ object-pointer. + // it also tells if it is const or not. + class LUABIND_API object_rep + { + public: + enum { constant = 1, owner = 2, lua_class = 4, call_super = 8 }; + + // dest is a function that is called to delete the c++ object this struct holds + object_rep(void* obj, class_rep* crep, int flags, void(*dest)(void*)); + object_rep(class_rep* crep, int flags, detail::lua_reference const& table_ref); + ~object_rep(); + + void* ptr() const { return m_object; } + + void* ptr(int pointer_offset) const + { + return reinterpret_cast(m_object) + pointer_offset; + } + + const class_rep* crep() const { return m_classrep; } + class_rep* crep() { return m_classrep; } + int flags() const { return m_flags; } + void set_flags(int flags) { m_flags = flags; } + + detail::lua_reference& get_lua_table() { return m_lua_table_ref; } + detail::lua_reference const& get_lua_table() const { return m_lua_table_ref; } + + void remove_ownership(); + void set_destructor(void(*ptr)(void*)); + + void set_object(void* p) { m_object = p; } + + void add_dependency(lua_State* L, int index); + + static int garbage_collector(lua_State* L); + + private: + + void* m_object; // pointer to the c++ object or holder / if lua class, this is a pointer the the instance of the + // c++ base or 0. + class_rep* m_classrep; // the class information about this object's type + int m_flags; + detail::lua_reference m_lua_table_ref; // reference to lua table if this is a lua class + void(*m_destructor)(void*); // this could be in class_rep? it can't: see intrusive_ptr + int m_dependency_cnt; // counts dependencies + detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references + + // ======== the new way, separate object_rep from the holder +// instance_holder* m_instance; + }; + + template + struct delete_s + { + static void apply(void* ptr) + { + delete static_cast(ptr); + } + }; + + template + struct destruct_only_s + { + static void apply(void* ptr) + { + // Removes unreferenced formal parameter warning on VC7. + (void)ptr; +#ifndef NDEBUG + int completeness_check[sizeof(T)]; + (void)completeness_check; +#endif + static_cast(ptr)->~T(); + } + }; + + + inline object_rep* is_class_object(lua_State* L, int index) + { + object_rep* obj = static_cast(lua_touserdata(L, index)); + if (!obj) return 0; + if (lua_getmetatable(L, index) == 0) return 0; + + lua_pushstring(L, "__luabind_class"); + lua_gettable(L, -2); + bool confirmation = lua_toboolean(L, -1) != 0; + lua_pop(L, 2); + if (!confirmation) return 0; + return obj; + + } + +}} + +#endif // LUABIND_OBJECT_REP_HPP_INCLUDED + diff --git a/include/luabind/detail/open.hpp b/include/luabind/detail/open.hpp new file mode 100644 index 0000000..a30faee --- /dev/null +++ b/include/luabind/detail/open.hpp @@ -0,0 +1,45 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OPEN_HPP_INCLUDED +#define LUABIND_OPEN_HPP_INCLUDED + +#include + +namespace luabind +{ + namespace detail + { + LUABIND_API void add_operator_to_metatable(lua_State* L, int op_index); + LUABIND_API int create_cpp_class_metatable(lua_State* L); + LUABIND_API int create_cpp_instance_metatable(lua_State* L); + LUABIND_API int create_lua_class_metatable(lua_State* L); + LUABIND_API int create_lua_instance_metatable(lua_State* L); + LUABIND_API int create_lua_function_metatable(lua_State* L); + } + + LUABIND_API void open(lua_State* L); +} + +#endif // LUABIND_OPEN_HPP_INCLUDED + diff --git a/include/luabind/detail/operator_id.hpp b/include/luabind/detail/operator_id.hpp new file mode 100644 index 0000000..ed64ba6 --- /dev/null +++ b/include/luabind/detail/operator_id.hpp @@ -0,0 +1,79 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OPERATOR_ID_HPP_INCLUDED +#define LUABIND_OPERATOR_ID_HPP_INCLUDED + +#include + +namespace luabind { namespace detail { + + enum operator_id + { + op_add = 0, + op_sub, + op_mul, + op_div, + op_pow, + op_lt, + op_le, + op_eq, + op_call, + op_unm, + op_tostring, + op_concat, + op_len, + + number_of_operators + }; + + inline const char* get_operator_name(int i) + { + static const char* a[number_of_operators] = { + "__add", "__sub", "__mul", "__div", "__pow", + "__lt", "__le", "__eq", "__call", "__unm", + "__tostring", "__concat", "__len" }; + return a[i]; + } + + inline const char* get_operator_symbol(int i) + { + static const char* a[number_of_operators] = { + "+", "-", "*", "/", "^", "<", + "<=", "==", "()", "- (unary)", + "tostring", "..", "#" }; + return a[i]; + } + + inline bool is_unary(int i) + { + // the reason why unary minus is not considered a unary operator here is + // that it always is given two parameters, where the second parameter always + // is nil. + return i == op_tostring; + } + + +}} + +#endif // LUABIND_OPERATOR_ID_HPP_INCLUDED diff --git a/include/luabind/detail/other.hpp b/include/luabind/detail/other.hpp new file mode 100644 index 0000000..679058c --- /dev/null +++ b/include/luabind/detail/other.hpp @@ -0,0 +1,119 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OTHER_HPP_INCLUDED +#define LUABIND_OTHER_HPP_INCLUDED + +// header derived from source code found in Boost.Python + +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include + +namespace luabind +{ + template + struct other + { + typedef T type; + }; +} + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace luabind { namespace detail +{ + template + class unwrap_other + { + public: + typedef T type; + }; + + template + class unwrap_other > + { + public: + typedef T type; + }; +}} // namespace luabind::detail + +# else // no partial specialization + +#include + +namespace luabind { namespace detail +{ + typedef char (&yes_other_t)[1]; + typedef char (&no_other_t)[2]; + + no_other_t is_other_test(...); + + template + yes_other_t is_other_test(type_< other >); + + template + struct other_unwrapper + { + template + struct apply + { + typedef T type; + }; + }; + + template<> + struct other_unwrapper + { + template + struct apply + { + typedef typename T::type type; + }; + }; + + template + class is_other + { + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_other_test(type_())) + == sizeof(detail::yes_other_t))); + }; + + template + class unwrap_other + : public detail::other_unwrapper< + is_other::value + >::template apply + {}; + +}} // namespace luabind::detail +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // LUABIND_OTHER_HPP_INCLUDED diff --git a/include/luabind/detail/overload_rep.hpp b/include/luabind/detail/overload_rep.hpp new file mode 100644 index 0000000..483b2fc --- /dev/null +++ b/include/luabind/detail/overload_rep.hpp @@ -0,0 +1,141 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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. + + +#if !BOOST_PP_IS_ITERATING + +#ifndef LUABIND_OVERLOAD_REP_HPP_INCLUDED +#define LUABIND_OVERLOAD_REP_HPP_INCLUDED + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#ifndef BOOST_MSVC +#include +#endif + +namespace luabind { namespace detail +{ + struct dummy_ {}; + + // this class represents a specific overload of a member-function. + struct overload_rep: public overload_rep_base + { + #define BOOST_PP_ITERATION_PARAMS_1 (4 \ + , (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + + bool operator==(const overload_rep& o) + { + if (o.m_const != m_const) return false; + if (o.m_arity != m_arity) return false; + if (o.m_params_.size() != m_params_.size()) return false; + for (int i = 0; i < (int)m_params_.size(); ++i) + { + if (!(LUABIND_TYPE_INFO_EQUAL(m_params_[i], o.m_params_[i]))) + return false; + } + return true; + } + + void set_fun(boost::function1 const& f) + { call_fun = f; } + + void set_fun_static(boost::function1 const& f) + { call_fun_static = f; } + + int call(lua_State* L, bool force_static_call) const; + + bool has_static() const { return !call_fun_static.empty(); } + + private: + + // this is the normal function pointer that may be a virtual + boost::function1 call_fun; + + // this is the optional function pointer that is only set if + // the first function pointer is virtual. This must always point + // to a static function. + boost::function1 call_fun_static; + + // the types of the parameter it takes + std::vector m_params_; + // is true if the overload is const (this is a part of the signature) + bool m_const; + }; + +}} // namespace luabind::detail + +#endif // LUABIND_OVERLOAD_REP_HPP_INCLUDED + +#elif BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_PARAM(z, n, _) m_params_.push_back(LUABIND_TYPEID(A##n)); +#define LUABIND_POLICY_DECL(z,n,offset) typedef typename detail::find_conversion_policy::type BOOST_PP_CAT(p,n); +#define LUABIND_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg + + // overloaded template funtion that initializes the parameter list + // called m_params and the m_arity member. + template + overload_rep(R(T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), Policies*) + : m_const(false) + { + m_params_.reserve(BOOST_PP_ITERATION()); + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_PARAM, _) + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POLICY_DECL, 2) + m_arity = 1 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_ARITY, 0); + } + + template + overload_rep(R(T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)) const, Policies*) + : m_const(true) + { + m_params_.reserve(BOOST_PP_ITERATION()); + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_PARAM, _) + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POLICY_DECL, 2) + m_arity = 1 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_ARITY, 0); + } + + template + overload_rep(R(*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), Policies*) + : m_const(false/*is_indirect_const::value*/) + { + m_params_.reserve(BOOST_PP_ITERATION()); + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_PARAM, _) + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POLICY_DECL, 1) + m_arity = 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_ARITY, 0); + } + +#undef LUABIND_ARITY +#undef LUABIND_POLICY_DECL +#undef LUABIND_PARAM + +#endif diff --git a/include/luabind/detail/overload_rep_base.hpp b/include/luabind/detail/overload_rep_base.hpp new file mode 100644 index 0000000..774461f --- /dev/null +++ b/include/luabind/detail/overload_rep_base.hpp @@ -0,0 +1,81 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OVERLOAD_REP_BASE_HPP_INCLUDED +#define LUABIND_OVERLOAD_REP_BASE_HPP_INCLUDED + +#include +#include + +struct lua_State; + +namespace luabind { namespace detail +{ + // this class represents a specific overload of a member-function. + struct overload_rep_base + { +#if !defined(NDEBUG) && !defined(LUABIND_NO_ERROR_CHECKING) + overload_rep_base(): m_get_signature_fun(0), m_match_fun(0), m_arity(-1) {} +#else + overload_rep_base(): m_match_fun(0), m_arity(-1) {} +#endif + + typedef boost::function1 match_fun_t; + typedef void(*get_sig_ptr)(lua_State*, std::string&); + + inline int match(lua_State* L, int num_params) const + { + if (num_params != m_arity) return -1; + return m_match_fun(L); + } + + inline void set_match_fun(match_fun_t const& fn) + { + m_match_fun = fn; + } + +#ifndef LUABIND_NO_ERROR_CHECKING + inline void get_signature(lua_State* L, std::string& s) const + { + m_get_signature_fun(L, s); + } + + inline void set_sig_fun(get_sig_ptr f) + { + m_get_signature_fun = f; + } +#endif + + protected: + +#ifndef LUABIND_NO_ERROR_CHECKING + get_sig_ptr m_get_signature_fun; +#endif + +// match_ptr m_match_fun; + match_fun_t m_match_fun; + int m_arity; + }; + +}} // namespace luabind::detail + +#endif // LUABIND_OVERLOAD_REP_BASE_HPP_INCLUDED diff --git a/include/luabind/detail/pcall.hpp b/include/luabind/detail/pcall.hpp new file mode 100755 index 0000000..f0d72b1 --- /dev/null +++ b/include/luabind/detail/pcall.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_PCALL_HPP_INCLUDED +#define LUABIND_PCALL_HPP_INCLUDED + +#include + +struct lua_State; + +namespace luabind { namespace detail +{ + LUABIND_API int pcall(lua_State *L, int nargs, int nresults); + LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); +}} + +#endif diff --git a/include/luabind/detail/pointee_sizeof.hpp b/include/luabind/detail/pointee_sizeof.hpp new file mode 100755 index 0000000..3875c09 --- /dev/null +++ b/include/luabind/detail/pointee_sizeof.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 POINTEE_SIZEOF_040211_HPP +#define POINTEE_SIZEOF_040211_HPP + +#include + +namespace luabind { + + namespace detail { + + template T& deref_type(T(*)(), int); + template T& deref_type(T*(*)(), long); + + } // namespace detail + + // returns the indirect sizeof U, as in + // sizeof(T*) = sizeof(T) + // sizeof(T&) = sizeof(T) + // sizeof(T) = sizeof(T) + template + struct pointee_sizeof + { + BOOST_STATIC_CONSTANT(int, value = ( + sizeof(detail::deref_type((T(*)())0), 0L) + )); + + typedef boost::mpl::int_ type; + }; + +} // namespace luabind + +#endif // POINTEE_SIZEOF_040211_HPP + diff --git a/include/luabind/detail/pointee_typeid.hpp b/include/luabind/detail/pointee_typeid.hpp new file mode 100755 index 0000000..3db2399 --- /dev/null +++ b/include/luabind/detail/pointee_typeid.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2004 Daniel Wallin + +// 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 POINTEE_TYPEID_040211_HPP +#define POINTEE_TYPEID_040211_HPP + +#include + +namespace luabind { namespace detail { + + template + LUABIND_TYPE_INFO pointee_typeid(T*) + { + return LUABIND_TYPEID(T); + } + +}} // namespace luabind::detail + +#endif // POINTEE_TYPEID_040211_HPP + diff --git a/include/luabind/detail/policy.hpp b/include/luabind/detail/policy.hpp new file mode 100644 index 0000000..c0475f7 --- /dev/null +++ b/include/luabind/detail/policy.hpp @@ -0,0 +1,1069 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_POLICY_HPP_INCLUDED +#define LUABIND_POLICY_HPP_INCLUDED + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +namespace luabind +{ + namespace detail + { + struct conversion_policy_base {}; + } + + template + struct conversion_policy : detail::conversion_policy_base + { + BOOST_STATIC_CONSTANT(int, index = N); + BOOST_STATIC_CONSTANT(bool, has_arg = HasArg); + }; + + class index_map + { + public: + index_map(const int* m): m_map(m) {} + + int operator[](int index) const + { + return m_map[index]; + } + + private: + const int* m_map; + }; + + namespace detail + { + + LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset); + } + +// template class functor; + class weak_ref; +} + +namespace luabind { namespace detail +{ + template + struct policy_cons + { + typedef H head; + typedef T tail; + + template + policy_cons > operator,(policy_cons) + { + return policy_cons >(); + } + + template + policy_cons > operator+(policy_cons) + { + return policy_cons >(); + } + + template + policy_cons > operator|(policy_cons) + { + return policy_cons >(); + } + }; + + struct indirection_layer + { + template + indirection_layer(const T&); + }; + + yes_t is_policy_cons_test(const null_type&); + template + yes_t is_policy_cons_test(const policy_cons&); + no_t is_policy_cons_test(...); + + template + struct is_policy_cons + { + static const T& t; + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(is_policy_cons_test(t)) == sizeof(yes_t)); + + typedef boost::mpl::bool_ type; + }; + + template + struct is_string_literal + { + static no_t helper(indirection_layer); + static yes_t helper(const char*); + }; + + template<> + struct is_string_literal + { + static no_t helper(indirection_layer); + }; + + + namespace mpl = boost::mpl; + +// ********** pointer converter *********** + + struct pointer_converter + { + typedef pointer_converter type; + typedef mpl::false_ is_native; + + template + void apply(lua_State* L, T* ptr) + { + if (ptr == 0) + { + lua_pushnil(L); + return; + } + + if (luabind::get_back_reference(L, ptr)) + return; + + class_rep* crep = get_class_rep(L); + + // if you get caught in this assert you are + // trying to use an unregistered type + assert(crep && "you are trying to use an unregistered type"); + + // create the struct to hold the object + void* obj = lua_newuserdata(L, sizeof(object_rep)); + //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s::apply); + new(obj) object_rep(ptr, crep, 0, 0); + + // set the meta table + detail::getref(L, crep->metatable_ref()); + lua_setmetatable(L, -2); + } + + conversion_storage storage; + + template + T* apply(lua_State* L, by_pointer, int index) + { + // preconditions: + // lua_isuserdata(L, index); + // getmetatable().__lua_class is true + // object_rep->flags() & object_rep::constant == 0 + + if (lua_isnil(L, index)) return 0; + + object_rep* obj = static_cast(lua_touserdata(L, index)); + assert((obj != 0) && "internal error, please report"); // internal error + const class_rep* crep = obj->crep(); + + return static_cast(crep->convert_to(LUABIND_TYPEID(T), obj, storage)); + } + + template + static int match(lua_State* L, by_pointer, int index) + { + if (lua_isnil(L, index)) return 0; + object_rep* obj = is_class_object(L, index); + if (obj == 0) return -1; + // cannot cast a constant object to nonconst + if (obj->flags() & object_rep::constant) return -1; + + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?-1:0; + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?0:1; + + int d; + return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d); + } + + template + void converter_postcall(lua_State*, by_pointer, int) + {} + }; + +// ******* value converter ******* + + struct value_converter + { + typedef value_converter type; + typedef mpl::false_ is_native; + + template + void apply(lua_State* L, const T& ref) + { + if (luabind::get_back_reference(L, ref)) + return; + + class_rep* crep = get_class_rep(L); + + // if you get caught in this assert you are + // trying to use an unregistered type + assert(crep && "you are trying to use an unregistered type"); + + void* obj_rep; + void* held; + + boost::tie(obj_rep,held) = crep->allocate(L); + + void* object_ptr; + void(*destructor)(void*); + destructor = crep->destructor(); + int flags = object_rep::owner; + if (crep->has_holder()) + { + if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type())) + { + new(held) T(ref); + object_ptr = held; + flags |= object_rep::constant; + destructor = crep->const_holder_destructor(); + } + else if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->holder_type())) + { + new(held) T(ref); + object_ptr = held; + } + else + { + assert(LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->type())); + std::auto_ptr obj(new T(ref)); + crep->construct_holder()(held, obj.get()); + object_ptr = held; + obj.release(); + } + } + else + { + object_ptr = new T(ref); + } + new(obj_rep) object_rep(object_ptr, crep, flags, destructor); + + // set the meta table + detail::getref(L, crep->metatable_ref()); + lua_setmetatable(L, -2); + } + + conversion_storage storage; + + template + T apply(lua_State* L, by_value, int index) + { + // preconditions: + // lua_isuserdata(L, index); + // getmetatable().__lua_class is true + // object_rep->flags() & object_rep::constant == 0 + + object_rep* obj = 0; + const class_rep* crep = 0; + + // special case if we get nil in, try to convert the holder type + if (lua_isnil(L, index)) + { + crep = get_class_rep(L); + assert(crep); + } + else + { + obj = static_cast(lua_touserdata(L, index)); + assert((obj != 0) && "internal error, please report"); // internal error + crep = obj->crep(); + } + assert(crep); + + return *static_cast(crep->convert_to(LUABIND_TYPEID(T), obj, storage)); + } + + template + static int match(lua_State* L, by_value, int index) + { + // special case if we get nil in, try to match the holder type + if (lua_isnil(L, index)) + { + class_rep* crep = get_class_rep(L); + if (crep == 0) return -1; + if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T)))) + return 0; + if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T)))) + return 0; + return -1; + } + + object_rep* obj = is_class_object(L, index); + if (obj == 0) return -1; + int d; + + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?-1:0; + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?0:1; + + return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d); + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + +// ******* const pointer converter ******* + + struct const_pointer_converter : pointer_converter + { + typedef const_pointer_converter type; + + template + void apply(lua_State* L, const T* ptr) + { + if (ptr == 0) + { + lua_pushnil(L); + return; + } + + if (luabind::get_back_reference(L, ptr)) + return; + + class_rep* crep = get_class_rep(L); + + // if you get caught in this assert you are + // trying to use an unregistered type + assert(crep && "you are trying to use an unregistered type"); + + // create the struct to hold the object + void* obj = lua_newuserdata(L, sizeof(object_rep)); + assert(obj && "internal error, please report"); + // we send 0 as destructor since we know it will never be called + new(obj) object_rep(const_cast(ptr), crep, object_rep::constant, 0); + + // set the meta table + detail::getref(L, crep->metatable_ref()); + lua_setmetatable(L, -2); + } + + template + T const* apply(lua_State* L, by_const_pointer, int index) + { + return pointer_converter::apply(L, by_pointer(), index); + } + + template + static int match(lua_State* L, by_const_pointer, int index) + { + if (lua_isnil(L, index)) return 0; + object_rep* obj = is_class_object(L, index); + if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match + + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?-1:0; + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?0:1; + + bool const_ = obj->flags() & object_rep::constant; + int d; + int points = implicit_cast(obj->crep(), LUABIND_TYPEID(T), d); + return points == -1 ? -1 : points + !const_; + } + + template + void converter_postcall(lua_State* L, by_const_pointer, int index) + { + pointer_converter::converter_postcall(L, by_pointer(), index); + } + }; + +// ******* reference converter ******* + + struct ref_converter + { + typedef ref_converter type; + typedef mpl::false_ is_native; + + template + void apply(lua_State* L, T& ref) + { + if (luabind::get_back_reference(L, ref)) + return; + + class_rep* crep = get_class_rep(L); + + // if you get caught in this assert you are + // trying to use an unregistered type + assert(crep && "you are trying to use an unregistered type"); + + T* ptr = &ref; + + // create the struct to hold the object + void* obj = lua_newuserdata(L, sizeof(object_rep)); + assert(obj && "internal error, please report"); + new(obj) object_rep(ptr, crep, 0, 0); + + // set the meta table + detail::getref(L, crep->metatable_ref()); + lua_setmetatable(L, -2); + } + + template + T& apply(lua_State* L, by_reference, int index) + { + assert(!lua_isnil(L, index)); + return *pointer_converter().apply(L, by_pointer(), index); + } + + template + static int match(lua_State* L, by_reference, int index) + { + if (lua_isnil(L, index)) return -1; + return pointer_converter::match(L, by_pointer(), index); + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + +// ******** const reference converter ********* + + struct const_ref_converter + { + typedef const_ref_converter type; + typedef mpl::false_ is_native; + + template + void apply(lua_State* L, T const& ref) + { + if (luabind::get_back_reference(L, ref)) + return; + + class_rep* crep = get_class_rep(L); + + // if you get caught in this assert you are + // trying to use an unregistered type + assert(crep && "you are trying to use an unregistered type"); + + T const* ptr = &ref; + + // create the struct to hold the object + void* obj = lua_newuserdata(L, sizeof(object_rep)); + assert(obj && "internal error, please report"); + new(obj) object_rep(const_cast(ptr), crep, object_rep::constant, 0); + + // set the meta table + detail::getref(L, crep->metatable_ref()); + lua_setmetatable(L, -2); + } + + conversion_storage storage; + + template + T const& apply(lua_State* L, by_const_reference, int index) + { + object_rep* obj = 0; + class_rep const * crep = 0; + + // special case if we get nil in, try to convert the holder type + if (lua_isnil(L, index)) + { + crep = get_class_rep(L); + assert(crep); + } + else + { + obj = static_cast(lua_touserdata(L, index)); + assert((obj != 0) && "internal error, please report"); // internal error + crep = obj->crep(); + } + assert(crep); + + return *static_cast(crep->convert_to(LUABIND_TYPEID(T), obj, storage)); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + // special case if we get nil in, try to match the holder type + if (lua_isnil(L, index)) + { + class_rep* crep = get_class_rep(L); + if (crep == 0) return -1; + if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T)))) + return 0; + if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T)))) + return 0; + return -1; + } + + object_rep* obj = is_class_object(L, index); + if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match + + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?-1:0; + if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T)))) + return (obj->flags() & object_rep::constant)?0:1; + + bool const_ = obj->flags() & object_rep::constant; + int d; + int points = implicit_cast(obj->crep(), LUABIND_TYPEID(T), d); + return points == -1 ? -1 : points + !const_; + } + + template + void converter_postcall(lua_State* L, by_const_reference, int index) + { + } + }; + + // ****** enum converter ******** + + struct enum_converter + { + typedef enum_converter type; + typedef mpl::true_ is_native; + + void apply(lua_State* L, int val) + { + lua_pushnumber(L, val); + } + + template + T apply(lua_State* L, by_value, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_value, int index) + { + if (lua_isnumber(L, index)) return 0; else return -1; + } + + template + T apply(lua_State* L, by_const_reference, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + if (lua_isnumber(L, index)) return 0; else return -1; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + template + struct value_wrapper_converter + { + typedef value_wrapper_converter type; + typedef mpl::true_ is_native; + + template + T apply(lua_State* L, by_const_reference, int index) + { + return T(from_stack(L, index)); + } + + template + T apply(lua_State* L, by_value, int index) + { + return apply(L, by_const_reference(), index); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + return value_wrapper_traits::check(L, index) + ? (std::numeric_limits::max)() / LUABIND_MAX_ARITY + : -1; + } + + template + static int match(lua_State* L, by_value, int index) + { + return match(L, by_const_reference(), index); + } + + void converter_postcall(...) {} + + template + void apply(lua_State* interpreter, T const& value_wrapper) + { + value_wrapper_traits::unwrap(interpreter, value_wrapper); + } + }; + + template + struct default_converter_generator + : mpl::eval_if< + is_value_wrapper_arg + , value_wrapper_converter + , mpl::eval_if< + boost::is_enum::type> + , enum_converter + , mpl::eval_if< + is_nonconst_pointer + , pointer_converter + , mpl::eval_if< + is_const_pointer + , const_pointer_converter + , mpl::eval_if< + is_nonconst_reference + , ref_converter + , mpl::eval_if< + is_const_reference + , const_ref_converter + , value_converter + > + > + > + > + > + > + {}; + +} // namespace detail + +// *********** default_policy ***************** + +template +struct default_converter + : detail::default_converter_generator::type +{}; + +template > +struct native_converter_base +{ + typedef boost::mpl::true_ is_native; + + template + void converter_postcall(lua_State*, U const&, int) + {} + + static int match(lua_State* L, detail::by_value, int index) + { + return Derived::compute_score(L, index); + } + + static int match(lua_State* L, detail::by_value, int index) + { + return Derived::compute_score(L, index); + } + + static int match(lua_State* L, detail::by_const_reference, int index) + { + return Derived::compute_score(L, index); + } + + T apply(lua_State* L, detail::by_value, int index) + { + return derived().from(L, index); + } + + T apply(lua_State* L, detail::by_value, int index) + { + return derived().from(L, index); + } + + T apply(lua_State* L, detail::by_const_reference, int index) + { + return derived().from(L, index); + } + + void apply(lua_State* L, T const& value) + { + derived().to(L, value); + } + + Derived& derived() + { + return static_cast(*this); + } +}; + +# define LUABIND_NUMBER_CONVERTER(type) \ + template <> \ +struct default_converter \ + : native_converter_base \ +{ \ + static int compute_score(lua_State* L, int index) \ + { \ + return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \ + }; \ + \ + type from(lua_State* L, int index) \ + { \ + return static_cast(lua_tonumber(L, index)); \ + } \ + \ + void to(lua_State* L, type const& value) \ + { \ + lua_pushnumber(L, static_cast(value)); \ + } \ +}; \ +\ +template <> \ +struct default_converter \ + : default_converter \ +{}; \ +\ +template <> \ +struct default_converter \ + : default_converter \ +{}; + +LUABIND_NUMBER_CONVERTER(char) +LUABIND_NUMBER_CONVERTER(signed char) +LUABIND_NUMBER_CONVERTER(short) +LUABIND_NUMBER_CONVERTER(unsigned short) +LUABIND_NUMBER_CONVERTER(int) +LUABIND_NUMBER_CONVERTER(unsigned int) +LUABIND_NUMBER_CONVERTER(long) +LUABIND_NUMBER_CONVERTER(unsigned long) +LUABIND_NUMBER_CONVERTER(float) +LUABIND_NUMBER_CONVERTER(double) +LUABIND_NUMBER_CONVERTER(long double) + +# undef LUABIND_NUMBER_CONVERTER + +template <> +struct default_converter + : native_converter_base +{ + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1; + } + + bool from(lua_State* L, int index) + { + return lua_toboolean(L, index) == 1; + } + + void to(lua_State* L, bool value) + { + lua_pushboolean(L, value); + } +}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : native_converter_base +{ + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TSTRING ? 0 : -1; + } + + std::string from(lua_State* L, int index) + { + return std::string(lua_tostring(L, index), lua_strlen(L, index)); + } + + void to(lua_State* L, std::string const& value) + { + lua_pushlstring(L, value.data(), value.size()); + } +}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter +{ + typedef boost::mpl::true_ is_native; + + template + static int match(lua_State* L, U, int index) + { + return lua_type(L, index) == LUA_TSTRING ? 0 : -1; + } + + template + char const* apply(lua_State* L, U, int index) + { + return lua_tostring(L, index); + } + + void apply(lua_State* L, char const* str) + { + lua_pushstring(L, str); + } + + template + void converter_postcall(lua_State*, U, int) + {} +}; + +template <> +struct default_converter + : default_converter +{}; + +template <> +struct default_converter + : default_converter +{}; + +template +struct default_converter + : default_converter +{}; + +template +struct default_converter + : default_converter +{}; + +namespace detail +{ + + struct default_policy : converter_policy_tag + { + BOOST_STATIC_CONSTANT(bool, has_arg = true); + + template + static void precall(lua_State*, T, int) {} + + template + struct apply + { + typedef default_converter type; + }; + }; + + template + struct is_primitive + : default_converter::is_native + {}; + +// ============== new policy system ================= + + template struct find_conversion_policy; + + template + struct find_conversion_impl + { + template + struct apply + { + typedef typename find_conversion_policy::type type; + }; + }; + + template<> + struct find_conversion_impl + { + template + struct apply + { + typedef typename Policies::head head; + typedef typename Policies::tail tail; + + BOOST_STATIC_CONSTANT(bool, found = (N == head::index)); + + typedef typename + boost::mpl::if_c::type + >::type type; + }; + }; + + template + struct find_conversion_impl2 + { + template + struct apply + : find_conversion_impl< + boost::is_base_and_derived::value + >::template apply + { + }; + }; + + template<> + struct find_conversion_impl2 + { + template + struct apply + { + typedef default_policy type; + }; + }; + + template + struct find_conversion_policy : find_conversion_impl2::template apply + { + }; + + template + struct policy_list_postcall + { + typedef typename List::head head; + typedef typename List::tail tail; + + static void apply(lua_State* L, const index_map& i) + { + head::postcall(L, i); + policy_list_postcall::apply(L, i); + } + }; + + template<> + struct policy_list_postcall + { + static void apply(lua_State*, const index_map&) {} + }; + +// ================================================== + +// ************** precall and postcall on policy_cons ********************* + + + template + struct policy_precall + { + typedef typename List::head head; + typedef typename List::tail tail; + + static void apply(lua_State* L, int index) + { + head::precall(L, index); + policy_precall::apply(L, index); + } + }; + + template<> + struct policy_precall + { + static void apply(lua_State*, int) {} + }; + + template + struct policy_postcall + { + typedef typename List::head head; + typedef typename List::tail tail; + + static void apply(lua_State* L, int index) + { + head::postcall(L, index); + policy_postcall::apply(L, index); + } + }; + + template<> + struct policy_postcall + { + static void apply(lua_State*, int) {} + }; + +}} // namespace luabind::detail + + +namespace luabind { namespace +{ +#if defined(__GNUC__) && \ + (__GNUC__ * 100 + __GNUC_MINOR__ <= 400 || BOOST_VERSION <= 103401) + static inline boost::arg<0> return_value() + { + return boost::arg<0>(); + } + + static inline boost::arg<0> result() + { + return boost::arg<0>(); + } +# define LUABIND_PLACEHOLDER_ARG(N) boost::arg(*)() +#elif defined(BOOST_MSVC) || defined(__MWERKS__) + static boost::arg<0> return_value; + static boost::arg<0> result; +# define LUABIND_PLACEHOLDER_ARG(N) boost::arg +#else + boost::arg<0> return_value; + boost::arg<0> result; +# define LUABIND_PLACEHOLDER_ARG(N) boost::arg +#endif +}} + +#endif // LUABIND_POLICY_HPP_INCLUDED + diff --git a/include/luabind/detail/primitives.hpp b/include/luabind/detail/primitives.hpp new file mode 100644 index 0000000..04ce17b --- /dev/null +++ b/include/luabind/detail/primitives.hpp @@ -0,0 +1,85 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_PRIMITIVES_HPP_INCLUDED +#define LUABIND_PRIMITIVES_HPP_INCLUDED + +#include +#include + +#include +#include + +namespace luabind { namespace detail +{ + template + struct identity + { + typedef T type; + }; + + template + struct type_ {}; + + struct null_type {}; + +/* typedef char yes_t; + typedef double no_t;*/ + + struct lua_to_cpp {}; + struct cpp_to_lua {}; + + template struct by_value {}; + template struct by_reference {}; + template struct by_const_reference {}; + template struct by_pointer {}; + template struct by_const_pointer {}; + + struct converter_policy_tag {}; + + struct ltstr + { + bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } + }; + + template + struct aligned + { + char storage[N]; + }; + + // returns the offset added to a Derived* when cast to a Base* + // TODO: return ptrdiff + template + int ptr_offset(type_, type_) + { + aligned obj; + Derived* ptr = reinterpret_cast(&obj); + + return int(static_cast(static_cast(static_cast(ptr))) + - static_cast(static_cast(ptr))); + } + +}} + +#endif // LUABIND_PRIMITIVES_HPP_INCLUDED diff --git a/include/luabind/detail/property.hpp b/include/luabind/detail/property.hpp new file mode 100644 index 0000000..2c30ce0 --- /dev/null +++ b/include/luabind/detail/property.hpp @@ -0,0 +1,33 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_PROPERTY_081020_HPP +# define LUABIND_PROPERTY_081020_HPP + +namespace luabind { namespace detail { + +template +struct access_member_ptr +{ + access_member_ptr(T Class::* mem_ptr) + : mem_ptr(mem_ptr) + {} + + Result operator()(Class const& x) const + { + return const_cast(x).*mem_ptr; + } + + void operator()(Class& x, T const& value) const + { + x.*mem_ptr = value; + } + + T Class::* mem_ptr; +}; + +}} // namespace luabind::detail + +#endif // LUABIND_PROPERTY_081020_HPP + diff --git a/include/luabind/detail/ref.hpp b/include/luabind/detail/ref.hpp new file mode 100644 index 0000000..e89c0ee --- /dev/null +++ b/include/luabind/detail/ref.hpp @@ -0,0 +1,128 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_REF_HPP_INCLUDED +#define LUABIND_REF_HPP_INCLUDED + +#include +#include + +#include +#include + +struct lua_State; + +namespace luabind +{ + +#if LUA_VERSION_NUM >= 501 +#define LUA_REFNIL (-1) +#undef luaL_setn +#undef luaL_getn +#endif + +namespace detail +{ + + int LUABIND_API ref(lua_State *L); + void LUABIND_API unref(lua_State *L, int ref); + + inline void getref(lua_State* L, int r) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, r); + } + + struct lua_reference + { + lua_reference(lua_State* L_ = 0) + : L(L_) + , m_ref(LUA_NOREF) + {} + lua_reference(lua_reference const& r) + : L(r.L) + , m_ref(LUA_NOREF) + { + if (!r.is_valid()) return; + r.get(L); + set(L); + } + ~lua_reference() { reset(); } + + lua_State* state() const { return L; } + + void operator=(lua_reference const& r) + { + // TODO: self assignment problems + reset(); + if (!r.is_valid()) return; + r.get(r.state()); + set(r.state()); + } + + bool is_valid() const + { return m_ref != LUA_NOREF; } + + void set(lua_State* L_) + { + reset(); + L = L_; + m_ref = ref(L); + } + + void replace(lua_State* L_) + { + lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); + } + + // L may not be the same pointer as + // was used when creating this reference + // since it may be a thread that shares + // the same globals table. + void get(lua_State* L_) const + { + assert(m_ref != LUA_NOREF); + assert(L_); + getref(L_, m_ref); + } + + void reset() + { + if (L && m_ref != LUA_NOREF) unref(L, m_ref); + m_ref = LUA_NOREF; + } + + void swap(lua_reference& r) + { + assert(r.L == L); + std::swap(r.m_ref, m_ref); + } + + private: + lua_State* L; + int m_ref; + }; + +}} + +#endif // LUABIND_REF_HPP_INCLUDED + diff --git a/include/luabind/detail/signature_match.hpp b/include/luabind/detail/signature_match.hpp new file mode 100644 index 0000000..7066b35 --- /dev/null +++ b/include/luabind/detail/signature_match.hpp @@ -0,0 +1,90 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_SIGNATURE_MATCH_HPP_INCLUDED +#define LUABIND_SIGNATURE_MATCH_HPP_INCLUDED + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace luabind +{ + + namespace adl + { + class argument; + } + + template + struct constructor + { + typedef BOOST_PP_CAT( + boost::mpl::vector, BOOST_PP_INC(BOOST_PP_INC(LUABIND_MAX_ARITY)))< + void, argument const&, BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A) + > signature0; + + typedef typename boost::mpl::remove< + signature0, detail::null_type>::type signature; + + BOOST_STATIC_CONSTANT(int, arity = boost::mpl::size::value - 1); + }; + +} + +namespace luabind { namespace detail +{ + + template + struct constructor_match + { + inline static int apply(lua_State* L) + { + typedef typename Sig::signature signature_type; + + if (lua_gettop(L) != compute_arity(signature_type(), Policies())) + return -1; + + return compute_score(L, signature_type(), Policies()); + } + }; + +}} // namespace luabind::detail + +#endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED + diff --git a/include/luabind/detail/stack_utils.hpp b/include/luabind/detail/stack_utils.hpp new file mode 100755 index 0000000..15f3a7f --- /dev/null +++ b/include/luabind/detail/stack_utils.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_STACK_UTILS_HPP_INCLUDED +#define LUABIND_STACK_UTILS_HPP_INCLUDED + +#include + +namespace luabind { namespace detail +{ + + struct stack_pop + { + stack_pop(lua_State* L, int n) + : m_state(L) + , m_n(n) + { + } + + ~stack_pop() + { + lua_pop(m_state, m_n); + } + + private: + + lua_State* m_state; + int m_n; + }; +}} + +#endif // LUABIND_STACK_UTILS_HPP_INCLUDED + diff --git a/include/luabind/detail/typetraits.hpp b/include/luabind/detail/typetraits.hpp new file mode 100644 index 0000000..f27934e --- /dev/null +++ b/include/luabind/detail/typetraits.hpp @@ -0,0 +1,190 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_TYPETRAITS_HPP_INCLUDED +#define LUABIND_TYPETRAITS_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace luabind { namespace detail +{ + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct is_const_type + { + typedef typename boost::mpl::if_ + , yes_t + , no_t + >::type type; + }; + + template + struct is_const_reference_helper + { + template + struct apply + { + enum + { + value = false + }; + }; + }; + + template + typename is_const_type::type is_const_reference_tester(T&); + no_t is_const_reference_tester(...); + + template<> + struct is_const_reference_helper + { + template + struct apply + { + static T getT(); + + enum + { + value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t) + }; + }; + }; + + template + struct is_const_reference + : is_const_reference_helper::value>::template apply + { + typedef boost::mpl::bool_ type; + }; + +#else + + template + struct is_const_reference + { + enum { value = false }; + typedef boost::mpl::bool_ type; + }; + + template + struct is_const_reference + { + enum { value = true }; + typedef boost::mpl::bool_ type; + }; + +#endif + + + template + struct is_nonconst_reference + { + enum + { + value = boost::is_reference::value && !is_const_reference::value + }; + typedef boost::mpl::bool_ type; + }; + + template + yes_t is_const_pointer_helper(void(*)(const A*)); + no_t is_const_pointer_helper(...); + + template + struct is_const_pointer + { + enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) }; + typedef boost::mpl::bool_ type; + }; + + template + yes_t is_nonconst_pointer_helper(void(*)(A*)); + no_t is_nonconst_pointer_helper(...); + + template + struct is_nonconst_pointer + { + enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer::value }; + typedef boost::mpl::bool_ type; + }; +/* + template + struct is_constructable_from_helper + { + static yes_t check(const T&); + static no_t check(...); + }; + + template + struct is_constructable_from + { + static From getFrom(); + + enum + { + value = sizeof(is_constructable_from_helper::check(getFrom())) == sizeof(yes_t) + }; + }; + + template + struct is_const_member_function_helper + { + static no_t test(...); + template + static yes_t test(R(T::*)() const); + template + static yes_t test(R(T::*)(A1) const); + template + static yes_t test(R(T::*)(A1,A2) const); + template + static yes_t test(R(T::*)(A1,A2,A3) const); + }; + + template + struct is_const_member_function + { + static U getU(); + + enum + { + value = sizeof(is_const_member_function_helper::test(getU())) == sizeof(yes_t) + }; + }; +*/ + + template + struct max_c + { + enum { value = (v1>v2)?v1:v2 }; + }; + +}} + +#endif // LUABIND_TYPETRAITS_HPP_INCLUDED + diff --git a/include/luabind/detail/yes_no.hpp b/include/luabind/detail/yes_no.hpp new file mode 100755 index 0000000..931847c --- /dev/null +++ b/include/luabind/detail/yes_no.hpp @@ -0,0 +1,34 @@ +// Copyright (c) 2004 Daniel Wallin + +// 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 YES_NO_040211_HPP +#define YES_NO_040211_HPP + +namespace luabind { namespace detail { + + typedef char(&yes_t)[1]; + typedef char(&no_t)[2]; + +}} // namespace luabind::detail + +#endif // YES_NO_040211_HPP + diff --git a/include/luabind/discard_result_policy.hpp b/include/luabind/discard_result_policy.hpp new file mode 100644 index 0000000..149a7b1 --- /dev/null +++ b/include/luabind/discard_result_policy.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED +#define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail +{ + struct discard_converter + { + template + void apply(lua_State*, T) {} + }; + + struct discard_result_policy : conversion_policy<0> + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct can_only_convert_from_cpp_to_lua {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , discard_converter + , can_only_convert_from_cpp_to_lua + >::type type; + }; + }; + +}} + +namespace luabind +{ + detail::policy_cons< + detail::discard_result_policy, detail::null_type> const discard_result = {}; + + namespace detail + { + inline void ignore_unused_discard_result() + { + (void)discard_result; + } + } +} + +#endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED + diff --git a/include/luabind/error.hpp b/include/luabind/error.hpp new file mode 100755 index 0000000..3824a70 --- /dev/null +++ b/include/luabind/error.hpp @@ -0,0 +1,92 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_ERROR_HPP_INCLUDED +#define LUABIND_ERROR_HPP_INCLUDED + +#include +#include +#include + +struct lua_State; + +namespace luabind +{ + +#ifndef LUABIND_NO_EXCEPTIONS + + // this exception usually means that the lua function you called + // from C++ failed with an error code. You will have to + // read the error code from the top of the lua stack + // the reason why this exception class doesn't contain + // the message itself is that std::string's copy constructor + // may throw, if the copy constructor of an exception that is + // being thrown throws another exception, terminate will be called + // and the entire application is killed. + class LUABIND_API error : public std::exception + { + public: + explicit error(lua_State* L): m_L(L) {} + lua_State* state() const throw() { return m_L; } + virtual const char* what() const throw() + { + return "lua runtime error"; + } + private: + lua_State* m_L; + }; + + // if an object_cast<>() fails, this is thrown + // it is also thrown if the return value of + // a lua function cannot be converted + class LUABIND_API cast_failed : public std::exception + { + public: + cast_failed(lua_State* L, LUABIND_TYPE_INFO i): m_L(L), m_info(i) {} + lua_State* state() const throw() { return m_L; } + LUABIND_TYPE_INFO info() const throw() { return m_info; } + virtual const char* what() const throw() { return "unable to make cast"; } + private: + lua_State* m_L; + LUABIND_TYPE_INFO m_info; + }; + +#else + + typedef void(*error_callback_fun)(lua_State*); + typedef void(*cast_failed_callback_fun)(lua_State*, LUABIND_TYPE_INFO); + + LUABIND_API void set_error_callback(error_callback_fun e); + LUABIND_API void set_cast_failed_callback(cast_failed_callback_fun c); + LUABIND_API error_callback_fun get_error_callback(); + LUABIND_API cast_failed_callback_fun get_cast_failed_callback(); + +#endif + + typedef int(*pcall_callback_fun)(lua_State*); + LUABIND_API void set_pcall_callback(pcall_callback_fun e); + LUABIND_API pcall_callback_fun get_pcall_callback(); + +} + +#endif // LUABIND_ERROR_HPP_INCLUDED + diff --git a/include/luabind/exception_handler.hpp b/include/luabind/exception_handler.hpp new file mode 100644 index 0000000..0048563 --- /dev/null +++ b/include/luabind/exception_handler.hpp @@ -0,0 +1,110 @@ +// Copyright Daniel Wallin 2005. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_EXCEPTION_HANDLER_050601_HPP +# define LUABIND_EXCEPTION_HANDLER_050601_HPP + +# include +# include +# include +# include + +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# include +# include +# endif + +namespace luabind { + +# ifndef LUABIND_NO_EXCEPTIONS + +namespace detail +{ + + struct LUABIND_API exception_handler_base + { + exception_handler_base() + : next(0) + {} + + virtual ~exception_handler_base() {} + virtual void handle(lua_State*) const = 0; + + void try_next(lua_State*) const; + + exception_handler_base* next; + }; + + namespace mpl = boost::mpl; + + template + struct exception_handler : exception_handler_base + { +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typedef typename mpl::if_< + boost::is_pointer, E, E const& + >::type argument; +# else + typedef E const& argument; +# endif + + exception_handler(Handler handler) + : handler(handler) + {} + + void handle(lua_State* L) const + { + try + { + try_next(L); + } + catch (argument e) + { + handler(L, e); + } + } + + Handler handler; + }; + + LUABIND_API void handle_exception_aux(lua_State* L); + LUABIND_API void register_exception_handler(exception_handler_base*); + +} // namespace detail + +# endif + +template +void register_exception_handler(Handler handler, boost::type* = 0) +{ +# ifndef LUABIND_NO_EXCEPTIONS + detail::register_exception_handler( + new detail::exception_handler(handler) + ); +# endif +} + +template +boost::optional handle_exceptions(lua_State* L, F fn, boost::type* = 0) +{ +# ifndef LUABIND_NO_EXCEPTIONS + try + { + return fn(); + } + catch (...) + { + detail::handle_exception_aux(L); + } + + return boost::optional(); +# else + return fn(); +# endif +} + +} // namespace luabind + +#endif // LUABIND_EXCEPTION_HANDLER_050601_HPP + diff --git a/include/luabind/from_stack.hpp b/include/luabind/from_stack.hpp new file mode 100755 index 0000000..56bc268 --- /dev/null +++ b/include/luabind/from_stack.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_FROM_STACK_050715_HPP +#define LUABIND_FROM_STACK_050715_HPP + +namespace luabind { + +struct from_stack +{ + from_stack(lua_State* interpreter, int index) + : interpreter(interpreter) + , index(index) + {} + + lua_State* interpreter; + int index; +}; + +} // namespace luabind + +#endif // LUABIND_FROM_STACK_050715_HPP + diff --git a/include/luabind/function.hpp b/include/luabind/function.hpp new file mode 100644 index 0000000..e156fbf --- /dev/null +++ b/include/luabind/function.hpp @@ -0,0 +1,62 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_FUNCTION2_081014_HPP +# define LUABIND_FUNCTION2_081014_HPP + +# include +# include +# include + +namespace luabind { + +namespace detail +{ + + template + struct function_registration : registration + { + function_registration(char const* name, F f, Policies const& policies) + : name(name) + , f(f) + , policies(policies) + {} + + void register_(lua_State* L) const + { + object fn = make_function(L, f, deduce_signature(f), policies); + + add_overload( + object(from_stack(L, -1)) + , name + , fn + ); + } + + char const* name; + F f; + Policies policies; + }; + + LUABIND_API bool is_luabind_function(lua_State* L, int index); + +} // namespace detail + +template +scope def(char const* name, F f, Policies const& policies) +{ + return scope(std::auto_ptr( + new detail::function_registration(name, f, policies))); +} + +template +scope def(char const* name, F f) +{ + return def(name, f, detail::null_type()); +} + +} // namespace luabind + +#endif // LUABIND_FUNCTION2_081014_HPP + diff --git a/include/luabind/get_pointer.hpp b/include/luabind/get_pointer.hpp new file mode 100755 index 0000000..b9aae48 --- /dev/null +++ b/include/luabind/get_pointer.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2005 Daniel Wallin + +// 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 LUABIND_GET_POINTER_051023_HPP +# define LUABIND_GET_POINTER_051023_HPP + +// +// We need these overloads in the luabind namespace. +// + +# include + +namespace luabind { + +using boost::get_pointer; + +} // namespace luabind + +#endif // LUABIND_GET_POINTER_051023_HPP + diff --git a/include/luabind/handle.hpp b/include/luabind/handle.hpp new file mode 100755 index 0000000..1416c46 --- /dev/null +++ b/include/luabind/handle.hpp @@ -0,0 +1,136 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_HANDLE_050420_HPP +#define LUABIND_HANDLE_050420_HPP + +#include +#include +#include + +namespace luabind { + +// A reference to a Lua value. Represents an entry in the +// registry table. +class handle +{ +public: + handle(); + handle(lua_State* interpreter, int stack_index); + handle(handle const& other); + ~handle(); + + handle& operator=(handle const& other); + void swap(handle& other); + + void push(lua_State* interpreter) const; + + lua_State* interpreter() const; + + void replace(lua_State* interpreter, int stack_index); + +private: + lua_State* m_interpreter; + int m_index; +}; + +inline handle::handle() + : m_interpreter(0) + , m_index(LUA_NOREF) +{} + +inline handle::handle(handle const& other) + : m_interpreter(other.m_interpreter) + , m_index(LUA_NOREF) +{ + if (m_interpreter == 0) return; + detail::getref(m_interpreter, other.m_index); + m_index = detail::ref(m_interpreter); +} + +inline handle::handle(lua_State* interpreter, int stack_index) + : m_interpreter(interpreter) + , m_index(LUA_NOREF) +{ + lua_pushvalue(interpreter, stack_index); + m_index = detail::ref(interpreter); +} + +inline handle::~handle() +{ + if (m_interpreter && m_index != LUA_NOREF) + detail::unref(m_interpreter, m_index); +} + +inline handle& handle::operator=(handle const& other) +{ + handle(other).swap(*this); + return *this; +} + +inline void handle::swap(handle& other) +{ + std::swap(m_interpreter, other.m_interpreter); + std::swap(m_index, other.m_index); +} + +inline void handle::push(lua_State* interpreter) const +{ + detail::getref(interpreter, m_index); +} + +inline lua_State* handle::interpreter() const +{ + return m_interpreter; +} + +inline void handle::replace(lua_State* interpreter, int stack_index) +{ + lua_pushvalue(interpreter, stack_index); + lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); +} + +template<> +struct value_wrapper_traits +{ + typedef boost::mpl::true_ is_specialized; + + static lua_State* interpreter(handle const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, handle const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } +}; + +} // namespace luabind + +#endif // LUABIND_HANDLE_050420_HPP + diff --git a/include/luabind/iterator_policy.hpp b/include/luabind/iterator_policy.hpp new file mode 100755 index 0000000..9610e65 --- /dev/null +++ b/include/luabind/iterator_policy.hpp @@ -0,0 +1,113 @@ +// Copyright Daniel Wallin 2007. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_ITERATOR_POLICY__071111_HPP +# define LUABIND_ITERATOR_POLICY__071111_HPP + +# include +# include +# include + +namespace luabind { namespace detail { + +template +struct iterator +{ + static int next(lua_State* L) + { + iterator* self = static_cast( + lua_touserdata(L, lua_upvalueindex(1))); + + if (self->first != self->last) + { + convert_to_lua(L, *self->first); + ++self->first; + } + else + { + lua_pushnil(L); + } + + return 1; + } + + static int destroy(lua_State* L) + { + iterator* self = static_cast( + lua_touserdata(L, lua_upvalueindex(1))); + self->~iterator(); + return 0; + } + + iterator(Iterator first, Iterator last) + : first(first) + , last(last) + {} + + Iterator first; + Iterator last; +}; + +template +int make_range(lua_State* L, Iterator first, Iterator last) +{ + void* storage = lua_newuserdata(L, sizeof(iterator)); + lua_newtable(L); + lua_pushcclosure(L, iterator::destroy, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + lua_pushcclosure(L, iterator::next, 1); + new (storage) iterator(first, last); + return 1; +} + +template +int make_range(lua_State* L, Container& container) +{ + return make_range(L, container.begin(), container.end()); +} + +struct iterator_converter +{ + typedef iterator_converter type; + + template + void apply(lua_State* L, Container& container) + { + make_range(L, container); + } + + template + void apply(lua_State* L, Container const& container) + { + make_range(L, container); + } +}; + +struct iterator_policy : conversion_policy<0> +{ + static void precall(lua_State*, index_map const&) + {} + + static void postcall(lua_State*, index_map const&) + {} + + template + struct apply + { + typedef iterator_converter type; + }; +}; + +}} // namespace luabind::detail + +namespace luabind { namespace { + +LUABIND_ANONYMOUS_FIX detail::policy_cons< + detail::iterator_policy, detail::null_type> return_stl_iterator; + +}} // namespace luabind::unnamed + +#endif // LUABIND_ITERATOR_POLICY__071111_HPP + diff --git a/include/luabind/lua_include.hpp b/include/luabind/lua_include.hpp new file mode 100755 index 0000000..d36a81e --- /dev/null +++ b/include/luabind/lua_include.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUA_INCLUDE_HPP_INCLUDED +#define LUA_INCLUDE_HPP_INCLUDED + +#include "lua/lua.h" +#include "lua/lauxlib.h" + +#endif + diff --git a/include/luabind/luabind.hpp b/include/luabind/luabind.hpp new file mode 100644 index 0000000..8229848 --- /dev/null +++ b/include/luabind/luabind.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_BIND_HPP_INCLUDED +#define LUABIND_BIND_HPP_INCLUDED + +#include +#include +#include +#include + +#endif // LUABIND_BIND_HPP_INCLUDED diff --git a/include/luabind/make_function.hpp b/include/luabind/make_function.hpp new file mode 100644 index 0000000..0bfed63 --- /dev/null +++ b/include/luabind/make_function.hpp @@ -0,0 +1,91 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_MAKE_FUNCTION_081014_HPP +# define LUABIND_MAKE_FUNCTION_081014_HPP + +# include +# include +# include +# include +# include +# include + +# include + +namespace luabind { + +namespace detail +{ + + template + struct function_invoke + { + function_invoke(F f) + : f(f) + {} + + int operator()(lua_State* L) const + { + return invoke(L, f, Signature(), Policies()); + } + + F f; + }; + + template + struct function_score + { + int operator()(lua_State* L) const + { + return compute_score(L, Signature(), Policies()); + } + }; + + template + struct function_signature + { + int operator()(lua_State* L, char const* function) const + { + format_signature(L, function, Signature()); + return 0; + } + }; + + typedef boost::function1 function_callback; + typedef boost::function2 signature_callback; + + LUABIND_API object make_function_aux( + lua_State*, int + , function_callback const& call + , function_callback const& score + , signature_callback const& signature + ); + + LUABIND_API void add_overload(object const&, char const*, object const&); + +} // namespace detail + +template +object make_function(lua_State* L, F f, Signature, Policies) +{ + return detail::make_function_aux( + L + , detail::compute_arity(Signature(), Policies()) + , detail::function_invoke(f) + , detail::function_score() + , detail::function_signature() + ); +} + +template +object make_function(lua_State* L, F f) +{ + return make_function(L, detail::deduce_signature(f), detail::null_type()); +} + +} // namespace luabind + +#endif // LUABIND_MAKE_FUNCTION_081014_HPP + diff --git a/include/luabind/nil.hpp b/include/luabind/nil.hpp new file mode 100644 index 0000000..5f9ba4d --- /dev/null +++ b/include/luabind/nil.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_NIL_HPP +#define LUABIND_NIL_HPP + +#include + +namespace luabind +{ + namespace detail + { + struct nil_type {}; + } + + // defined in class.cpp + extern LUABIND_API detail::nil_type nil; +} + +#endif + diff --git a/include/luabind/object.hpp b/include/luabind/object.hpp new file mode 100644 index 0000000..f3c7661 --- /dev/null +++ b/include/luabind/object.hpp @@ -0,0 +1,1377 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OBJECT_050419_HPP +#define LUABIND_OBJECT_050419_HPP + +#include // detail::push() +#include // detail::push() +#include // value_wrapper_traits specializations +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include // REFACTOR + +#include // iterator +#include + +#include +#include + +namespace luabind { + +namespace detail +{ + namespace mpl = boost::mpl; + + template + void push_aux(lua_State* interpreter, T& value, ConverterGenerator*) + { + typedef typename boost::mpl::if_< + boost::is_reference_wrapper + , BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& + , T + >::type unwrapped_type; + + typename mpl::apply_wrap2< + ConverterGenerator,unwrapped_type,cpp_to_lua + >::type cv; + + cv.apply( + interpreter + , boost::implicit_cast< + BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& + >(value) + ); + } + + template + void push(lua_State* interpreter, T& value, Policies const&) + { + typedef typename find_conversion_policy< + 0 + , Policies + >::type converter_policy; + + push_aux(interpreter, value, (converter_policy*)0); + } + + template + void push(lua_State* interpreter, T& value) + { + push(interpreter, value, null_type()); + } + +} // namespace detail + +namespace adl +{ + namespace mpl = boost::mpl; + + template + class object_interface; + + namespace is_object_interface_aux + { + typedef char (&yes)[1]; + typedef char (&no)[2]; + + template + yes check(object_interface*); + no check(void*); + + template + struct impl + { + BOOST_STATIC_CONSTANT(bool, value = + sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes) + ); + + typedef mpl::bool_ type; + }; + + } // namespace detail + + template + struct is_object_interface + : is_object_interface_aux::impl::type + {}; + + template + struct enable_binary +# ifndef BOOST_NO_SFINAE + : boost::enable_if< + mpl::or_< + is_object_interface + , is_object_interface + > + , R + > + {}; +# else + { + typedef R type; + }; +# endif + + template + int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs + , boost::mpl::true_, boost::mpl::true_) + { + L = value_wrapper_traits::interpreter(lhs); + lua_State* L2 = value_wrapper_traits::interpreter(rhs); + + // you are comparing objects with different interpreters + // that's not allowed. + assert(L == L2 || L == 0 || L2 == 0); + + // if the two objects we compare have different interpreters + // then they + + if (L != L2) return -1; + if (L == 0) return 1; + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const& + , boost::mpl::true_, boost::mpl::false_) + { + L = value_wrapper_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_) + { + L = value_wrapper_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const& y) + { + return binary_interpreter( + L + , x + , y + , is_value_wrapper() + , is_value_wrapper() + ); + } + +#define LUABIND_BINARY_OP_DEF(op, fn) \ + template \ + typename enable_binary::type \ + operator op(LHS const& lhs, RHS const& rhs) \ + { \ + lua_State* L = 0; \ + switch (binary_interpreter(L, lhs, rhs)) \ + { \ + case 1: \ + return true; \ + case -1: \ + return false; \ + } \ +\ + assert(L); \ +\ + detail::stack_pop pop1(L, 1); \ + detail::push(L, lhs); \ + detail::stack_pop pop2(L, 1); \ + detail::push(L, rhs); \ +\ + return fn(L, -1, -2) != 0; \ + } + +LUABIND_BINARY_OP_DEF(==, lua_equal) +LUABIND_BINARY_OP_DEF(<, lua_lessthan) + + template + std::ostream& operator<<(std::ostream& os + , object_interface const& v) + { + using namespace luabind; + lua_State* interpreter = value_wrapper_traits::interpreter( + static_cast(v)); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter + , static_cast(v)); + char const* p = lua_tostring(interpreter, -1); + int len = lua_strlen(interpreter, -1); + std::copy(p, p + len, std::ostream_iterator(os)); + return os; + } + +#undef LUABIND_BINARY_OP_DEF + + template + typename enable_binary::type + operator>(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs || lhs == rhs); + } + + template + typename enable_binary::type + operator<=(LHS const& lhs, RHS const& rhs) + { + return lhs < rhs || lhs == rhs; + } + + template + typename enable_binary::type + operator>=(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs); + } + + template + typename enable_binary::type + operator!=(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs); + } + + template + struct call_proxy; + + template + class index_proxy; + + class object; + + template + class object_interface + { + struct safe_bool_type {}; + public: + ~object_interface() {} + + call_proxy > operator()(); + + template + call_proxy< + Derived + , boost::tuples::tuple + > operator()(A0 const& a0) + { + typedef boost::tuples::tuple arguments; + + return call_proxy( + derived() + , arguments(&a0) + ); + } + + template + call_proxy< + Derived + , boost::tuples::tuple + > operator()(A0 const& a0, A1 const& a1) + { + typedef boost::tuples::tuple arguments; + + return call_proxy( + derived() + , arguments(&a0, &a1) + ); + } + + // The rest of the overloads are PP-generated. + #define BOOST_PP_ITERATION_PARAMS_1 (3, \ + (3, LUABIND_MAX_ARITY, )) + #include BOOST_PP_ITERATE() + + operator safe_bool_type*() const + { + lua_State* L = value_wrapper_traits::interpreter(derived()); + + if (!L) + return 0; + + value_wrapper_traits::unwrap(L, derived()); + detail::stack_pop pop(L, 1); + + return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0; + } + + private: + Derived& derived() + { + return *static_cast(this); + } + + Derived const& derived() const + { + return *static_cast(this); + } + }; + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + struct iterator_proxy_tag; +#endif + + template + class iterator_proxy + : public object_interface > + { + public: +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + typedef iterator_proxy_tag value_wrapper_tag; +#endif + + iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) + : m_interpreter(interpreter) + , m_table_index(lua_gettop(interpreter) + 1) + , m_key_index(m_table_index + 1) + { + table.push(m_interpreter); + key.push(m_interpreter); + } + + iterator_proxy(iterator_proxy const& other) + : m_interpreter(other.m_interpreter) + , m_table_index(other.m_table_index) + , m_key_index(other.m_key_index) + { + other.m_interpreter = 0; + } + + ~iterator_proxy() + { + if (m_interpreter) + lua_pop(m_interpreter, 2); + } + + // this will set the value to nil + iterator_proxy & operator=(luabind::detail::nil_type) + { + lua_pushvalue(m_interpreter, m_key_index); + lua_pushnil(m_interpreter); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + iterator_proxy& operator=(T const& value) + { + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + index_proxy > operator[](Key const& key) + { + return index_proxy >( + *this, m_interpreter, key + ); + } + + // This is non-const to prevent conversion on lvalues. + operator object(); + + lua_State* interpreter() const + { + return m_interpreter; + } + + // TODO: Why is it non-const? + void push(lua_State* interpreter) + { + assert(interpreter == m_interpreter); + lua_pushvalue(m_interpreter, m_key_index); + AccessPolicy::get(m_interpreter, m_table_index); + } + + private: + mutable lua_State* m_interpreter; + int m_table_index; + int m_key_index; + }; + +} // namespace adl + +namespace detail +{ + struct basic_access + { + static void set(lua_State* interpreter, int table) + { + lua_settable(interpreter, table); + } + + static void get(lua_State* interpreter, int table) + { + lua_gettable(interpreter, table); + } + }; + + struct raw_access + { + static void set(lua_State* interpreter, int table) + { + lua_rawset(interpreter, table); + } + + static void get(lua_State* interpreter, int table) + { + lua_rawget(interpreter, table); + } + }; + + template + class basic_iterator + : public boost::iterator_facade< + basic_iterator + , adl::iterator_proxy + , boost::single_pass_traversal_tag + , adl::iterator_proxy + > + { + public: + basic_iterator() + : m_interpreter(0) + {} + + template + explicit basic_iterator(ValueWrapper const& value_wrapper) + : m_interpreter( + value_wrapper_traits::interpreter(value_wrapper) + ) + { + detail::stack_pop pop(m_interpreter, 1); + value_wrapper_traits::unwrap(m_interpreter, value_wrapper); + + lua_pushnil(m_interpreter); + if (lua_next(m_interpreter, -2) != 0) + { + detail::stack_pop pop(m_interpreter, 2); + handle(m_interpreter, -2).swap(m_key); + } + else + { + m_interpreter = 0; + return; + } + + handle(m_interpreter, -1).swap(m_table); + } + + adl::object key() const; + + private: + friend class boost::iterator_core_access; + + void increment() + { + m_table.push(m_interpreter); + m_key.push(m_interpreter); + + detail::stack_pop pop(m_interpreter, 1); + + if (lua_next(m_interpreter, -2) != 0) + { + m_key.replace(m_interpreter, -2); + lua_pop(m_interpreter, 2); + } + else + { + m_interpreter = 0; + handle().swap(m_table); + handle().swap(m_key); + } + } + + bool equal(basic_iterator const& other) const + { + if (m_interpreter == 0 && other.m_interpreter == 0) + return true; + + if (m_interpreter != other.m_interpreter) + return false; + + detail::stack_pop pop(m_interpreter, 2); + m_key.push(m_interpreter); + other.m_key.push(m_interpreter); + return lua_equal(m_interpreter, -2, -1) != 0; + } + + adl::iterator_proxy dereference() const + { + return adl::iterator_proxy(m_interpreter, m_table, m_key); + } + + lua_State* m_interpreter; + handle m_table; + handle m_key; + }; + +// Needed because of some strange ADL issues. + +#define LUABIND_OPERATOR_ADL_WKND(op) \ + inline bool operator op( \ + basic_iterator const& x \ + , basic_iterator const& y) \ + { \ + return boost::operator op(x, y); \ + } \ + \ + inline bool operator op( \ + basic_iterator const& x \ + , basic_iterator const& y) \ + { \ + return boost::operator op(x, y); \ + } + + LUABIND_OPERATOR_ADL_WKND(==) + LUABIND_OPERATOR_ADL_WKND(!=) + +#undef LUABIND_OPERATOR_ADL_WKND + +} // namespace detail + +namespace adl +{ + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + struct index_proxy_tag; +#endif + + template + class index_proxy + : public object_interface > + { + public: +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + typedef index_proxy_tag value_wrapper_tag; +#endif + + typedef index_proxy this_type; + + template + index_proxy(Next const& next, lua_State* interpreter, Key const& key) + : m_interpreter(interpreter) + , m_key_index(lua_gettop(interpreter) + 1) + , m_next(next) + { + detail::push(m_interpreter, key); + } + + index_proxy(index_proxy const& other) + : m_interpreter(other.m_interpreter) + , m_key_index(other.m_key_index) + , m_next(other.m_next) + { + other.m_interpreter = 0; + } + + ~index_proxy() + { + if (m_interpreter) + lua_pop(m_interpreter, 1); + } + + // This is non-const to prevent conversion on lvalues. + operator object(); + + // this will set the value to nil + this_type& operator=(luabind::detail::nil_type) + { + value_wrapper_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + lua_pushnil(m_interpreter); + lua_settable(m_interpreter, -3); + return *this; + } + + template + this_type& operator=(T const& value) + { + value_wrapper_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + lua_settable(m_interpreter, -3); + return *this; + } + + this_type& operator=(this_type const& value) + { + value_wrapper_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + lua_settable(m_interpreter, -3); + return *this; + } + + template + index_proxy operator[](T const& key) + { + return index_proxy(*this, m_interpreter, key); + } + + void push(lua_State* interpreter); + + lua_State* interpreter() const + { + return m_interpreter; + } + + private: + struct hidden_type {}; + +// this_type& operator=(index_proxy const&); + + mutable lua_State* m_interpreter; + int m_key_index; + + Next const& m_next; + }; + +} // namespace adl + +typedef detail::basic_iterator iterator; +typedef detail::basic_iterator raw_iterator; + +#ifndef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits > +#else +template<> +struct value_wrapper_traits +#endif +{ + typedef boost::mpl::true_ is_specialized; + + template + static lua_State* interpreter(adl::index_proxy const& proxy) + { + return proxy.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) + { + const_cast&>(proxy).push(interpreter); + } +}; + +#ifndef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits > +#else +template<> +struct value_wrapper_traits +#endif +{ + typedef boost::mpl::true_ is_specialized; + + template + static lua_State* interpreter(Proxy const& p) + { + return p.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, Proxy const& p) + { + // TODO: Why const_cast? + const_cast(p).push(interpreter); + } +}; + +namespace adl +{ + + // An object holds a reference to a Lua value residing + // in the registry. + class object : public object_interface + { + public: + object() + {} + + explicit object(handle const& other) + : m_handle(other) + {} + + explicit object(from_stack const& stack_reference) + : m_handle(stack_reference.interpreter, stack_reference.index) + { + } + + template + object(lua_State* interpreter, T const& value) + { + detail::push(interpreter, value); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + template + object(lua_State* interpreter, T const& value, Policies const&) + { + detail::push(interpreter, value, Policies()); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + void push(lua_State* interpreter) const; + lua_State* interpreter() const; + bool is_valid() const; + + template + index_proxy operator[](T const& key) const + { + return index_proxy( + *this, m_handle.interpreter(), key + ); + } + + void swap(object& other) + { + m_handle.swap(other.m_handle); + } + + private: + handle m_handle; + }; + + inline void object::push(lua_State* interpreter) const + { + m_handle.push(interpreter); + } + + inline lua_State* object::interpreter() const + { + return m_handle.interpreter(); + } + + inline bool object::is_valid() const + { + return m_handle.interpreter() != 0; + } + + class argument : public object_interface + { + public: + argument(from_stack const& stack_reference) + : m_interpreter(stack_reference.interpreter) + , m_index(stack_reference.index) + { + if (m_index < 0) + m_index = lua_gettop(m_interpreter) - m_index + 1; + } + + template + index_proxy operator[](T const& key) const + { + return index_proxy(*this, m_interpreter, key); + } + + void push(lua_State* L) const + { + lua_pushvalue(L, m_index); + } + + lua_State* interpreter() const + { + return m_interpreter; + } + + private: + lua_State* m_interpreter; + int m_index; + }; + +} // namespace adl + +using adl::object; +using adl::argument; + +#ifndef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits > +#else +template<> +struct value_wrapper_traits +#endif +{ + typedef boost::mpl::true_ is_specialized; + + template + static lua_State* interpreter(adl::call_proxy const& proxy) + { + return value_wrapper_traits::interpreter(*proxy.value_wrapper); + } + + template + static void unwrap(lua_State* interpreter, adl::call_proxy const& proxy) + { + object result = const_cast&>(proxy); + result.push(result.interpreter()); + } +}; + +template<> +struct value_wrapper_traits +{ + typedef boost::mpl::true_ is_specialized; + + static lua_State* interpreter(object const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, object const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } +}; + +template<> +struct value_wrapper_traits +{ + typedef boost::mpl::true_ is_specialized; + + static lua_State* interpreter(argument const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, argument const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } +}; + +template +inline void adl::index_proxy::push(lua_State* interpreter) +{ + assert(interpreter == m_interpreter); + + value_wrapper_traits::unwrap(m_interpreter, m_next); + + lua_pushvalue(m_interpreter, m_key_index); + lua_gettable(m_interpreter, -2); + lua_remove(m_interpreter, -2); +} + +template +inline adl::index_proxy::operator object() +{ + detail::stack_pop pop(m_interpreter, 1); + push(m_interpreter); + return object(from_stack(m_interpreter, -1)); +} + +template +adl::iterator_proxy::operator object() +{ + lua_pushvalue(m_interpreter, m_key_index); + AccessPolicy::get(m_interpreter, m_table_index); + detail::stack_pop pop(m_interpreter, 1); + return object(from_stack(m_interpreter, -1)); +} + +template +object detail::basic_iterator::key() const +{ + return object(m_key); +} + +namespace detail +{ + + template< + class T + , class ValueWrapper + , class Policies + , class ErrorPolicy + , class ReturnType + > + ReturnType object_cast_aux( + ValueWrapper const& value_wrapper + , T* + , Policies* + , ErrorPolicy* + , ReturnType* + ) + { + lua_State* interpreter = value_wrapper_traits::interpreter( + value_wrapper + ); + +#ifndef LUABIND_NO_ERROR_CHECKING + if (!interpreter) + return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(void)); +#endif + + value_wrapper_traits::unwrap(interpreter, value_wrapper); + + detail::stack_pop pop(interpreter, 1); + + typedef typename detail::find_conversion_policy< + 0 + , Policies + >::type converter_generator; + + typename mpl::apply_wrap2::type cv; + +#ifndef LUABIND_NO_ERROR_CHECKING + if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0) + { + return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(T)); + } +#endif + + return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1); + } + + template + struct throw_error_policy + { + static T handle_error(lua_State* interpreter, LUABIND_TYPE_INFO type_info) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(interpreter, type_info); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if (e) e(interpreter, type_info); + + assert(0 && "object_cast failed. If you want to handle this error use " + "luabind::set_error_callback()"); + std::terminate(); +#endif + return *(typename boost::remove_reference::type*)0; + } + }; + + template + struct nothrow_error_policy + { + static boost::optional handle_error(lua_State*, LUABIND_TYPE_INFO) + { + return boost::optional(); + } + }; + +} // namespace detail + +template +T object_cast(ValueWrapper const& value_wrapper) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (detail::null_type*)0 + , (detail::throw_error_policy*)0 + , (T*)0 + ); +} + +template +T object_cast(ValueWrapper const& value_wrapper, Policies const&) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (Policies*)0 + , (detail::throw_error_policy*)0 + , (T*)0 + ); +} + +template +boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (detail::null_type*)0 + , (detail::nothrow_error_policy*)0 + , (boost::optional*)0 + ); +} + +template +boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&) +{ + return detail::object_cast_aux( + value_wrapper + , (T*)0 + , (Policies*)0 + , (detail::nothrow_error_policy*)0 + , (boost::optional*)0 + ); +} + +namespace detail +{ + + template + struct push_args_from_tuple + { + template + inline static void apply(lua_State* L, const boost::tuples::cons& x, const Policies& p) + { + convert_to_lua_p(L, *x.get_head(), p); + push_args_from_tuple::apply(L, x.get_tail(), p); + } + + template + inline static void apply(lua_State* L, const boost::tuples::cons& x) + { + convert_to_lua(L, *x.get_head()); + push_args_from_tuple::apply(L, x.get_tail()); + } + + template + inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {} + + inline static void apply(lua_State*, const boost::tuples::null_type&) {} + }; + +} // namespace detail + +namespace adl +{ + + template + struct call_proxy + { + call_proxy(ValueWrapper& value_wrapper, Arguments arguments) + : value_wrapper(&value_wrapper) + , arguments(arguments) + {} + + call_proxy(call_proxy const& other) + : value_wrapper(other.value_wrapper) + , arguments(other.arguments) + { + other.value_wrapper = 0; + } + + ~call_proxy() + { + if (value_wrapper) + call((detail::null_type*)0); + } + + operator object() + { + return call((detail::null_type*)0); + } + + template + object operator[](Policies const&) + { + return call((Policies*)0); + } + + template + object call(Policies*) + { + lua_State* interpreter = value_wrapper_traits::interpreter( + *value_wrapper + ); + + value_wrapper_traits::unwrap( + interpreter + , *value_wrapper + ); + + value_wrapper = 0; + + detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies()); + + if (detail::pcall(interpreter, boost::tuples::length::value, 1)) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(interpreter); +#else + error_callback_fun e = get_error_callback(); + if (e) e(interpreter); + + assert(0 && "the lua function threw an error and exceptions are disabled." + "if you want to handle this error use luabind::set_error_callback()"); + std::terminate(); +#endif + } + + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + + mutable ValueWrapper* value_wrapper; + Arguments arguments; + }; + + template + call_proxy > + object_interface::operator()() + { + return call_proxy >( + derived() + , boost::tuples::tuple<>() + ); + } + +} // namespace adl + +inline object newtable(lua_State* interpreter) +{ + lua_newtable(interpreter); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); +} + +// this could be optimized by returning a proxy +inline object globals(lua_State* interpreter) +{ + lua_pushvalue(interpreter, LUA_GLOBALSINDEX); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); +} + +// this could be optimized by returning a proxy +inline object registry(lua_State* interpreter) +{ + lua_pushvalue(interpreter, LUA_REGISTRYINDEX); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); +} + +template +inline object gettable(ValueWrapper const& table, K const& key) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push(interpreter, key); + lua_gettable(interpreter, -2); + return object(from_stack(interpreter, -1)); +} + +template +inline void settable(ValueWrapper const& table, K const& key, T const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + // TODO: Exception safe? + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push(interpreter, key); + detail::push(interpreter, value); + lua_settable(interpreter, -3); +} + +template +inline object rawget(ValueWrapper const& table, K const& key) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push(interpreter, key); + lua_rawget(interpreter, -2); + return object(from_stack(interpreter, -1)); +} + +template +inline void rawset(ValueWrapper const& table, K const& key, T const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + table + ); + + // TODO: Exception safe? + + value_wrapper_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push(interpreter, key); + detail::push(interpreter, value); + lua_rawset(interpreter, -3); +} + +template +inline int type(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_type(interpreter, -1); +} + +template +inline object getmetatable(ValueWrapper const& obj) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + obj + ); + + value_wrapper_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 2); + lua_getmetatable(interpreter, -1); + return object(from_stack(interpreter, -1)); +} + +template +inline void setmetatable( + ValueWrapper1 const& obj, ValueWrapper2 const& metatable) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + obj + ); + + value_wrapper_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter, metatable); + lua_setmetatable(interpreter, -2); +} + +template +inline lua_CFunction tocfunction(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_tocfunction(interpreter, -1); +} + +template +inline T* touserdata(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return static_cast(lua_touserdata(interpreter, -1)); +} + +template +inline object getupvalue(ValueWrapper const& value, int index) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 2); + lua_getupvalue(interpreter, -1, index); + return object(from_stack(interpreter, -1)); +} + +template +inline void setupvalue( + ValueWrapper1 const& function, int index, ValueWrapper2 const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + function + ); + + value_wrapper_traits::unwrap(interpreter, function); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter, value); + lua_setupvalue(interpreter, -2, index); +} + +template +object property(GetValueWrapper const& get) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + get + ); + + value_wrapper_traits::unwrap(interpreter, get); + lua_pushnil(interpreter); + + lua_pushcclosure(interpreter, &detail::property_tag, 2); + detail::stack_pop pop(interpreter, 1); + + return object(from_stack(interpreter, -1)); +} + +template +object property(GetValueWrapper const& get, SetValueWrapper const& set) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + get + ); + + value_wrapper_traits::unwrap(interpreter, get); + value_wrapper_traits::unwrap(interpreter, set); + + lua_pushcclosure(interpreter, &detail::property_tag, 2); + detail::stack_pop pop(interpreter, 1); + + return object(from_stack(interpreter, -1)); + +} + + +} // namespace luabind + +#endif // LUABIND_OBJECT_050419_HPP + diff --git a/include/luabind/open.hpp b/include/luabind/open.hpp new file mode 100755 index 0000000..cca4c7a --- /dev/null +++ b/include/luabind/open.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OPEN_HPP_INCLUDED +#define LUABIND_OPEN_HPP_INCLUDED + +#include + +namespace luabind { + + LUABIND_API void open(lua_State* L); + +} + +#endif // LUABIND_OPEN_HPP_INCLUDED + diff --git a/include/luabind/operator.hpp b/include/luabind/operator.hpp new file mode 100755 index 0000000..aeb651c --- /dev/null +++ b/include/luabind/operator.hpp @@ -0,0 +1,355 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 OPERATOR_040729_HPP +#define OPERATOR_040729_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && __GNUC__ < 3 +# define LUABIND_NO_STRINGSTREAM +#else +# if defined(BOOST_NO_STRINGSTREAM) +# define LUABIND_NO_STRINGSTREAM +# endif +#endif + +#ifdef LUABIND_NO_STRINGSTREAM +#include +#else +#include +#endif + +namespace luabind { namespace detail { + + template struct unwrap_parameter_type; + template struct operator_ {}; + + struct operator_void_return {}; + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + template + inline T const& operator,(T const& x, operator_void_return) + { + return x; + } +#endif + +}} // namespace luabind + +namespace luabind { namespace operators { + + #define BOOST_PP_ITERATION_PARAMS_1 (3, \ + (0, LUABIND_MAX_ARITY, )) + #include BOOST_PP_ITERATE() + +}} // namespace luabind::operators + +#include + +namespace luabind { + + template + struct self_base + { + operators::call_operator0 operator()() const + { + return 0; + } + +#define BOOST_PP_LOCAL_MACRO(n) \ + template \ + BOOST_PP_CAT(operators::call_operator, n)< \ + Derived \ + BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \ + >\ + operator()( \ + BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \ + ) const \ + { \ + return 0; \ + } + +#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY) +#include BOOST_PP_LOCAL_ITERATE() + + }; + + struct self_type : self_base + { + }; + + struct const_self_type : self_base + { + }; + +namespace detail { + + template + struct unwrap_parameter_type + { + typedef typename boost::mpl::eval_if< + boost::is_same + , boost::mpl::identity + , boost::mpl::eval_if< + boost::is_same + , boost::mpl::identity + , unwrap_other + > + >::type type; + }; + + template + struct binary_operator + : operator_ > + { + binary_operator(int) {} + + template + struct apply + { + typedef typename unwrap_parameter_type::type arg0; + typedef typename unwrap_parameter_type::type arg1; + + static void execute(lua_State* L, arg0 _0, arg1 _1) + { + Derived::template apply::execute( + L, _0, _1); + } + }; + + static char const* name() + { + return Derived::name(); + } + }; + + template + struct unary_operator + : operator_ > + { + unary_operator(int) {} + + template + struct apply + { + typedef typename unwrap_parameter_type::type arg0; + + static void execute(lua_State* L, arg0 _0) + { + Derived::template apply::execute(L, _0); + } + }; + + static char const* name() + { + return Derived::name(); + } + }; + + template + inline void operator_result(lua_State* L, operator_void_return, Policies*) + { + } + + namespace mpl = boost::mpl; + + template + inline void operator_result(lua_State* L, T const& x, Policies*) + { + typedef typename find_conversion_policy< + 0 + , Policies + >::type cv_policy; + + typename mpl::apply_wrap2::type cv; + + cv.apply(L, x); + } + +}} // namespace detail::luabind + +namespace luabind { + +#define LUABIND_BINARY_OPERATOR(name_, op) \ + namespace operators { \ +\ + struct name_ \ + { \ + template \ + struct apply \ + { \ + static void execute(lua_State* L, T0 _0, T1 _1) \ + { \ + detail::operator_result(L, _0 op _1, (Policies*)0); \ + } \ + }; \ +\ + static char const* name() \ + { \ + return "__" # name_; \ + } \ + }; \ +\ + } \ + \ + template \ + detail::binary_operator< \ + operators::name_ \ + , U \ + , T \ + > \ + inline operator op(self_base, T const&) \ + { \ + return 0; \ + } \ + \ + template \ + detail::binary_operator< \ + operators::name_ \ + , T \ + , U \ + > \ + inline operator op(T const&, self_base) \ + { \ + return 0; \ + } \ + \ + detail::binary_operator< \ + operators::name_ \ + , self_type \ + , self_type \ + > \ + inline operator op(self_type, self_type) \ + { \ + return 0; \ + } \ + \ + detail::binary_operator< \ + operators::name_ \ + , self_type \ + , const_self_type \ + > \ + inline operator op(self_type, const_self_type) \ + { \ + return 0; \ + } \ + \ + detail::binary_operator< \ + operators::name_ \ + , const_self_type \ + , self_type \ + > \ + inline operator op(const_self_type, self_type) \ + { \ + return 0; \ + } \ + \ + detail::binary_operator< \ + operators::name_ \ + , const_self_type \ + , const_self_type \ + > \ + inline operator op(const_self_type, const_self_type) \ + { \ + return 0; \ + } + + LUABIND_BINARY_OPERATOR(add, +) + LUABIND_BINARY_OPERATOR(sub, -) + LUABIND_BINARY_OPERATOR(mul, *) + LUABIND_BINARY_OPERATOR(div, /) + LUABIND_BINARY_OPERATOR(pow, ^) + LUABIND_BINARY_OPERATOR(lt, <) + LUABIND_BINARY_OPERATOR(le, <=) + LUABIND_BINARY_OPERATOR(eq, ==) + +#undef LUABIND_UNARY_OPERATOR + +#define LUABIND_UNARY_OPERATOR(name_, op, fn) \ + namespace operators { \ +\ + struct name_ \ + { \ + template \ + struct apply \ + { \ + static void execute(lua_State* L, T x) \ + { \ + detail::operator_result(L, op(x), (Policies*)0); \ + } \ + }; \ +\ + static char const* name() \ + { \ + return "__" # name_; \ + } \ + }; \ +\ + } \ + \ + template \ + detail::unary_operator< \ + operators::name_ \ + , T \ + > \ + inline fn(self_base) \ + { \ + return 0; \ + } + + template + std::string tostring_operator(T const& x) + { +#ifdef LUABIND_NO_STRINGSTREAM + std::strstream s; + s << x << std::ends; +#else + std::stringstream s; + s << x; +#endif + return s.str(); + } + + LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) + LUABIND_UNARY_OPERATOR(unm, -, operator-) + +#undef LUABIND_BINARY_OPERATOR + + namespace { + + LUABIND_ANONYMOUS_FIX self_type self; + LUABIND_ANONYMOUS_FIX const_self_type const_self; + + } // namespace unnamed + +} // namespace luabind + +#endif // OPERATOR_040729_HPP + diff --git a/include/luabind/out_value_policy.hpp b/include/luabind/out_value_policy.hpp new file mode 100644 index 0000000..b9509fa --- /dev/null +++ b/include/luabind/out_value_policy.hpp @@ -0,0 +1,270 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED +#define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED + +#include +#include +#include + +namespace luabind { namespace detail +{ + template + struct char_array + { + char storage[N]; + }; + +#if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 ) + + template + char_array indirect_sizeof_test(by_reference); + + template + char_array indirect_sizeof_test(by_const_reference); + + template + char_array indirect_sizeof_test(by_pointer); + + template + char_array indirect_sizeof_test(by_const_pointer); + + template + char_array indirect_sizeof_test(by_value); + +#else + + template + char_array::type)> indirect_sizeof_test(by_reference); + + template + char_array::type)> indirect_sizeof_test(by_const_reference); + + template + char_array::type)> indirect_sizeof_test(by_pointer); + + template + char_array::type)> indirect_sizeof_test(by_const_pointer); + + template + char_array::type)> indirect_sizeof_test(by_value); + +#endif + + template + struct indirect_sizeof + { + BOOST_STATIC_CONSTANT(int, value = sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T)))); + }; + + namespace mpl = boost::mpl; + + template + struct out_value_converter + { + template + T& apply(lua_State* L, by_reference, int index) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); + return *reinterpret_cast(m_storage); + } + + template + static int match(lua_State* L, by_reference, int index) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typedef typename mpl::apply_wrap2::type converter; + return converter::match(L, LUABIND_DECORATE_TYPE(T), index); + } + + template + void converter_postcall(lua_State* L, by_reference, int) + { + typedef typename find_conversion_policy<2, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } + + template + T* apply(lua_State* L, by_pointer, int index) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); + return reinterpret_cast(m_storage); + } + + template + static int match(lua_State* L, by_pointer, int index) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typedef typename mpl::apply_wrap2::type converter; + return converter::match(L, LUABIND_DECORATE_TYPE(T), index); + } + + template + void converter_postcall(lua_State* L, by_pointer, int) + { + typedef typename find_conversion_policy<2, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } + + char m_storage[Size]; + }; + + template + struct out_value_policy : conversion_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , typename boost::mpl::if_, is_nonconst_pointer > + , out_value_converter::value, Policies> + , only_accepts_nonconst_references_or_pointers + >::type + , can_only_convert_from_lua_to_cpp + >::type type; + }; + }; + + template + struct pure_out_value_converter + { + template + T& apply(lua_State* L, by_reference, int index) + { + new (m_storage) T(); + return *reinterpret_cast(m_storage); + } + + template + static int match(lua_State* L, by_reference, int index) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_reference, int) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } + + template + T* apply(lua_State* L, by_pointer, int index) + { + new (m_storage) T(); + return reinterpret_cast(m_storage); + } + + template + static int match(lua_State* L, by_pointer, int index) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_pointer, int) + { + typedef typename find_conversion_policy<1, Policies>::type converter_policy; + typename mpl::apply_wrap2::type converter; + converter.apply(L, *reinterpret_cast(m_storage)); + reinterpret_cast(m_storage)->~T(); + } + + + char m_storage[Size]; + }; + + template + struct pure_out_value_policy : conversion_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct apply + { + typedef typename boost::mpl::if_ + , typename boost::mpl::if_, is_nonconst_pointer > + , pure_out_value_converter::value, Policies> + , only_accepts_nonconst_references_or_pointers + >::type + , can_only_convert_from_lua_to_cpp + >::type type; + }; + }; + +}} + +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + out_value(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + pure_out_value(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } + + template + detail::policy_cons, detail::null_type> + pure_out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) + { + return detail::policy_cons, detail::null_type>(); + } +} + +#endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED + diff --git a/include/luabind/prefix.hpp b/include/luabind/prefix.hpp new file mode 100755 index 0000000..86f2db1 --- /dev/null +++ b/include/luabind/prefix.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2004 Daniel Wallin + +// 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 PREFIX_040218_HPP +#define PREFIX_040218_HPP + +#ifdef LUABIND_PREFIX_INCLUDE +# include LUABIND_PREFIX_INCLUDE +#endif + +#endif // PREFIX_040218_HPP + diff --git a/include/luabind/raw_policy.hpp b/include/luabind/raw_policy.hpp new file mode 100755 index 0000000..2872f29 --- /dev/null +++ b/include/luabind/raw_policy.hpp @@ -0,0 +1,80 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_RAW_POLICY_HPP_INCLUDED +#define LUABIND_RAW_POLICY_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail { + + struct raw_converter + { + lua_State* apply(lua_State* L, by_pointer, int) + { + return L; + } + + static int match(...) + { + return 0; + } + + void converter_postcall(lua_State*, by_pointer, int) {} + }; + + template + struct raw_policy : conversion_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + + template + struct apply + { + typedef raw_converter type; + }; + }; + +}} // namespace luabind::detail + +namespace luabind { + + template + detail::policy_cons< + detail::raw_policy + , detail::null_type + > + inline raw(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons< + detail::raw_policy + , detail::null_type + >(); + } + +} // namespace luabind + +#endif // LUABIND_RAW_POLICY_HPP_INCLUDED + diff --git a/include/luabind/return_reference_to_policy.hpp b/include/luabind/return_reference_to_policy.hpp new file mode 100644 index 0000000..1432f79 --- /dev/null +++ b/include/luabind/return_reference_to_policy.hpp @@ -0,0 +1,73 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED +#define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED + +namespace luabind { namespace detail +{ + template + struct return_reference_to_converter; + + template<> + struct return_reference_to_converter + { + template + void apply(lua_State* L, const T&) + { + lua_pushnil(L); + } + }; + + template + struct return_reference_to_policy : conversion_policy<0> + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State* L, const index_map& indices) + { + int result_index = indices[0]; + int ref_to_index = indices[N]; + + lua_pushvalue(L, ref_to_index); + lua_replace(L, result_index); + } + + template + struct apply + { + typedef return_reference_to_converter type; + }; + }; +}} + +namespace luabind +{ + template + detail::policy_cons, detail::null_type> + return_reference_to(LUABIND_PLACEHOLDER_ARG(N)) + { + return detail::policy_cons, detail::null_type>(); + } +} + +#endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED + diff --git a/include/luabind/scope.hpp b/include/luabind/scope.hpp new file mode 100755 index 0000000..085ff42 --- /dev/null +++ b/include/luabind/scope.hpp @@ -0,0 +1,101 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 NEW_SCOPE_040211_HPP +#define NEW_SCOPE_040211_HPP + +#include +#include +#include +#include + +namespace luabind { + + struct scope; + +} // namespace luabind + +namespace luabind { namespace detail { + + struct LUABIND_API registration + { + registration(); + virtual ~registration(); + + protected: + virtual void register_(lua_State*) const = 0; + + private: + friend struct ::luabind::scope; + registration* m_next; + }; + +}} // namespace luabind::detail + +namespace luabind { + + struct LUABIND_API scope + { + scope(); + explicit scope(std::auto_ptr reg); + scope(scope const& other_); + ~scope(); + + scope& operator,(scope s); + + void register_(lua_State* L) const; + + private: + detail::registration* m_chain; + }; + + class LUABIND_API namespace_ : public scope + { + public: + explicit namespace_(char const* name); + namespace_& operator[](scope s); + + private: + struct registration_; + registration_* m_registration; + }; + + class LUABIND_API module_ + { + public: + module_(lua_State* L_, char const* name); + void operator[](scope s); + + private: + lua_State* m_state; + char const* m_name; + }; + + inline module_ module(lua_State* L, char const* name = 0) + { + return module_(L, name); + } + +} // namespace luabind + +#endif // NEW_SCOPE_040211_HPP + diff --git a/include/luabind/tag_function.hpp b/include/luabind/tag_function.hpp new file mode 100644 index 0000000..4788d42 --- /dev/null +++ b/include/luabind/tag_function.hpp @@ -0,0 +1,87 @@ +// Copyright Daniel Wallin 2008. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !BOOST_PP_IS_ITERATING + +# ifndef LUABIND_TAG_FUNCTION_081129_HPP +# define LUABIND_TAG_FUNCTION_081129_HPP + +# if LUABIND_MAX_ARITY <= 8 +# include +# else +# include +# endif +# include +# include +# include +# include + +namespace luabind { + +namespace detail +{ + + template + struct tagged_function + { + tagged_function(F f) + : f(f) + {} + + F f; + }; + + template + Signature deduce_signature(tagged_function const&, ...) + { + return Signature(); + } + + template + int invoke( + lua_State* L, tagged_function const& tagged + , Signature, Policies const& policies) + { + return invoke(L, tagged.f, Signature(), policies); + } + + template + struct signature_from_function; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, LUABIND_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +} // namespace detail + +template +detail::tagged_function< + typename detail::signature_from_function::type + , F +> +tag_function(F f) +{ + return f; +} + +} // namespace luabind + +# endif // LUABIND_TAG_FUNCTION_081129_HPP + +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() +# define NPLUS1 BOOST_PP_INC(N) + +template +struct signature_from_function +{ + typedef BOOST_PP_CAT(mpl::vector, NPLUS1)< + R BOOST_PP_ENUM_TRAILING_PARAMS(N, A) + > type; +}; + +#endif // BOOST_PP_IS_ITERATING + + diff --git a/include/luabind/value_wrapper.hpp b/include/luabind/value_wrapper.hpp new file mode 100755 index 0000000..8e09395 --- /dev/null +++ b/include/luabind/value_wrapper.hpp @@ -0,0 +1,168 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_VALUE_WRAPPER_050419_HPP +#define LUABIND_VALUE_WRAPPER_050419_HPP + +#include +#include +#include + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define LUABIND_USE_VALUE_WRAPPER_TAG +#else +#endif + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +namespace luabind { + +// +// Concept ``ValueWrapper`` +// + +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG +template +struct value_wrapper_traits; + +namespace detail +{ + + BOOST_MPL_HAS_XXX_TRAIT_DEF(value_wrapper_tag); + + struct unspecialized_value_wrapper_traits + { + typedef boost::mpl::false_ is_specialized; + }; + + template + struct value_wrapper_traits_aux + { + typedef value_wrapper_traits type; + }; + +} // namespace detail +#endif + +template +struct value_wrapper_traits +#ifdef LUABIND_USE_VALUE_WRAPPER_TAG + : boost::mpl::eval_if< + boost::mpl::and_< + boost::mpl::not_< + boost::mpl::or_< + boost::is_reference + , boost::is_pointer + , boost::is_array + > + > + , detail::has_value_wrapper_tag + > + , detail::value_wrapper_traits_aux + , boost::mpl::identity + >::type +{}; +#else +{ + typedef boost::mpl::false_ is_specialized; +}; +#endif + +template +struct is_value_wrapper + : boost::mpl::aux::msvc_eti_base< + typename value_wrapper_traits::is_specialized + >::type +{}; + +} // namespace luabind + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +# include +# include + +namespace luabind { + +template +struct is_value_wrapper_arg + : is_value_wrapper< + typename boost::remove_const< + typename boost::remove_reference::type + >::type + > +{}; + +} // namespace luabind + +#else + +# include +# include + +namespace luabind { + +namespace detail +{ + template + typename is_value_wrapper::type is_value_wrapper_arg_check(T const*); + + yes_t to_yesno(boost::mpl::true_); + no_t to_yesno(boost::mpl::false_); + + template + struct is_value_wrapper_arg_aux + { + static typename boost::add_reference::type x; + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(to_yesno(is_value_wrapper_arg_check(&x))) + == sizeof(yes_t) + ); + + typedef boost::mpl::bool_ type; + }; + +} // namespace detail + +template +struct is_value_wrapper_arg + : detail::is_value_wrapper_arg_aux::type +{ +}; + +} // namespace luabind + +#endif + +#endif // LUABIND_VALUE_WRAPPER_050419_HPP + diff --git a/include/luabind/weak_ref.hpp b/include/luabind/weak_ref.hpp new file mode 100755 index 0000000..9eb7e24 --- /dev/null +++ b/include/luabind/weak_ref.hpp @@ -0,0 +1,59 @@ +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// 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 WEAK_REF_040402_HPP +#define WEAK_REF_040402_HPP + +#include + +struct lua_State; + +namespace luabind { + + class LUABIND_API weak_ref + { + public: + weak_ref(); + weak_ref(lua_State*, int); + weak_ref(weak_ref const&); + ~weak_ref(); + + weak_ref& operator=(weak_ref const&); + + void swap(weak_ref&); + + // returns a unique id that no + // other weak ref will return + int id() const; + + lua_State* state() const; + void get(lua_State* L) const; + + private: + struct impl; + impl* m_impl; + }; + +} // namespace luabind + +#endif // WEAK_REF_040402_HPP + diff --git a/include/luabind/wrapper_base.hpp b/include/luabind/wrapper_base.hpp new file mode 100755 index 0000000..cc8026a --- /dev/null +++ b/include/luabind/wrapper_base.hpp @@ -0,0 +1,188 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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. + +#if !BOOST_PP_IS_ITERATING + +#ifndef LUABIND_WRAPPER_BASE_HPP_INCLUDED +#define LUABIND_WRAPPER_BASE_HPP_INCLUDED + +#include +#include +#include +#include + +#include +#include + +namespace luabind +{ + namespace detail + { + struct wrap_access; + + // implements the selection between dynamic dispatch + // or default implementation calls from within a virtual + // function wrapper. The input is the self reference on + // the top of the stack. Output is the function to call + // on the top of the stack (the input self reference will + // be popped) + LUABIND_API void do_call_member_selection(lua_State* L, char const* name); + } + + struct wrapped_self_t: weak_ref + { + detail::lua_reference m_strong_ref; + }; + + struct wrap_base + { + friend struct detail::wrap_access; + wrap_base() {} + + #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) + #include BOOST_PP_ITERATE() + + private: + wrapped_self_t m_self; + }; + +#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 2)) +#include BOOST_PP_ITERATE() + + namespace detail + { + struct wrap_access + { + static wrapped_self_t const& ref(wrap_base const& b) + { + return b.m_self; + } + + static wrapped_self_t& ref(wrap_base& b) + { + return b.m_self; + } + }; + } +} + +#endif // LUABIND_WRAPPER_BASE_HPP_INCLUDED + +#elif BOOST_PP_ITERATION_FLAGS() == 1 + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + template + typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type + call(char const* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _), detail::type_* = 0) const + { + typedef boost::tuples::tuple tuple_t; + #if BOOST_PP_ITERATION() == 0 + tuple_t args; + #else + tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); + #endif + + typedef typename boost::mpl::if_ + , luabind::detail::proxy_member_void_caller > + , luabind::detail::proxy_member_caller > >::type proxy_type; + + // this will be cleaned up by the proxy object + // once the call has been made + + // TODO: what happens if this virtual function is + // dispatched from a lua thread where the state + // pointer is different? + + // get the function + lua_State* L = m_self.state(); + m_self.get(L); + assert(!lua_isnil(L, -1)); + detail::do_call_member_selection(L, name); + + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + throw std::runtime_error("Attempt to call nonexistent function"); + } + + // push the self reference as the first parameter + m_self.get(L); + + // now the function and self objects + // are on the stack. These will both + // be popped by pcall + return proxy_type(L, args); + } + +#undef LUABIND_CALL_MEMBER_NAME +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + +#else // free call_member forwardarding functions + +#define N BOOST_PP_ITERATION() + +#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * +#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n + + template< + class R + BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) + > + typename boost::mpl::if_< + boost::is_void + , detail::proxy_member_void_caller< + boost::tuples::tuple< + BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) + > + > + , detail::proxy_member_caller< + R + , boost::tuples::tuple< + BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) + > + > + >::type + call_member( + wrap_base const* self + , char const* fn + BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, &a) + , detail::type_* = 0 + ) + { + return self->call( + fn + BOOST_PP_ENUM_TRAILING_PARAMS(N, a) + , (detail::type_*)0 + ); + } + +#undef LUABIND_OPERATOR_PARAMS +#undef LUABIND_TUPLE_PARAMS + +#undef N + +#endif diff --git a/include/luabind/yield_policy.hpp b/include/luabind/yield_policy.hpp new file mode 100755 index 0000000..9dbbefa --- /dev/null +++ b/include/luabind/yield_policy.hpp @@ -0,0 +1,67 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// 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 LUABIND_YIELD_POLICY_HPP_INCLUDED +#define LUABIND_YIELD_POLICY_HPP_INCLUDED + +#include +#include + +namespace luabind { namespace detail +{ + struct yield_policy + { + static void precall(lua_State*, const index_map&) {} + static void postcall(lua_State*, const index_map&) {} + }; + + template + struct has_yield + { + BOOST_STATIC_CONSTANT(bool, + value = (boost::is_same::value || + has_yield::value)); + }; + + template<> + struct has_yield + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +}} + +namespace luabind +{ + detail::policy_cons const yield = {}; + + namespace detail + { + inline void ignore_unused_yield() + { + (void)yield; + } + } +} + +#endif // LUABIND_YIELD_POLICY_HPP_INCLUDED + diff --git a/include/math/math.h b/include/math/math.h new file mode 100644 index 0000000..3ccc14a --- /dev/null +++ b/include/math/math.h @@ -0,0 +1,329 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file math.h + * + * Contains all relevant math related classes. + */ + +#pragma once + +#include + +#include "vector.h" + +namespace tre { + + /* + * Constants + */ + + /** PI constant */ + const float pi = 3.1415926535897932384626433832795f; + + /* + * Helper functions + */ + + /** Converts angle from degrees to radians + ((d)*2.0f*PI/360.0f) */ + template + inline T Deg2Rad(T a) {return a * 0.01745329252f;} + + /** Converts angle from radians to degrees + ((r)*360.0f/(2.0f*PI)) */ + template + inline T Rad2Deg(T a) {return a * 57.29577951f;} + + /* + * Declarations of all classes + */ + + template class Line2; + template class Line3; + template class Plane; + + /* + * Convenience typedefs + */ + typedef Plane Planef; + typedef Plane Planed; + + /* + * Declarations of utility functions + */ + + template T Distance + (const Vector2 & v, const Line2 & l); + template T Distance + (const Line2 & l, const Vector2 & v); + template T Distance + (const Vector3 & v, const Line3 & l); + template T Distance + (const Line3 & l, const Vector3 & v); + template T Distance + (const Vector3 & v, const Plane & p); + template T Distance + (const Plane & p, const Vector3 & v); + + template T BezierInterpolation + (T t, const T & cp1, const T & cp2, const T & cp3, const T & cp4); + + template + T Lerp(T t, const T & p1, const T & p2); + + /* + * Line classes + */ + + template + class Line2 { + public: + Vector2 A; // X = A + t*s + Vector2 s; + + Vector2 n; // ax + by + c = 0 => a*n.x + b*n.y - c = 0 + T c; // represents distance from origin + + public: + Line2() {} + Line2(const Vector2 & v1, const Vector2 & v2); + Line2(const Line2 & l) : A(l.A), s(l.s), n(l.n), c(l.c) {} + + void operator = (const Line2 & l); + + void Set(const Vector2 & vA, const Vector2 & vs); + + T GetParam(const Vector2 & v) const; + }; + + template + class Line3 { + public: + Vector3 A; // parametrical representation: X = A + t*s + Vector3 s; + + public: + Line3() {} + Line3(const Vector3 & v1, const Vector3 & v2) : A(v1), s(v2) {} + Line3(const Line3 & l) : A(l.A), s(l.s) {} + + Line3 & operator = (const Line3 & l); + + void Set(const Vector3 & b, const Vector3 & t); + + T GetParam(Vector3 & v) const; + }; + + /* + * Plane + */ + + template + class Plane { + public: + Vector3 n; // ax + by + cz + d = 0 => a*n.x + b*n.y + c*n.z - d = 0 + T d; // represents distance from origin + + public: + Plane() {} + Plane(const Vector3 & v1, T f) : n(v1), d(f) {} + Plane(const Vector3 & v1, const Vector3 & v2, const Vector3 & v3) + {ABCD(v1,v2,v3);} + + Plane & operator = (const Plane & p); + + void ABCD(const Vector3 & v1, const Vector3 & v2, + const Vector3 & v3); + void Set(const Vector3 & v, T f); + }; + + /* + * Inline methods + */ + template + inline Line2::Line2(const Vector2 & v1, const Vector2 & v2) + : A(v1), s(v2) + { + n.x = s.y; + n.y = -s.x; + n.Normalize(); + c = A.x*n.x + A.y*n.y; + } + + template + inline void Line2::operator = (const Line2 & l) + { + A = l.A; + s = l.s; + n = l.n; + c = l.c; + } + + template + inline void Line2::Set(const Vector2 & vA, const Vector2 & vs) + { + A = vA; + s = vs; + + n.x = s.y; + n.y = -s.x; + n.Normalize(); + c = Dot(A, n); + } + + // returns parameter t for point v (v = A + s*t) + template + inline T Line2::GetParam(const Vector2 & v) const + { + return s.x != 0.0f ? (v.x - A.x) / s.x : (v.y - A.y) / s.y; + } + + template + inline Line3 & Line3::operator = (const Line3 & l) + { + A = l.A; + s = l.s; + return *this; + } + + template + inline void Line3::Set(const Vector3 & b, const Vector3 & t) + { + A = b; + s = t; + } + + // returns parameter t for point v (v = A + s*t) + template + inline T Line3::GetParam(Vector3 & v) const + { + if(s.x != 0.0f) + return (v.x - A.x) / s.x; + else if(s.y != 0.0f) + return (v.y - A.y) / s.y; + else { + return (v.z - A.z) / s.z; + } + } + + template + inline void Plane::ABCD + (const Vector3 & v1, const Vector3 & v2, const Vector3 & v3) + { + n.Cross(v2 - v1, v3 - v1); + n.Normalize(); + d = Dot(n, v2); + } + + template + inline Plane & Plane::operator = (const Plane & p) + { + n = p.n; + d = p.d; + return *this; + } + + template + inline void Plane::Set(const Vector3 & v, T f) + { + n = v; + d = f; + } + + /* + * Utility functions + */ + + template + inline T Distance(const Vector2 & v, const Line2 & l) + { + return Distance(l, v); + } + + template + inline T Distance(const Line2 & l, const Vector2 & v) + { + return Dot(l.n, v) - l.c; + } + + template + inline T Distance(const Vector3 & v, const Line3 & l) + { + return Distance(l, v); + } + + template + inline T Distance(const Line3 & l, const Vector3 & v) + { + Vector3 v2, up; + Plane p; + + v2 = l.A + l.s; + up = l.A + v2.Cross(v - l.A); + p.ABCD(l.A, v2, up); + return Distance(p, v); + } + + template + inline T Distance(const Vector3 & v, const Plane & p) + { + return Distance(p, v); + } + + template + inline T Distance(const Plane & p, const Vector3 & v) + { + return Dot(p.n, v) - p.d; + } + + /** Interpolates curve using simple linear equation. + * + * @param[in] t Time - position on curve. + * @param[in] p1 Start point. + * @param[in] p2 End point. + * @return point on curve. + */ + template + T LinearInterpolation(float t, const T & p1, const T & p2) + { + return t * p1 + (1.0f - t) * p2; + } + + /** Interpolates curve using Bernstein multinominals. + * + * @param[in] t Time - position on curve. + * @param[in] p1 Start point. + * @param[in] p2 First control point. + * @param[in] p3 Second control point. + * @param[in] p4 End point. + * @return point on curve. + */ + template T BezierInterpolation + (T t, const T & cp1, const T & cp2, const T & cp3, const T & cp4) + { + T comp = 1.0 - t; // substitution + + T res = (comp * comp * comp) * cp1; + res += (3.0f * comp * comp * t) * cp2; + res += (3.0f * comp * t * t) * cp3; + res += (t * t * t) * cp4; + return res; + } +} diff --git a/include/math/matrix.h b/include/math/matrix.h new file mode 100644 index 0000000..24cfd96 --- /dev/null +++ b/include/math/matrix.h @@ -0,0 +1,810 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file matrix.h + * + * Contains all relevant math related classes. + */ + +#pragma once + +#include + +#include "assertion.h" +#include "vector.h" + +namespace tre { + + /* + * Declarations of all classes + */ + + template class Matrix2x2; + template class Matrix3x3; + template class Matrix4x4; + + /* + * Convenience typedefs + */ + typedef Matrix2x2 Matrix2x2f; + typedef Matrix3x3 Matrix3x3f; + typedef Matrix4x4 Matrix4x4f; + typedef Matrix2x2 Matrix2x2d; + typedef Matrix3x3 Matrix3x3d; + typedef Matrix4x4 Matrix4x4d; + + /* + * Declarations of utility functions + */ + + template const Matrix2x2 operator * + (const Matrix2x2 & l, const Matrix2x2 & r); + template const Matrix3x3 operator * + (const Matrix3x3 & l, const Matrix3x3 & r); + template const Matrix4x4 operator * + (const Matrix4x4 & l, const Matrix4x4 & r); + + template const Matrix4x4 operator * + (const Matrix4x4 & l, const Matrix3x3 & r); + template const Matrix4x4 operator * + (const Matrix3x3 & l, const Matrix4x4 & r); + + template const Vector2 operator * + (const Matrix2x2 & l, const Vector2 & r); + template const Vector3 operator * + (const Matrix3x3 & l, const Vector3 & r); + template const Vector3 operator * + (const Matrix4x4 & l, const Vector3 & r); + template const Vector4 operator * + (const Matrix4x4 & l, const Vector4 & r); + + /* + * Matrix classes + */ + + template + class Matrix2x2 { + public: + Vector2 c1, c2; + + public: + Matrix2x2() {} + Matrix2x2(const Matrix2x2 & m) : c1(m.c1), c2(m.c2) {} + Matrix2x2(const Vector2 & v1, const Vector2 & v2) + : c1(v1), c2(v2) {} + + const Matrix2x2 operator + (const Matrix2x2 & m) const; + const Matrix2x2 operator - (const Matrix2x2 & m) const; + const Matrix2x2 operator * (T f) const; + const Matrix2x2 operator / (T f) const; + + const Matrix2x2 operator - () const; + + Matrix2x2 & operator += (const Matrix2x2 & m); + Matrix2x2 & operator -= (const Matrix2x2 & m); + Matrix2x2 & operator *= (T f); + Matrix2x2 & operator /= (T f); + + bool operator == (const Matrix2x2 & m) const; + bool operator != (const Matrix2x2 & m) const; + + Matrix2x2 & operator = (const Matrix2x2 & m); + + Vector2 & operator [] (unsigned i); + const Vector2 & operator [] (unsigned i) const; + + void Set(const Vector2 & v1, const Vector2 & v2); + + void Identity(void); + + const Matrix2x2 Transpose(void) const; + void TransposeSelf(void); + }; + + template + class Matrix3x3 { + public: + static const Matrix3x3 CreateSMatrix(const Vector3 & s); + static const Matrix3x3 CreateInvSMatrix(const Vector3 & s); + static const Matrix3x3 CreateRMatrix(const Quaternion & r); + + public: + Vector3 c1, c2, c3; + + public: + Matrix3x3() {} + Matrix3x3(const Matrix3x3 & m) : c1(m.c1), c2(m.c2), c3(m.c3) {} + Matrix3x3(const Vector3 & v1, const Vector3 & v2, + const Vector3 & v3) : c1(v1), c2(v2), c3(v3) {} + + const Matrix3x3 operator + (const Matrix3x3 & m) const; + const Matrix3x3 operator - (const Matrix3x3 & m) const; + const Matrix3x3 operator * (T f) const; + const Matrix3x3 operator / (T f) const; + + const Matrix3x3 operator - () const; + + Matrix3x3 & operator += (const Matrix3x3 & m); + Matrix3x3 & operator -= (const Matrix3x3 & m); + Matrix3x3 & operator *= (T f); + Matrix3x3 & operator /= (T f); + + bool operator == (const Matrix3x3 & m) const; + bool operator != (const Matrix3x3 & m) const; + + Matrix3x3 & operator = (const Matrix3x3 & m); + + Vector3 & operator [] (unsigned i); + const Vector3 & operator [] (unsigned i) const; + + void Set(const Vector3 & v1, const Vector3 & v2, + const Vector3 & v3); + + void Identity(void); + + const Matrix3x3 Transpose(void) const; + void TransposeSelf(void); + }; + + template + class Matrix4x4 { + public: + static const Matrix4x4 CreateTMatrix(const Vector3 & p); + static const Matrix4x4 CreateInvTMatrix(const Vector3 & p); + + public: + Vector4 c1, c2, c3, c4; + + public: + Matrix4x4() {} + Matrix4x4(const Matrix4x4 & m) + : c1(m.c1), c2(m.c2), c3(m.c3), c4(m.c4) {} + Matrix4x4(const Vector4 & v1, const Vector4 & v2, + const Vector4 & v3, const Vector4 & v4) + : c1(v1), c2(v2), c3(v3), c4(v4) {} + + const Matrix4x4 operator + (const Matrix4x4 & m) const; + const Matrix4x4 operator - (const Matrix4x4 & m) const; + const Matrix4x4 operator * (T f) const; + const Matrix4x4 operator / (T f) const; + + const Matrix4x4 operator - () const; + + Matrix4x4 & operator += (const Matrix4x4 & m); + Matrix4x4 & operator -= (const Matrix4x4 & m); + Matrix4x4 & operator *= (T f); + Matrix4x4 & operator /= (T f); + + bool operator == (const Matrix4x4 & m) const; + bool operator != (const Matrix4x4 & m) const; + + Matrix4x4 & operator = (const Matrix4x4 & m); + + Vector4 & operator [] (unsigned i); + const Vector4 & operator [] (unsigned i) const; + + void Set(const Vector4 & v1, const Vector4 & v2, + const Vector4 & v3, const Vector4 & v4); + + void Identity(void); + + const Matrix4x4 Transpose(void) const; + void TransposeSelf(void); + }; + + /* + * Static member functions + */ + + template + const Matrix3x3 Matrix3x3::CreateSMatrix(const Vector3 & s) + { + return Matrix3x3( + Vector3(s.x, 0.0f, 0.0f), + Vector3(0.0f, s.y, 0.0f), + Vector3(0.0f, 0.0f, s.z)); + } + + template + const Matrix3x3 Matrix3x3::CreateInvSMatrix(const Vector3 & s) + { + return Matrix3x3f( + Vector3f(1.0f / s.x, 0.0f, 0.0f), + Vector3f(0.0f, 1.0f / s.y, 0.0f), + Vector3f(0.0f, 0.0f, 1.0f / s.z)); + } + + template + const Matrix3x3 Matrix3x3::CreateRMatrix(const Quaternion & r) + { + T wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; + + // calculate coefficients + x2 = r.x + r.x; y2 = r.y + r.y; + z2 = r.z + r.z; + xx = r.x * x2; xy = r.x * y2; xz = r.x * z2; + yy = r.y * y2; yz = r.y * z2; zz = r.z * z2; + wx = r.w * x2; wy = r.w * y2; wz = r.w * z2; + + Matrix3x3 m; + + m.c1.x = 1.0f - (yy + zz); + m.c1.y = xy - wz; + m.c1.z = xz + wy; + m.c2.x = xy + wz; + m.c2.y = 1.0f - (xx + zz); + m.c2.z = yz - wx; + m.c3.x = xz - wy; + m.c3.y = yz + wx; + m.c3.z = 1.0f - (xx + yy); + return m; + } + + template + const Matrix4x4 Matrix4x4::CreateTMatrix(const Vector3 & p) + { + return Matrix4x4( + Vector4(1.0f, 0.0f, 0.0f, 0.0f), + Vector4(0.0f, 1.0f, 0.0f, 0.0f), + Vector4(0.0f, 0.0f, 1.0f, 0.0f), + Vector4(p.x, p.y, p.z, 1.0f)); + } + + template + const Matrix4x4 Matrix4x4::CreateInvTMatrix(const Vector3 & p) + { + return Matrix4x4( + Vector4(1.0f, 0.0f, 0.0f, 0.0f), + Vector4(0.0f, 1.0f, 0.0f, 0.0f), + Vector4(0.0f, 0.0f, 1.0f, 0.0f), + Vector4(-p.x, -p.y, -p.z, 1.0f)); + } + + /* + * Inline methods + */ + + template + inline const Matrix2x2 Matrix2x2::operator + + (const Matrix2x2 & m) const + { + return Matrix2x2(c1 + m.c1, c2 + m.c2); + } + + template + inline const Matrix2x2 Matrix2x2::operator - + (const Matrix2x2 & m) const + { + return Matrix2x2(c1 - m.c1, c2 - m.c2); + } + + template + inline const Matrix2x2 Matrix2x2::operator * (T f) const + { + return Matrix2x2(c1 * f, c2 * f); + } + + template + inline const Matrix2x2 Matrix2x2::operator / (T f) const + { + return Matrix2x2(c1 / f, c2 / f); + } + + template + inline const Matrix2x2 Matrix2x2::operator - () const + { + return Matrix2x2(-c1, -c2); + } + + template + inline Matrix2x2 & Matrix2x2::operator += (const Matrix2x2 & m) + { + c1 += m.c1; + c2 += m.c2; + return *this; + } + + template + inline Matrix2x2 & Matrix2x2::operator -= (const Matrix2x2 & m) + { + c1 -= m.c1; + c2 -= m.c2; + return *this; + } + + template + inline Matrix2x2 & Matrix2x2::operator *= (T f) + { + c1 *= f; + c2 *= f; + return *this; + } + + template + inline Matrix2x2 & Matrix2x2::operator /= (T f) + { + c1 /= f; + c2 /= f; + return *this; + } + + template + inline bool Matrix2x2::operator == (const Matrix2x2 & m) const + { + return (c1 == m.c1) && (c2 == m.c2); + } + + template + inline bool Matrix2x2::operator != (const Matrix2x2 & m) const + { + return (c1 != m.c1) || (c2 != m.c2); + } + + template + inline Matrix2x2 & Matrix2x2::operator = (const Matrix2x2 & m) + { + c1 = m.c1; + c2 = m.c2; + return *this; + } + + template + inline Vector2 & Matrix2x2::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 2); + return *(&c1 + i); + } + + template + inline const Vector2 & Matrix2x2::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 2); + return *(&c1 + i); + } + + template + inline void Matrix2x2::Set(const Vector2 & v1, const Vector2 & v2) + { + c1 = v1; + c2 = v2; + } + + template + inline void Matrix2x2::Identity(void) + { + c1.Set(1.0f, 0.0f); + c2.Set(0.0f, 1.0f); + } + + template + inline const Matrix2x2 Matrix2x2::Transpose(void) const + { + return Matrix2x2(Vector2(c1.x, c2.x), Vector2(c1.y, c2.y)); + } + + template + inline void Matrix2x2::TransposeSelf(void) + { + std::swap(c1.y, c2.x); + } + + template + inline const Matrix3x3 Matrix3x3::operator + + (const Matrix3x3 & m) const + { + return Matrix3x3(c1 + m.c1, c2 + m.c2, c3 + m.c3); + } + + template + inline const Matrix3x3 Matrix3x3::operator - + (const Matrix3x3 & m) const + { + return Matrix3x3(c1 - m.c1, c2 - m.c2, c3 - m.c3); + } + + template + inline const Matrix3x3 Matrix3x3::operator - () const + { + return Matrix3x3(-c1, -c2, -c3); + } + + template + inline const Matrix3x3 Matrix3x3::operator * (T f) const + { + return Matrix3x3(c1 * f, c2 * f, c3 * f); + } + + template + inline const Matrix3x3 Matrix3x3::operator / (T f) const + { + return Matrix3x3(c1 / f, c2 / f, c3 / f); + } + + template + inline Matrix3x3 & Matrix3x3::operator += (const Matrix3x3 & m) + { + c1 += m.c1; + c2 += m.c2; + c3 += m.c3; + return *this; + } + + template + inline Matrix3x3 & Matrix3x3::operator -= (const Matrix3x3 & m) + { + c1 -= m.c1; + c2 -= m.c2; + c3 -= m.c3; + return *this; + } + + template + inline Matrix3x3 & Matrix3x3::operator *= (T f) + { + c1 *= f; + c2 *= f; + c3 *= f; + return *this; + } + + template + inline Matrix3x3 & Matrix3x3::operator /= (T f) + { + c1 /= f; + c2 /= f; + c3 /= f; + return *this; + } + + template + inline bool Matrix3x3::operator == (const Matrix3x3 & m) const + { + return (c1 == m.c1) && (c2 == m.c2) && (c3 == m.c3); + } + + template + inline bool Matrix3x3::operator != (const Matrix3x3 & m) const + { + return (c1 != m.c1) || (c2 != m.c2) || (c3 != m.c3); + } + + template + inline Matrix3x3 & Matrix3x3::operator = (const Matrix3x3 & m) + { + c1 = m.c1; + c2 = m.c2; + c3 = m.c3; + return *this; + } + + template + inline Vector3 & Matrix3x3::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 3); + return *(&c1 + i); + } + + template + inline const Vector3 & Matrix3x3::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 3); + return *(&c1 + i); + } + + template + inline void Matrix3x3::Set + (const Vector3 & v1, const Vector3 & v2, const Vector3 & v3) + { + c1 = v1; + c2 = v2; + c3 = v3; + } + + template + inline void Matrix3x3::Identity(void) + { + c1.Set(1.0f, 0.0f, 0.0f); + c2.Set(0.0f, 1.0f, 0.0f); + c3.Set(0.0f, 0.0f, 1.0f); + } + + template + inline const Matrix3x3 Matrix3x3::Transpose(void) const + { + return Matrix3x3(Vector3(c1.x, c2.x, c3.x), Vector3(c1.y, c2.y, c3.y), + Vector3(c1.z, c2.z, c3.z)); + } + + template + inline void Matrix3x3::TransposeSelf(void) + { + std::swap(c1.y, c2.x); + std::swap(c1.z, c3.x); + std::swap(c2.z, c3.y); + } + + template + inline const Matrix4x4 Matrix4x4::operator + + (const Matrix4x4 & m) const + { + return Matrix4x4(c1 + m.c1, c2 + m.c2, c3 + m.c3, c4 + m.c4); + } + + template + inline const Matrix4x4 Matrix4x4::operator - + (const Matrix4x4 & m) const + { + return Matrix4x4(c1 - m.c1, c2 - m.c2, c3 - m.c3, c4 - m.c4); + } + + template + inline const Matrix4x4 Matrix4x4::operator - () const + { + return Matrix4x4(-c1, -c2, -c3, -c4); + } + + template + inline const Matrix4x4 Matrix4x4::operator * (T f) const + { + return Matrix4x4(c1 * f, c2 * f, c3 * f, c4 * f); + } + + template + inline const Matrix4x4 Matrix4x4::operator / (T f) const + { + return Matrix4x4(c1 / f, c2 / f, c3 / f, c4 / f); + } + + template + inline Matrix4x4 & Matrix4x4::operator += (const Matrix4x4 & m) + { + c1 += m.c1; + c2 += m.c2; + c3 += m.c3; + c4 += m.c4; + return *this; + } + + template + inline Matrix4x4 & Matrix4x4::operator -= (const Matrix4x4 & m) + { + c1 -= m.c1; + c2 -= m.c2; + c3 -= m.c3; + c4 -= m.c4; + return *this; + } + + template + inline Matrix4x4 & Matrix4x4::operator *= (T f) + { + c1 *= f; + c2 *= f; + c3 *= f; + c4 *= f; + return *this; + } + + template + inline Matrix4x4 & Matrix4x4::operator /= (T f) + { + c1 /= f; + c2 /= f; + c3 /= f; + c4 /= f; + return *this; + } + + template + inline bool Matrix4x4::operator == (const Matrix4x4 & m) const + { + return (c1 == m.c1) && (c2 == m.c2) && (c3 == m.c3) && (c4 == m.c4); + } + + template + inline bool Matrix4x4::operator != (const Matrix4x4 & m) const + { + return (c1 != m.c1) || (c2 != m.c2) || (c3 != m.c3) || (c4 != m.c4); + } + + template + inline Matrix4x4 & Matrix4x4::operator = (const Matrix4x4 & m) + { + c1 = m.c1; + c2 = m.c2; + c3 = m.c3; + c4 = m.c4; + return *this; + } + + template + inline Vector4 & Matrix4x4::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 4); + return *(&c1 + i); + } + + template + inline const Vector4 & Matrix4x4::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 4); + return *(&c1 + i); + } + + template + inline void Matrix4x4::Set(const Vector4 & v1, const Vector4 & v2, + const Vector4 & v3, const Vector4 & v4) + { + c1 = v1; + c2 = v2; + c3 = v3; + c4 = v4; + } + + template + inline void Matrix4x4::Identity(void) + { + c1.Set(1.0f, 0.0f, 0.0f, 0.0f); + c2.Set(0.0f, 1.0f, 0.0f, 0.0f); + c3.Set(0.0f, 0.0f, 1.0f, 0.0f); + c4.Set(0.0f, 0.0f, 0.0f, 1.0f); + } + + template + inline const Matrix4x4 Matrix4x4::Transpose(void) const + { + return Matrix4x4(Vector4(c1.x, c2.x, c3.x, c4.x), + Vector4(c1.y, c2.y, c3.y, c4.y), + Vector4(c1.z, c2.z, c3.z, c4.x), + Vector4(c1.w, c2.w, c3.w, c4.w)); + } + + template + inline void Matrix4x4::TransposeSelf(void) + { + std::swap(c1.y, c2.x); + std::swap(c1.z, c3.x); + std::swap(c1.w, c4.x); + std::swap(c2.z, c3.y); + std::swap(c2.w, c4.y); + std::swap(c3.w, c4.z); + } + + /* + * Utility functions + */ + + template + const Matrix2x2 operator * (const Matrix2x2 & l, const Matrix2x2 & r) + { + return Matrix2x2( + Vector2(l.c1.x*r.c1.x + l.c2.x*r.c1.y,l.c1.y*r.c1.x + l.c2.y*r.c1.y), + Vector2(l.c1.x*r.c2.x + l.c2.x*r.c2.y,l.c1.y*r.c2.x + l.c2.y*r.c2.y)); + } + + template + const Matrix3x3 operator * (const Matrix3x3 & l, const Matrix3x3 & r) + { + return Matrix3x3( + Vector3(l.c1.x*r.c1.x + l.c2.x*r.c1.y + l.c3.x*r.c1.z, + l.c1.y*r.c1.x + l.c2.y*r.c1.y + l.c3.y*r.c1.z, + l.c1.z*r.c1.x + l.c2.z*r.c1.y + l.c3.z*r.c1.z), + Vector3(l.c1.x*r.c2.x + l.c2.x*r.c2.y + l.c3.x*r.c2.z, + l.c1.y*r.c2.x + l.c2.y*r.c2.y + l.c3.y*r.c2.z, + l.c1.z*r.c2.x + l.c2.z*r.c2.y + l.c3.z*r.c2.z), + Vector3(l.c1.x*r.c3.x + l.c2.x*r.c3.y + l.c3.x*r.c3.z, + l.c1.y*r.c3.x + l.c2.y*r.c3.y + l.c3.y*r.c3.z, + l.c1.z*r.c3.x + l.c2.z*r.c3.y + l.c3.z*r.c3.z)); + } + + template + const Matrix4x4 operator * (const Matrix4x4 & l, const Matrix4x4 & r) + { + return Matrix4x4( + Vector4(l.c1.x*r.c1.x + l.c2.x*r.c1.y + l.c3.x*r.c1.z + l.c4.x*r.c1.w, + l.c1.y*r.c1.x + l.c2.y*r.c1.y + l.c3.y*r.c1.z + l.c4.y*r.c1.w, + l.c1.z*r.c1.x + l.c2.z*r.c1.y + l.c3.z*r.c1.z + l.c4.z*r.c1.w, + l.c1.w*r.c1.x + l.c2.w*r.c1.y + l.c3.w*r.c1.z + l.c4.w*r.c1.w), + Vector4(l.c1.x*r.c2.x + l.c2.x*r.c2.y + l.c3.x*r.c2.z + l.c4.x*r.c2.w, + l.c1.y*r.c2.x + l.c2.y*r.c2.y + l.c3.y*r.c2.z + l.c4.y*r.c2.w, + l.c1.z*r.c2.x + l.c2.z*r.c2.y + l.c3.z*r.c2.z + l.c4.z*r.c2.w, + l.c1.w*r.c2.x + l.c2.w*r.c2.y + l.c3.w*r.c2.z + l.c4.w*r.c2.w), + Vector4(l.c1.x*r.c3.x + l.c2.x*r.c3.y + l.c3.x*r.c3.z + l.c4.x*r.c3.w, + l.c1.y*r.c3.x + l.c2.y*r.c3.y + l.c3.y*r.c3.z + l.c4.y*r.c3.w, + l.c1.z*r.c3.x + l.c2.z*r.c3.y + l.c3.z*r.c3.z + l.c4.z*r.c3.w, + l.c1.w*r.c3.x + l.c2.w*r.c3.y + l.c3.w*r.c3.z + l.c4.w*r.c3.w), + Vector4(l.c1.x*r.c4.x + l.c2.x*r.c4.y + l.c3.x*r.c4.z + l.c4.x*r.c4.w, + l.c1.y*r.c4.x + l.c2.y*r.c4.y + l.c3.y*r.c4.z + l.c4.y*r.c4.w, + l.c1.z*r.c4.x + l.c2.z*r.c4.y + l.c3.z*r.c4.z + l.c4.z*r.c4.w, + l.c1.w*r.c4.x + l.c2.w*r.c4.y + l.c3.w*r.c4.z + l.c4.w*r.c4.w)); + } + + template + const Matrix4x4 operator * (const Matrix4x4 & l, const Matrix3x3 & r) + { + return Matrix4x4( + Vector4(l.c1.x*r.c1.x + l.c2.x*r.c1.y + l.c3.x*r.c1.z, + l.c1.y*r.c1.x + l.c2.y*r.c1.y + l.c3.y*r.c1.z, + l.c1.z*r.c1.x + l.c2.z*r.c1.y + l.c3.z*r.c1.z, + l.c1.w*r.c1.x + l.c2.w*r.c1.y + l.c3.w*r.c1.z), + Vector4(l.c1.x*r.c2.x + l.c2.x*r.c2.y + l.c3.x*r.c2.z, + l.c1.y*r.c2.x + l.c2.y*r.c2.y + l.c3.y*r.c2.z, + l.c1.z*r.c2.x + l.c2.z*r.c2.y + l.c3.z*r.c2.z, + l.c1.w*r.c2.x + l.c2.w*r.c2.y + l.c3.w*r.c2.z), + Vector4(l.c1.x*r.c3.x + l.c2.x*r.c3.y + l.c3.x*r.c3.z, + l.c1.y*r.c3.x + l.c2.y*r.c3.y + l.c3.y*r.c3.z, + l.c1.z*r.c3.x + l.c2.z*r.c3.y + l.c3.z*r.c3.z, + l.c1.w*r.c3.x + l.c2.w*r.c3.y + l.c3.w*r.c3.z), + Vector4(l.c4.x, l.c4.y, l.c4.z, l.c4.w)); + } + + template + const Matrix4x4 operator * (const Matrix3x3 & l, const Matrix4x4 & r) + { + return Matrix4x4( + Vector4(l.c1.x*r.c1.x + l.c2.x*r.c1.y + l.c3.x*r.c1.z, + l.c1.y*r.c1.x + l.c2.y*r.c1.y + l.c3.y*r.c1.z, + l.c1.z*r.c1.x + l.c2.z*r.c1.y + l.c3.z*r.c1.z, + r.c1.w), + Vector4(l.c1.x*r.c2.x + l.c2.x*r.c2.y + l.c3.x*r.c2.z, + l.c1.y*r.c2.x + l.c2.y*r.c2.y + l.c3.y*r.c2.z, + l.c1.z*r.c2.x + l.c2.z*r.c2.y + l.c3.z*r.c2.z, + r.c2.w), + Vector4(l.c1.x*r.c3.x + l.c2.x*r.c3.y + l.c3.x*r.c3.z, + l.c1.y*r.c3.x + l.c2.y*r.c3.y + l.c3.y*r.c3.z, + l.c1.z*r.c3.x + l.c2.z*r.c3.y + l.c3.z*r.c3.z, + r.c3.w), + Vector4(l.c1.x*r.c4.x + l.c2.x*r.c4.y + l.c3.x*r.c4.z, + l.c1.y*r.c4.x + l.c2.y*r.c4.y + l.c3.y*r.c4.z, + l.c1.z*r.c4.x + l.c2.z*r.c4.y + l.c3.z*r.c4.z, + r.c4.w)); + } + + template + const Vector2 operator * (const Matrix2x2 & l, const Vector2 & r) + { + return Vector2(l.c1.x*r.x + l.c2.x*r.y, l.c1.y*r.x + l.c2.y*r.y); + } + + template + const Vector3 operator * (const Matrix3x3 & l, const Vector3 & r) + { + return Vector3(l.c1.x*r.x + l.c2.x*r.y + l.c3.x*r.z, + l.c1.y*r.x + l.c2.y*r.y + l.c3.y*r.z, + l.c1.z*r.x + l.c2.z*r.y + l.c3.z*r.z); + } + + template + const Vector3 operator * (const Matrix4x4 & l, const Vector3 & r) + { + return Vector3(l.c1.x*r.x + l.c2.x*r.y + l.c3.x*r.z + l.c4.x, + l.c1.y*r.x + l.c2.y*r.y + l.c3.y*r.z + l.c4.y, + l.c1.z*r.x + l.c2.z*r.y + l.c3.z*r.z + l.c4.z); + } + + template + const Vector4 operator * (const Matrix4x4 & l, const Vector4 & r) + { + return Vector4(l.c1.x*r.x + l.c2.x*r.y + l.c3.x*r.z + l.c4.x*r.w, + l.c1.y*r.x + l.c2.y*r.y + l.c3.y*r.z + l.c4.y*r.w, + l.c1.z*r.x + l.c2.z*r.y + l.c3.z*r.z + l.c4.z*r.w, + l.c1.w*r.x + l.c2.w*r.y + l.c3.w*r.z + l.c4.w*r.w); + } + +} diff --git a/include/math/quaternion.h b/include/math/quaternion.h new file mode 100644 index 0000000..40b064c --- /dev/null +++ b/include/math/quaternion.h @@ -0,0 +1,401 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file quaternion.h + * + * Contains all relevant math related classes. + */ + +#pragma once + +#include +#include + +#include "assertion.h" + +#include "math/matrix.h" +#include "math/vector.h" + +namespace tre { + + /* + * Declarations of all classes + */ + + template class Quaternion; + + /* + * Convenience typedefs + */ + typedef Quaternion Quaternionf; + typedef Quaternion Quaterniond; + + /* + * Quaternion class + */ + + template + class Quaternion { + public: + static const Quaternion CreateQuatFromRMatrix(const Matrix3x3 & m); + static const Quaternion CreateAxisQuaternion( + const Vector3 & axis, T angle); + static const Quaternion CreateLookAtQuaternion(const Vector3 & eye, + const Vector3 & at, const Vector3 & up); + + static const Quaternion CreateZxyYawPitchRoll(const Vector3 & ypr); + static const Quaternion CreateZxYawPitch(const Vector2 & yp); + + public: + T w, x, y, z; + + public: + Quaternion() {} + Quaternion(T f1, T f2, T f3, T f4) + : w(f1), x(f2), y(f3), z(f4) {} + Quaternion(T f, const Vector3 & v) : + w(f), x(v.x), y(v.y), z(v.z) {} + Quaternion(const Quaternion & q) : w(q.w), x(q.x), y(q.y), z(q.z) {} + + const Quaternion operator + (const Quaternion & q) const; + const Quaternion operator - (const Quaternion & q) const; + const Quaternion operator - () const; + const Quaternion operator * (T f) const; + const Quaternion operator * (const Quaternion & q) const; + const Quaternion operator / (T f) const; + + Quaternion & operator += (const Quaternion & q); + Quaternion & operator -= (const Quaternion & q); + Quaternion & operator *= (T f); + Quaternion & operator *= (const Quaternion & q); + Quaternion & operator /= (T f); + + bool operator == (const Quaternion & q) const; + bool operator != (const Quaternion & q) const; + + Quaternion & operator = (const Quaternion & q); + + T & operator [] (unsigned i); + const T & operator [] (unsigned i) const; + + void Identity(void); + + void Set(T f1, T f2, T f3, T f4); + void Set(T f, const Vector3 & v); + + T Length(void) const; + void Normalize(void); + + const Quaternion Conjugate(void) const; + }; + + /* + * Static member functions + */ + + template const Quaternion + Quaternion::CreateQuatFromRMatrix(const Matrix3x3 & m) + { + Quaternion quat; + T s; + T tr = 1.0f + m.c1.x + m.c2.y + m.c3.z; + + if (tr > std::numeric_limits::epsilon()) { + s = sqrtf(tr) * 2.0f; + quat.x = (m.c2.z - m.c3.y) / s; + quat.y = (m.c3.x - m.c1.z) / s; + quat.z = (m.c1.y - m.c2.x) / s; + quat.w = 0.25f * s; + } else { + if (m.c1.x > m.c2.y && m.c1.x > m.c3.z) { // Column 0: + s = sqrtf(1.0f + m.c1.x - m.c2.y - m.c3.z) * 2.0f; + quat.x = 0.25f * s; + quat.y = (m.c1.y + m.c2.x) / s; + quat.z = (m.c3.x + m.c1.z) / s; + quat.w = (m.c2.z - m.c3.y) / s; + } else if (m.c2.y > m.c3.z) { // Column 1: + s = sqrtf(1.0f + m.c2.y - m.c1.x - m.c3.z) * 2.0f; + quat.x = (m.c1.y + m.c2.x) / s; + quat.y = 0.25f * s; + quat.z = (m.c2.z + m.c3.y) / s; + quat.w = (m.c3.x - m.c1.z) / s; + } else { // Column 2: + s = sqrtf(1.0f + m.c3.z - m.c1.x - m.c2.y) * 2.0f; + quat.x = (m.c3.x + m.c1.z) / s; + quat.y = (m.c2.z + m.c3.y) / s; + quat.z = 0.25f * s; + quat.w = (m.c1.y - m.c2.x) / s; + } + } + return quat; + } + + template const Quaternion + Quaternion::CreateAxisQuaternion(const Vector3 & axis, T angle) + { + float s = sinf(angle / 2.0f); + return Quaternion(cosf(angle / 2.0f), + axis.x * s, axis.y * s, axis.z * s); + } + + template const Quaternion + Quaternion::CreateLookAtQuaternion + (const Vector3 & eye, const Vector3 & at, const Vector3 & up) + { + Matrix3x3 tmpm; + Vector3 dir = at - eye; + dir.Normalize(); + + Vector3 right; + right.Cross(dir, up); + right.Normalize(); + + Vector3 newup; + newup.Cross(right, dir); + newup.Normalize(); + + tmpm[0][0] = right[0]; tmpm[1][0] = right[1]; tmpm[2][0] = right[2]; + tmpm[0][1] = newup[0]; tmpm[1][1] = newup[1]; tmpm[2][1] = newup[2]; + tmpm[0][2] = -dir[0]; tmpm[1][2] = -dir[1]; tmpm[2][2] = -dir[2]; + return CreateQuatFromRMatrix(tmpm); + } + + template const Quaternion + Quaternion::CreateZxyYawPitchRoll(const Vector3 & ypr) + { + T cr, cp, cy, sr, sp, sy, cpcy, spsy; + + // calculate trig identities + cr = cosf(ypr.z / 2.0f); + cp = cosf(ypr.y / 2.0f); + cy = cosf(ypr.x / 2.0f); + sr = sinf(ypr.z / 2.0f); + sp = sinf(ypr.y / 2.0f); + sy = sinf(ypr.x / 2.0f); + + cpcy = cp * cy; + spsy = sp * sy; + + return Quaternionf(cr * cpcy + sr * spsy, + cr * sp * cy + sr * cp * sy, + sr * cpcy - cr * spsy, + cr * cp * sy - sr * sp * cy); + } + + template const Quaternion + Quaternion::CreateZxYawPitch(const Vector2 & yp) + { + T cy, cp, sy, sp; + cy = cosf(yp.x / 2.0f); + cp = cosf(yp.y / 2.0f); + sy = sinf(yp.x / 2.0f); + sp = sinf(yp.y / 2.0f); + + return Quaternion(cy * cp, cy * sp, -sy * sp, cp * sy); + } + + /* + * Inline methods + */ + + template + inline const Quaternion Quaternion::operator + + (const Quaternion & q) const + { + return Quaternion(w + q.w, x + q.x, y + q.y, z + q.z); + } + + template + inline const Quaternion Quaternion::operator - + (const Quaternion & q) const + { + return Quaternion(w - q.w, x - q.x, y - q.y, z - q.z); + } + + template + inline const Quaternion Quaternion::operator - () const + { + return Quaternion(-w, -x, -y, -z); + } + + template + inline const Quaternion Quaternion::operator * (T f) const + { + return Quaternion(f * w, f * x, f * y, f * z); + } + + template + inline const Quaternion Quaternion::operator * + (const Quaternion & q) const + { + return Quaternion(w*q.w - x*q.x - y*q.y - z*q.z, + w*q.x + q.w*x + y*q.z - z*q.y, + w*q.y + q.w*y + z*q.x - x*q.z, + w*q.z + q.w*z + x*q.y - y*q.x); + } + + template + inline const Quaternion Quaternion::operator / (T f) const + { + return Quaternion(w / f, x / f, y / f, z / f); + } + + template + inline Quaternion & Quaternion::operator += (const Quaternion & q) + { + w += q.w; + x += q.x; + y += q.y; + z += q.z; + return *this; + } + + template + inline Quaternion & Quaternion::operator -= (const Quaternion & q) + { + w -= q.w; + x -= q.x; + y -= q.y; + z -= q.z; + return *this; + } + + template + inline Quaternion & Quaternion::operator *= (T f) + { + w *= f; + x *= f; + y *= f; + z *= f; + return *this; + } + + template + inline Quaternion & Quaternion::operator *= (const Quaternion & q) + { + float a = w*q.w - x*q.x - y*q.y - z*q.z; + float b = w*q.x + q.w*x + y*q.z - z*q.y; + float c = w*q.y + q.w*y + z*q.x - x*q.z; + float d = w*q.z + q.w*z + x*q.y - y*q.x; + w = a; + x = b; + y = c; + z = d; + return *this; + } + + template + inline Quaternion & Quaternion::operator /= (T f) + { + w /= f; + x /= f; + y /= f; + z /= f; + return *this; + } + + template + inline bool Quaternion::operator == (const Quaternion & q) const + { + return (w == q.w) && (x == q.x) && (y == q.y) && (z == q.z); + } + + template + inline bool Quaternion::operator != (const Quaternion & q) const + { + return (w != q.w) || (x != q.x) || (y != q.y) || (z != q.z); + } + + template + inline Quaternion & Quaternion::operator = (const Quaternion & q) + { + w = q.w; + x = q.x; + y = q.y; + z = q.z; + return *this; + } + + template + inline T & Quaternion::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 4); + return *(&w + i); + } + + template + inline const T & Quaternion::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 4); + return *(&w + i); + } + + template + inline void Quaternion::Identity(void) + { + w = 1.0f; + x = y = z = 0.0f; + } + + template + inline void Quaternion::Set(T f1, T f2, T f3, T f4) + { + w = f1; + x = f2; + y = f3; + z = f4; + } + + template + inline void Quaternion::Set(T f, const Vector3 & v) + { + w = f; + x = v.x; + y = v.y; + z = v.z; + } + + template <> + inline float Quaternion::Length(void) const + { + return sqrtf(w*w + x*x + y*y + z*z); + } + + template <> + inline double Quaternion::Length(void) const + { + return sqrt(w*w + x*x + y*y + z*z); + } + + template + inline void Quaternion::Normalize(void) + { + T len = Length(); + + if(len > std::numeric_limits::epsilon()) + *this /= len; + } + + template + inline const Quaternion Quaternion::Conjugate(void) const + { + return Quaternion(w, -x, -y, -z); + } + +} diff --git a/include/math/transform.h b/include/math/transform.h new file mode 100644 index 0000000..332089e --- /dev/null +++ b/include/math/transform.h @@ -0,0 +1,327 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file transform.h + * + * Encapsulation of object transformations. + */ + +#pragma once + +#include + +#include "math/vector.h" +#include "math/matrix.h" +#include "math/quaternion.h" + +namespace tre { + + template + class Transform; + + typedef Transform Transformf; + typedef Transform Transformd; + + template + class Transform { + public: + public: + Transform(); + Transform(const Transform & t); + + void LookAtObject(const Vector3 & at); + void LookAtObject(const Vector3 & at, const Vector3 & up); + void LookAtWorld(const Vector3 & at); + void LookAtWorld(const Vector3 & at, const Vector3 & up); + + void RotateAxis(const Vector3 & axis, float angle); + void RotateAbsX(T angle); + void RotateAbsY(T angle); + void RotateAbsZ(T angle); + + void RotateRelX(T angle) {RotateAxis(GetObjectX(), angle);} + void RotateRelY(T angle) {RotateAxis(GetObjectY(), angle);} + void RotateRelZ(T angle) {RotateAxis(GetObjectZ(), angle);} + + void MoveAbs(const Vector3 & pos); + void MoveRel(const Vector3 & pos); + + const bool HasScale(void) const {return hasScale_;} + + const Transform * GetWParent(void) const {return wParent_;} + + const Vector3 & GetOPosition(void) const {return oPosition_;} + const Vector3 GetWPosition(void) const + {return Vector3(wTransform_.c4);} + const Vector3 & GetOScale(void) const {return oScale_;} + const Quaternion & GetORotation(void) const {return oRotation_;} + + const Vector3 & GetObjectX(void) const {return vMatrix_.c1;} + const Vector3 & GetObjectY(void) const {return vMatrix_.c2;} + const Vector3 & GetObjectZ(void) const {return vMatrix_.c3;} + + const Vector3 GetWorldX(void) const; + const Vector3 GetWorldY(void) const; + const Vector3 GetWorldZ(void) const; + + const Matrix4x4 & GetWTransform(void) const {return wTransform_;} + const Matrix4x4 GetOTransform(void) const; + const Matrix4x4 GetInverseWTransform(void) const; + const Matrix4x4 GetInverseOTransform(void) const; + + void SetWParent(const Transform * parent); + void SetOPosition(const Vector3 & pos); + + void SetOScale(const Vector3 & scale); + void SetORotation(const Quaternion & rot); + + void ResetOPosition(void); + void ResetOScale(void); + void ResetORotation(void); + + private: + bool hasScale_; + + const Transform * wParent_; + + Vector3 oPosition_; + Vector3 oScale_; + Quaternion oRotation_; + + Matrix4x4 wTransform_; + + Matrix3x3 vMatrix_; + + void UpdateTransform(void); + }; + + template + Transform::Transform() : hasScale_(false), wParent_(NULL), + oPosition_(0.0f), oScale_(1.0f) + { + oRotation_.Identity(); + UpdateTransform(); + } + + template + Transform::Transform(const Transform & t) + : hasScale_(false), wParent_(t.wParent_), oPosition_(t.oPosition_), + oScale_(t.oScale_), oRotation_(t.oRotation_), + wTransform_(t.wTransform_), vMatrix_(t.vMatrix_) + { + } + + template + inline void Transform::LookAtObject(const Vector3 & at) + { + LookAtObject(at, GetObjectY()); + } + + template inline void + Transform::LookAtObject(const Vector3 & at, const Vector3 & up) + { + SetORotation(CreateLookAtQuaternion(oPosition_, at, up)); + } + + template + inline void Transform::LookAtWorld(const Vector3 & at) + { + LookAtWorld(at, Vector3(0.0f, 0.0f, 1.0f)); + } + + template + inline void Transform::LookAtWorld + (const Vector3 & at, const Vector3 & up) + { + Vector3 newat(GetInverseWTransform() * at); + SetORotation(CreateLookAtQuaternion(oPosition_, newat, up)); + } + + template + void Transform::RotateAxis(const Vector3 & axis, float angle) + { + oRotation_ *= CreateAxisQuaternion(axis, angle); + oRotation_.Normalize(); + UpdateTransform(); + } + + template + inline void Transform::RotateAbsX(T angle) + { + RotateAxis(Vector3(1.0f, 0.0f, 0.0f), angle); + } + + template + inline void Transform::RotateAbsY(T angle) + { + RotateAxis(Vector3(0.0f, 1.0f, 0.0f), angle); + } + + template + inline void Transform::RotateAbsZ(T angle) + { + RotateAxis(Vector3(0.0f, 0.0f, 1.0f), angle); + } + + template + inline void Transform::MoveAbs(const Vector3 & pos) + { + oPosition_ += pos; + UpdateTransform(); + } + + template + inline void Transform::MoveRel(const Vector3 & pos) + { + oPosition_ += GetObjectX() * pos.x + GetObjectY() * pos.y + + GetObjectZ() * pos.z; + UpdateTransform(); + } + + template + inline const Vector3 Transform::GetWorldX(void) const + { + T len = vMatrix_.c1.Length(); + if(len > std::numeric_limits::epsilon()) + return vMatrix_.c1 / len; + else + return vMatrix_.c1; + } + + template + inline const Vector3 Transform::GetWorldY(void) const + { + T len = vMatrix_.c2.Length(); + if(len > std::numeric_limits::epsilon()) + return vMatrix_.c2 / len; + else + return vMatrix_.c2; + } + + template + inline const Vector3 Transform::GetWorldZ(void) const + { + T len = vMatrix_.c3.Length(); + if(len > std::numeric_limits::epsilon()) + return vMatrix_.c3 / len; + else + return vMatrix_.c3; + } + + template + const Matrix4x4 Transform::GetOTransform(void) const + { + Matrix4x4 tmpm(CreateTMatrix(oPosition_)); + + if(!hasScale_) { + return tmpm * vMatrix_; + } else { + tmpm = tmpm * vMatrix_; + return tmpm * CreateSMatrix(oScale_); + } + } + + template + const Matrix4x4 Transform::GetInverseWTransform(void) const + { + if(wParent_) { + return GetInverseOTransform() * wParent_->GetInverseWTransform(); + } else { + return GetInverseOTransform(); + } + } + + template + const Matrix4x4 Transform::GetInverseOTransform(void) const + { + if(hasScale_) + return CreateInvSMatrix(oScale_) * CreateRMatrix(oRotation_.Conjugate()) + * CreateInvTMatrix(oPosition_); + else + return CreateRMatrix(oRotation_.Conjugate()) + * CreateInvTMatrix(oPosition_); + } + + template + inline void Transform::SetWParent(const Transform * parent) + { + wParent_ = parent; + UpdateTransform(); + } + + template + inline void Transform::SetOPosition(const Vector3 & pos) + { + oPosition_ = pos; + UpdateTransform(); + } + + template + void Transform::SetOScale(const Vector3 & scale) + { + if(scale.x != 0.0f && scale.y != 0.0f && scale.z != 0.0f) { + hasScale_ = true; + oScale_ = scale; + UpdateTransform(); + } + } + + template + inline void Transform::SetORotation(const Quaternion & rot) + { + oRotation_ = rot; + UpdateTransform(); + } + + template + inline void Transform::ResetOPosition(void) + { + oPosition_ = 0.0f; + UpdateTransform(); + } + + template + inline void Transform::ResetOScale(void) + { + hasScale_ = wParent_ ? wParent_->hasScale_ : false; + oScale_ = 1.0f; + UpdateTransform(); + } + + template + inline void Transform::ResetORotation(void) + { + oRotation_.Identity(); + UpdateTransform(); + } + + template + inline void Transform::UpdateTransform(void) + { + vMatrix_ = Matrix3x3::CreateRMatrix(oRotation_); + wTransform_ = Matrix4x4::CreateTMatrix(oPosition_) * vMatrix_; + + if(hasScale_) + wTransform_ = wTransform_ * Matrix3x3::CreateSMatrix(oScale_); + + if(wParent_) + wTransform_ = wParent_->GetWTransform() * wTransform_; + } + +} diff --git a/include/math/vector.h b/include/math/vector.h new file mode 100644 index 0000000..6478fe7 --- /dev/null +++ b/include/math/vector.h @@ -0,0 +1,954 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file vector.h + * + * Contains all relevant math related classes. + */ + +#pragma once + +#include +#include + +#include "assertion.h" + +namespace tre { + + /* + * Helper functions + */ + + /** Encodes normal float into char */ + template + inline char Real2Char(T a) {return static_cast((a) * 127.0f);} + + /** Decodes normal float from char */ + template + inline T Char2Real(char a) {return (a) / 127.0f;} + + /* + * Declarations of all classes + */ + + class VectorNorm2; + class VectorNorm3; + + template class Vector2; + template class Vector3; + template class Vector4; + + template class Matrix2x2; + template class Matrix3x3; + template class Matrix4x4; + + template class Quaternion; + + template class Line2; + template class Line3; + template class Plane; + + /* + * Convenience typedefs + */ + typedef Vector2 Vector2f; + typedef Vector3 Vector3f; + typedef Vector4 Vector4f; + typedef Vector2 Vector2d; + typedef Vector3 Vector3d; + typedef Vector4 Vector4d; + typedef Vector2 Vector2i; + typedef Vector3 Vector3i; + typedef Vector4 Vector4i; + typedef Vector2 Vector2u; + typedef Vector3 Vector3u; + typedef Vector4 Vector4u; + + /* + * Declarations of utility functions + */ + + template T Dot(const Vector2 & v1, const Vector2 & v2); + template T Dot(const Vector3 & v1, const Vector3 & v2); + template T Dot(const Vector4 & v1, const Vector4 & v2); + + template T Distance + (const Vector2 & v1, const Vector2 & v2); + template T Distance + (const Vector3 & v1, const Vector3 & v2); + + /* + * Normal vector classes + */ + + class VectorNorm2 { + public: + char x, y; + + public: + template VectorNorm2 & operator = (const Vector2 & v); + template VectorNorm2 & operator = (const Vector3 & v); + VectorNorm2 & operator = (char i); + template VectorNorm2 & operator = (T f); + + void Set(char cX, char cY); + template void Set(T fX, T fY); + }; + + class VectorNorm3 { + public: + char x, y, z; + + public: + template VectorNorm3 & operator = (const Vector3 & v); + VectorNorm3 & operator = (char i); + template VectorNorm3 & operator = (T f); + + void Set(char cX, char cY, char cZ); + }; + + /* + * Common vector classes + */ + + template + class Vector2 { + public: + T x, y; + + public: + Vector2() {} + Vector2(const VectorNorm2 & v) + : x(Char2Real(v.x)), y(Char2Real(v.y)) {} + Vector2(const Vector2 & v) : x(v.x), y(v.y) {} + explicit Vector2(T f) : x(f), y(f) {} + explicit Vector2(const Vector3 & v) : x(v.x), y(v.y) {} + Vector2(T fX, T fY) : x(fX), y(fY) {} + + const Vector2 operator + (const Vector2 & v) const; + const Vector2 operator + (T f) const; + const Vector2 operator - (const Vector2 & v) const; + const Vector2 operator - (T f) const; + const Vector2 operator * (T f) const; + const Vector2 operator / (T f) const; + + const Vector2 operator - () const; + + Vector2 & operator += (const Vector2 & v); + Vector2 & operator -= (const Vector2 & v); + Vector2 & operator *= (T f); + Vector2 & operator /= (T f); + + bool operator == (const Vector2 & v) const; + bool operator != (const Vector2 & v) const; + + Vector2 & operator = (T f); + Vector2 & operator = (const VectorNorm2 & v); + Vector2 & operator = (const Vector2 & v); + + T & operator [] (unsigned i); + const T & operator [] (unsigned i) const; + + void Set(T fX, T fY); + + T Length(void) const; + T LengthSquared(void) const; + void Normalize(void); + }; + + template + class Vector3 { + public: + T x, y, z; + + public: + Vector3() {} + explicit Vector3(const Vector2 & v) : x(v.x), y(v.y), z(0.0f) {} + Vector3(const Vector3 & v) : x(v.x), y(v.y), z(v.z) {} + explicit Vector3(const Vector4 & v); + explicit Vector3(float f) : x(f), y(f), z(f) {} + Vector3(float fX,float fY,float fZ) + : x(fX), y(fY), z(fZ) {} + + const Vector3 operator + (const Vector3 & v) const; + const Vector3 operator + (T f) const; + const Vector3 operator - (const Vector3 & v) const; + const Vector3 operator - (T f) const; + const Vector3 operator * (T f) const; + const Vector3 operator / (T f) const; + + const Vector3 operator - () const; + + Vector3 & operator += (const Vector3 & v); + Vector3 & operator -= (const Vector3 & v); + Vector3 & operator *= (T f); + Vector3 & operator /= (T f); + + bool operator == (const Vector3 & v) const; + bool operator == (T f) const; + bool operator != (const Vector3 & v) const; + bool operator != (T f) const; + + Vector3 & operator = (T f); + Vector3 & operator = (const VectorNorm3 & v); + Vector3 & operator = (const VectorNorm2 & v); + Vector3 & operator = (const Vector4 & v); + Vector3 & operator = (const Vector3 & v); + Vector3 & operator = (const Vector2 & v); + + T & operator [] (unsigned i); + const T & operator [] (unsigned i) const; + + void Set(T fX, T fY, T fZ); + + T Length(void) const; + T LengthSquared(void) const; + void Normalize(void); + + const Vector3 Cross(const Vector3 & v) const; + void Cross(const Vector3 & v1, const Vector3 & v2); + }; + + template + class Vector4 { + public: + T x, y, z, w; + + public: + Vector4() {} + + // assigning homogenous coordinates? + explicit Vector4(T f, T fW = 1.0f) + : x(f), y(f), z(f), w(fW) {} + explicit Vector4(const Vector2 & v, T fW = 1.0f) + : x(v.x), y(v.y), z(0.0f), w(fW) {} + explicit Vector4(const Vector3 & v, T fW = 1.0f) + : x(v.x), y(v.y), z(v.z), w(fW) {} + Vector4(const Vector4 & v) : x(v.x), y(v.y), z(v.z), w(v.w) {} + Vector4(T fX, T fY, T fZ, T fW = 1.0f) : x(fX), y(fY), z(fZ), w(fW) {} + + const Vector4 operator + (const Vector4 & v) const; + const Vector4 operator - (const Vector4 & v) const; + const Vector4 operator * (T f) const; + const Vector4 operator / (T f) const; + + const Vector4 operator - () const; + + Vector4 & operator += (const Vector4 & v); + Vector4 & operator -= (const Vector4 & v); + Vector4 & operator *= (T f); + Vector4 & operator /= (T f); + + bool operator == (const Vector4 & v) const; + bool operator != (const Vector4 & v) const; + + Vector4 & operator = (T f); + Vector4 & operator = (const VectorNorm3 & v); + Vector4 & operator = (const VectorNorm2 & v); + Vector4 & operator = (const Vector4 & v); + Vector4 & operator = (const Vector3 & v); + Vector4 & operator = (const Vector2 & v); + + T & operator [] (unsigned i); + const T & operator [] (unsigned i) const; + + void Set(T fX, T fY, T fZ, T fW); + + T Length(void) const; + }; + + /* + * Inline methods + */ + + template + inline VectorNorm2 & VectorNorm2::operator = (const Vector2 & v) + { + x = Real2Char(v.x); + y = Real2Char(v.y); + return *this; + } + + template + inline VectorNorm2 & VectorNorm2::operator = (const Vector3 & v) + { + x = Real2Char(v.x); + y = Real2Char(v.y); + return *this; + } + + inline VectorNorm2 & VectorNorm2::operator = (char i) + { + x = y = i; + return *this; + } + + template + inline VectorNorm2 & VectorNorm2::operator = (T f) + { + x = y = Real2Char(f); + return *this; + } + + inline void VectorNorm2::Set(const char cX, const char cY) + { + x = cX; + y = cY; + } + + template + inline void VectorNorm2::Set(T fX, T fY) + { + x = Real2Char(fX); + y = Real2Char(fY); + } + + template + inline VectorNorm3 & VectorNorm3::operator = (const Vector3 & v) + { + x = Real2Char(v.x); + y = Real2Char(v.y); + z = Real2Char(v.z); + return *this; + } + + inline VectorNorm3 & VectorNorm3::operator = (const char i) + { + x = y = i; + return *this; + } + + template + inline VectorNorm3 & VectorNorm3::operator = (T f) + { + x = y = Real2Char(f); + return *this; + } + + inline void VectorNorm3::Set(const char cX, const char cY, const char cZ) + { + x = cX; + y = cY; + z = cZ; + } + + template + inline const Vector2 Vector2::operator + (const Vector2 & v) const + { + return Vector2(x + v.x, y + v.y); + } + + template + inline const Vector2 Vector2::operator + (T f) const + { + return Vector2(x + f, y + f); + } + + template + inline const Vector2 Vector2::operator - (const Vector2 & v) const + { + return Vector2(x - v.x, y - v.y); + } + + template + inline const Vector2 Vector2::operator - (T f) const + { + return Vector2(x - f, y - f); + } + + template + inline const Vector2 Vector2::operator * (T f) const + { + return Vector2(x * f, y * f); + } + + template + inline const Vector2 Vector2::operator / (T f) const + { + return Vector2(x / f, y / f); + } + + template + inline const Vector2 Vector2::operator - () const + { + return Vector2(-x, -y); + } + + template + inline Vector2 & Vector2::operator += (const Vector2 & v) + { + x += v.x; + y += v.y; + return *this; + } + + template + inline Vector2 & Vector2::operator -= (const Vector2 & v) + { + x -= v.x; + y -= v.y; + return *this; + } + + template + inline Vector2 & Vector2::operator *= (T f) + { + x *= f; + y *= f; + return *this; + } + + template + inline Vector2 & Vector2::operator /= (T f) + { + x /= f; + y /= f; + return *this; + } + + template + inline bool Vector2::operator == (const Vector2 & v) const + { + return (x == v.x) && (y == v.y); + } + + template + inline bool Vector2::operator != (const Vector2 & v) const + { + return (x != v.x) || (y != v.y); + } + + template + inline Vector2 & Vector2::operator = (T f) + { + x = y = f; + return *this; + } + + template + inline Vector2 & Vector2::operator = (const VectorNorm2 & v) + { + x = Char2Real(v.x); + y = Char2Real(v.y); + return *this; + } + + template + inline Vector2 & Vector2::operator = (const Vector2 & v) + { + x = v.x; + y = v.y; + return *this; + } + + template + inline T & Vector2::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 2); + return *(&x + i); + } + + template + inline const T & Vector2::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 2); + return *(&x + i); + } + + template + inline void Vector2::Set(T fX, T fY) + { + x = fX; + y = fY; + } + + template <> + inline float Vector2::Length(void) const + { + return sqrtf(x*x + y*y); + } + + template <> + inline double Vector2::Length(void) const + { + return sqrt(x*x + y*y); + } + + template + inline T Vector2::LengthSquared(void) const + { + return x*x + y*y; + } + + template + inline void Vector2::Normalize(void) + { + T len = Length(); + + if(len > std::numeric_limits::epsilon()) + *this /= len; + } + + template + inline Vector3::Vector3(const Vector4 & v) + : x(v.x), y(v.y), z(v.z) + { + } + + template + inline const Vector3 Vector3::operator + (const Vector3 & v) const + { + return Vector3(x + v.x, y + v.y, z + v.z); + } + + template + inline const Vector3 Vector3::operator + (T f) const + { + return Vector3(x + f, y + f, z + f); + } + + template + inline const Vector3 Vector3::operator - (const Vector3 & v) const + { + return Vector3(x - v.x, y - v.y, z - v.z); + } + + template + inline const Vector3 Vector3::operator - (T f) const + { + return Vector3(x - f, y - f, z - f); + } + + template + inline const Vector3 Vector3::operator * (T f) const + { + return Vector3(x * f, y * f, z * f); + } + + template + inline const Vector3 Vector3::operator / (T f) const + { + return Vector3(x / f, y / f, z / f); + } + + template + inline const Vector3 Vector3::operator - () const + { + return Vector3(-x, -y, -z); + } + + template + inline Vector3 & Vector3::operator += (const Vector3 & v) + { + x += v.x; + y += v.y; + z += v.z; + return *this; + } + + template + inline Vector3 & Vector3::operator -= (const Vector3 & v) + { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } + + template + inline Vector3 & Vector3::operator *= (T f) + { + x *= f; + y *= f; + z *= f; + return *this; + } + + template + inline Vector3 & Vector3::operator /= (T f) + { + x /= f; + y /= f; + z /= f; + return *this; + } + + template + inline bool Vector3::operator == (const Vector3 & v) const + { + return ((x == v.x) && (y == v.y) && (z == v.z)); + } + + template + inline bool Vector3::operator == (T f) const + { + return ((x == f) && (y == f) && (z == f)); + } + + template + inline bool Vector3::operator != (const Vector3 & v) const + { + return ((x != v.x) || (y != v.y) || (z != v.z)); + } + + template + inline bool Vector3::operator != (T f) const + { + return ((x != f) || (y != f) || (z != f)); + } + + template + inline Vector3 & Vector3::operator = (T f) + { + x = y = z = f; + return *this; + } + + template + inline Vector3 & Vector3::operator = (const VectorNorm3 & v) + { + x = Char2Real(v.x); + y = Char2Real(v.y); + z = Char2Real(v.z); + return *this; + } + + template + inline Vector3 & Vector3::operator = (const VectorNorm2 & v) + { + x = Char2Real(v.x); + y = Char2Real(v.y); + z = 0.0f; + return *this; + } + + template + inline Vector3 & Vector3::operator = (const Vector4 & v) + { + x = v.x; + y = v.y; + z = v.z; + return *this; + } + + template + inline Vector3 & Vector3::operator = (const Vector3 & v) + { + x = v.x; + y = v.y; + z = v.z; + return *this; + } + + template + inline Vector3 & Vector3::operator = (const Vector2 & v) + { + x = v.x; + y = v.y; + z = 0.0f; + return *this; + } + + template + inline T & Vector3::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 3); + return *(&x + i); + } + + template + inline const T & Vector3::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 3); + return *(&x + i); + } + + template + inline void Vector3::Set(T fX, T fY, T fZ) + { + x = fX; + y = fY; + z = fZ; + } + + template <> + inline float Vector3::Length(void) const + { + return sqrtf(x*x + y*y + z*z); + } + + template <> + inline double Vector3::Length(void) const + { + return sqrt(x*x + y*y + z*z); + } + + template + inline T Vector3::LengthSquared(void) const + { + return x*x + y*y + z*z; + } + + template + inline void Vector3::Normalize(void) + { + T len = Length(); + + if(len > std::numeric_limits::epsilon()) + *this /= len; + } + + template + inline const Vector3 Vector3::Cross(const Vector3 & v) const + { + return Vector3(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); + } + + template + inline void Vector3::Cross + (const Vector3 & v1, const Vector3 & v2) + { + x = v1.y * v2.z - v1.z * v2.y; + y = v1.z * v2.x - v1.x * v2.z; + z = v1.x * v2.y - v1.y * v2.x; + } + + template + inline const Vector4 Vector4::operator + (const Vector4 & v) const + { + return Vector4(x + v.x, y + v.y, z + v.z, w + v.w); + } + + template + inline const Vector4 Vector4::operator - (const Vector4 & v) const + { + return Vector4(x - v.x, y - v.y, z - v.z, w - v.w); + } + + template + inline const Vector4 Vector4::operator * (T f) const + { + return Vector4(x * f, y * f, z * f, w * f); + } + + template + inline const Vector4 Vector4::operator / (T f) const + { + return Vector4(x / f, y / f, z / f, w / f); + } + + template + inline const Vector4 Vector4::operator - () const + { + return Vector4(-x, -y, -z, -w); + } + + template + inline Vector4 & Vector4::operator += (const Vector4 & v) + { + x += v.x; + y += v.y; + z += v.z; + w += v.w; + return *this; + } + + template + inline Vector4 & Vector4::operator -= (const Vector4 & v) + { + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + return *this; + } + + template + inline Vector4 & Vector4::operator *= (T f) + { + x *= f; + y *= f; + z *= f; + w *= f; + return *this; + } + + template + inline Vector4 & Vector4::operator /= (T f) + { + x /= f; + y /= f; + z /= f; + w /= f; + return *this; + } + + template + inline bool Vector4::operator == (const Vector4 & v) const + { + return ((x == v.x) && (y == v.y) && (z == v.z) && (w == v.w)); + } + + template + inline bool Vector4::operator != (const Vector4 & v) const + { + return ((x != v.x) || (y != v.y) || (z != v.z) || (w != v.w)); + } + + template + inline Vector4 & Vector4::operator = (T f) + { + x = y = z = w = f; + return *this; + } + + template + inline Vector4 & Vector4::operator = (const VectorNorm3 & v) + { + x = Char2Real(v.x); + y = Char2Real(v.y); + z = Char2Real(v.z); + w = 1.0f; + return *this; + } + + template + inline Vector4 & Vector4::operator = (const VectorNorm2 & v) + { + x = Char2Real(v.x); + y = Char2Real(v.y); + z = 0.0f; + w = 1.0f; + return *this; + } + + template + inline Vector4 & Vector4::operator = (const Vector4 & v) + { + x = v.x; + y = v.y; + z = v.z; + w = v.w; + return *this; + } + + template + inline Vector4 & Vector4::operator = (const Vector3 & v) + { + x = v.x; + y = v.y; + z = v.z; + w = 1.0f; + return *this; + } + + template + inline Vector4 & Vector4::operator = (const Vector2 & v) + { + x = v.x; + y = v.y; + z = 0.0f; + w = 1.0f; + return *this; + } + + template + inline T & Vector4::operator [] (unsigned i) + { + DEBUG_ASSERT(i < 4); + return *(&x + i); + } + + template + inline const T & Vector4::operator [] (unsigned i) const + { + DEBUG_ASSERT(i < 4); + return *(&x + i); + } + + template + inline void Vector4::Set(T fX, T fY, T fZ, T fW) + { + x = fX; + y = fY; + z = fZ; + w = fW; + } + + template <> + inline float Vector4::Length(void) const + { + return sqrtf(x*x + y*y + z*z + w*w); + } + + template <> + inline double Vector4::Length(void) const + { + return sqrt(x*x + y*y + z*z + w*w); + } + + /* + * Utility functions + */ + + template + inline T Dot(const Vector2 & v1, const Vector2 & v2) + { + return v1.x*v2.x + v1.y*v2.y; + } + + template + inline T Dot(const Vector3 & v1, const Vector3 & v2) + { + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; + } + + template + inline T Dot(const Vector4 & v1, const Vector4 & v2) + { + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w; + } + + template <> + inline float Distance(const Vector2f & v1, const Vector2f & v2) + { + return sqrtf((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y)); + } + + template <> + inline double Distance(const Vector2d & v1, const Vector2d & v2) + { + return sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y)); + } + + template <> + inline float Distance(const Vector3f & v1, const Vector3f & v2) + { + return sqrtf((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + + (v1.z - v2.z) * (v1.z - v2.z)); + } + + template <> + inline double Distance(const Vector3d & v1, const Vector3d & v2) + { + return sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + + (v1.z - v2.z) * (v1.z - v2.z)); + } + +} diff --git a/include/math/volumes.h b/include/math/volumes.h new file mode 100644 index 0000000..af33b91 --- /dev/null +++ b/include/math/volumes.h @@ -0,0 +1,268 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file volumes.h + * + * Huhu + */ + +#pragma once + +#include "stdtypes.h" + +#include "math/math.h" +#include "math/vector.h" + +#include "transform.h" + +namespace tre { + + class BndVolume; + class BndSphere; + class AABBox; + class OBBox; + class PVolume; + + enum ProjectionType { + ptPerspective, + ptOrtho + }; + + struct ProjectionBase { + float left; + float right; + float bottom; + float top; + float near; + float far; + }; + + float Distance(const BndVolume & bv1, const BndVolume & bv2); + + // every bounding volume instance is also a bounding sphere + class BndVolume { + public: + Vector3f center; + float radius; + + public: + BndVolume() {} + BndVolume(const Vector3f & c, float r) : center(c), radius(r) {} + virtual ~BndVolume() {} + + // creation + virtual void CreateFromData(const Float3Vector & data) = 0; + + // transformation + virtual void SetTransform(const Transformf & t) = 0; + virtual void ResetTransform(void) = 0; + + // boundig sphere tests + bool SphereCollision(const BndVolume & bvol) const; + bool SphereCollision(const Vector3f & v) const; + int SphereIntersection(const BndVolume & bvol) const; + + // true/false collision testing + virtual bool TestCollision(const BndVolume & bvol) const = 0; + + virtual bool TestCollision(const Vector3f & v) const; + virtual bool TestCollision(const BndSphere & bsp) const; + virtual bool TestCollision(const AABBox & bbox) const; + virtual bool TestCollision(const OBBox & bbox) const; + virtual bool TestCollision(const PVolume & pvol) const; + + // more thorough testing + virtual int TestIntersection(const BndVolume & bvol) const = 0; + + virtual int TestIntersection(const BndSphere & bsp) const; + virtual int TestIntersection(const AABBox & bbox) const; + virtual int TestIntersection(const OBBox & bbox) const; + virtual int TestIntersection(const PVolume & pvol) const; + }; + + class BndSphere : public BndVolume { + public: + BndSphere() {} + BndSphere(const Vector3f & c, float r) + : BndVolume(c, r), baseCenter_(c), baseRadius_(r) {} + + void CreateFromData(const Float3Vector & data); + + void SetTransform(const Transformf & t); + void ResetTransform(void); + + // true/false collision testing + bool TestCollision(const BndVolume & bvol) const; + bool TestCollision(const AABBox & bbox) const; + bool TestCollision(const OBBox & bbox) const; + bool TestCollision(const PVolume & pvol) const; + + // more thorough testing + int TestIntersection(const BndVolume & bvol) const; + int TestIntersection(const AABBox & bbox) const; + int TestIntersection(const OBBox & bbox) const; + int TestIntersection(const PVolume & pvol) const; + + void Set(const Vector3f & c, float r); + + private: + Vector3f baseCenter_; + float baseRadius_; + }; + + // axis aligned box + class AABBox : public BndVolume { + public: + Vector3f halfSize; + + public: + AABBox() {} + AABBox(const Vector3f & c, const Vector3f & hs) + : BndVolume(c, hs.Length()), halfSize(hs), + baseCenter_(c), baseHSize_(hs) {} + + void CreateFromData(const Float3Vector & data); + + void SetTransform(const Transformf & t); + void ResetTransform(void); + + int GetQuadrant(const BndVolume & bvol) const; + + // true/false collision testing + bool TestCollision(const BndVolume & bvol) const; + bool TestCollision(const Vector3f & v) const; + bool TestCollision(const BndSphere & bsp) const; + bool TestCollision(const AABBox & bbox) const; + bool TestCollision(const OBBox & bbox) const; + bool TestCollision(const PVolume & pvol) const; + + // more thorough testing + int TestIntersection(const BndVolume & bvol) const; + int TestIntersection(const BndSphere & bsp) const; + int TestIntersection(const AABBox & bbox) const; + int TestIntersection(const OBBox & bbox) const; + int TestIntersection(const PVolume & pvol) const; + + void Set(const Vector3f & c, const Vector3f & hs); + + private: + Vector3f baseCenter_; + Vector3f baseHSize_; + }; + + // oriented bouding box + class OBBox : public BndVolume { + public: + Vector3f halfSize; + + // perpendicular to axes X, Y and Z + Planef centralPlanes[3]; + + public: + OBBox() {} + OBBox(const Vector3f & c, const Vector3f & hs, const Vector3f & d, + const Vector3f & u, const Vector3f & r); + + void CreateFromData(const Float3Vector & data); + + void SetTransform(const Transformf & t); + void ResetTransform(void); + + // true/false collision testing + bool TestCollision(const BndVolume & bvol) const; + bool TestCollision(const Vector3f & v) const; + bool TestCollision(const BndSphere & bsp) const; + bool TestCollision(const AABBox & bbox) const; + bool TestCollision(const OBBox & bbox) const; + bool TestCollision(const PVolume & pvol) const; + + // more thorough testing + int TestIntersection(const BndVolume & bvol) const; + int TestIntersection(const BndSphere & bsp) const; + int TestIntersection(const AABBox & bbox) const; + int TestIntersection(const OBBox & bbox) const; + int TestIntersection(const PVolume & pvol) const; + + void Set(const Vector3f & c, const Vector3f & hs, const Vector3f & d, + const Vector3f & r, const Vector3f & u); + + private: + Vector3f baseCenter_; + Vector3f baseHSize_; + + Vector3f baseDir_; + Vector3f baseUp_; + Vector3f baseRight_; + }; + + // frustum or box, depending on the projection type + class PVolume : public BndVolume { + public: + // left, right, bottom, top, near, far + // normals pointing inwards + Planef clipPlane[6]; +// Vector3f corner[8]; + + public: + PVolume(); + + const Vector3f & GetEye(void) const {return eye_;} + const Vector3f & GetDir(void) const {return dir_;} + const Vector3f & GetRight(void) const {return right_;} + const Vector3f & GetUp(void) const {return up_;} + + void CreateFromData(const Float3Vector & data) {} + + void SetTransform(const Transformf & t); + void ResetTransform(void); + + // true/false collision testing + bool TestCollision(const BndVolume & bvol) const; + bool TestCollision(const Vector3f & v) const; + bool TestCollision(const BndSphere & bsp) const; + bool TestCollision(const AABBox & bbox) const; + bool TestCollision(const OBBox & bbox) const; + + // more thorough testing + int TestIntersection(const BndVolume & bvol) const; + int TestIntersection(const BndSphere & bsp) const; + int TestIntersection(const AABBox & bbox) const; + int TestIntersection(const OBBox & bbox) const; + + ProjectionType GetProjectionType(void) const {return type_;} + const ProjectionBase & GetProjection(void) const {return proj_;} + + void SetPerspective(float fov, float asp, float near, float far); + void SetOrtho(float left, float right, float bottom, + float top, float near, float far); + + private: + ProjectionType type_; + ProjectionBase proj_; + + Vector3f eye_; + Vector3f dir_; + Vector3f right_; + Vector3f up_; + + private: + void UpdatePerspective(void); + void UpdateOrtho(void); + }; +} diff --git a/include/mem_off.h b/include/mem_off.h new file mode 100644 index 0000000..798e605 --- /dev/null +++ b/include/mem_off.h @@ -0,0 +1,62 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +// ---------------------------------------------------------------------------- +// Originally created on 12/22/2000 by Paul Nettle +// +// Copyright 2000, Fluid Studios, Inc., all rights reserved. +// +// For more information, visit HTTP://www.FluidStudios.com +// ---------------------------------------------------------------------------- + +/** + * @file mem_off.h + * + * Contains macros for disabling the overriden new/delete macros. + */ + +// defines MEM_MANAGER_ON macro +#include "config.h" + +#ifdef MEM_MANAGER_ON + +#ifdef new +# undef new +#endif + +#ifdef delete +# undef delete +#endif + +#ifdef malloc +# undef malloc +#endif + +#ifdef calloc +# undef calloc +#endif + +#ifdef realloc +# undef realloc +#endif + +#ifdef free +# undef free +#endif + +#endif /* MEM_MANAGER_ON */ diff --git a/include/mem_on.h b/include/mem_on.h new file mode 100644 index 0000000..c07376f --- /dev/null +++ b/include/mem_on.h @@ -0,0 +1,50 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +// ---------------------------------------------------------------------------- +// Originally created on 12/22/2000 by Paul Nettle +// +// Copyright 2000, Fluid Studios, Inc., all rights reserved. +// +// For more information, visit HTTP://www.FluidStudios.com +// ---------------------------------------------------------------------------- + +/** + * @file mem_on.h + * + * Contains macros overriding the standard new/delete operators. + */ + +// defines MEM_MANAGER_ON macro +#include "config.h" + +#ifdef MEM_MANAGER_ON + +#define new (tre::SetOwner(__FILE__,__LINE__,__FUNCTION__),false) ? NULL : new +#define delete (tre::SetOwner(__FILE__,__LINE__,__FUNCTION__),false) ? \ + tre::SetOwner("",0,"") : delete +#define malloc(sz) tre::Allocator(__FILE__,__LINE__,\ + __FUNCTION__,tre::atMalloc,sz) +#define calloc(sz) tre::Allocator(__FILE__,__LINE__,\ + __FUNCTION__,tre::atCalloc,sz) +#define realloc(ptr,sz) tre::Reallocator(__FILE__,__LINE__,\ + __FUNCTION__,tre::atRealloc,sz,ptr) +#define free(ptr) tre::Deallocator(__FILE__,__LINE__,\ + __FUNCTION__,tre::atFree,ptr) + +#endif /* MEM_MANAGER_ON */ diff --git a/include/memory/init_mmgr.cpp b/include/memory/init_mmgr.cpp new file mode 100644 index 0000000..eaf2f04 --- /dev/null +++ b/include/memory/init_mmgr.cpp @@ -0,0 +1,55 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file init_mmgr.cpp + * + * This file should be *included* to unit defining static global objects. + * Logger should be initialized prior to memory manager. + */ + +#include "config.h" + +#ifdef MEM_MANAGER_ON + +#ifndef BUILD_NAME +# error BUILD_NAME not defined! +#endif /* BUILD_NAME */ + +namespace tre { + bool InitializeMemoryManager(const char * buildName); +} + +namespace { + + /** + * @class MemInit + * + * Used for initialization of memory manager. + */ + class MemInit { + public: + MemInit() {tre::InitializeMemoryManager(BUILD_NAME);} + }; + + /** Memory manager object */ + MemInit sMemInit; + +} + +#endif /* MEM_MANAGER_ON */ diff --git a/include/memory/mmgr.h b/include/memory/mmgr.h new file mode 100644 index 0000000..b69220e --- /dev/null +++ b/include/memory/mmgr.h @@ -0,0 +1,149 @@ +// +// Copyright (C) 2007 by Martin Moracek +// Portions Copyright (C) 2001 by Peter Dalton +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +// ---------------------------------------------------------------------------- +// Originally created on 12/22/2000 by Paul Nettle +// +// Copyright 2000, Fluid Studios, Inc., all rights reserved. +// +// For more information, visit HTTP://www.FluidStudios.com +// ---------------------------------------------------------------------------- + +/** + * @file mmgr.h + * + * Contains declarations of exported memory management routines. + * + * This file exposes control routines for modifying memory manager's + * behaviour and creating log reports. + */ + +#pragma once + +// defines MEM_MANAGER_ON macro +#include "config.h" + +#ifdef MEM_MANAGER_ON + +#include + +#include +#include + +namespace tre { + + struct MemStats { + unsigned totalReportedMemory; + unsigned totalActualMemory; + unsigned peakReportedMemory; + unsigned peakActualMemory; + unsigned accumReportedMemory; + unsigned accumActualMemory; + unsigned accumAllocUnitCount; + unsigned totalAllocUnitCount; + unsigned peakAllocUnitCount; + }; + + /* + * Constants + */ + /// Posible allocation/deallocation types. + typedef unsigned char AllocType; + + const AllocType atUnknown = 0; /// Unknown allocation. + const AllocType atNew = 1; /// new + const AllocType atNewArray = 2; /// new [] + + // C library functions + const AllocType atMalloc = 3; /// malloc() + const AllocType atCalloc = 4; /// calloc() + const AllocType atRealloc = 5; /// realloc() + + // deallocations + const AllocType atDelete = 6; /// delete + const AllocType atDeleteArray = 7; /// delete [] + const AllocType atFree = 8; /// free() + + /* + * Init functions + */ + bool InitializeMemoryManager(const char * buildName); + void ReleaseMemoryManager(void); + + /* + * Used by macros + */ + void SetOwner(const char * file, unsigned line, const char * func); + + /* + * Control functions + */ + void SetAlwaysValidateAll(bool st); + void SetAlwaysLogAll(bool st); + void SetAlwaysWipeAll(bool st); + void SetRandomWipe(bool st); + void SetBreakOnRealloc(void * address, bool st); + void SetBreakOnDealloc(void * address, bool st); + void SetBreakOnAllocation(unsigned int count); + + /* + * The meat of the memory tracking software + */ + void * Allocator(const char * file, unsigned line, + const char * func, AllocType type, size_t size); + void * Reallocator(const char * file, unsigned line, + const char * func, AllocType type, size_t size, void * address); + void Deallocator(const char * file, unsigned line, + const char * func, AllocType type, const void * address); + + /* + * Utilitarian functions + */ + bool ValidateAddress(const void * address); + bool ValidateAllAllocUnits(void); + + /* + * Unused RAM calculations + */ + unsigned CalcAllUnused(void); + + /* + * Logging and reporting + */ + void DumpLogReport(std::ostream & out); + MemStats GetMemoryStatistics(void); +} + +/* + * Variants of overloaded new & delete operators + */ + +void * operator new(size_t size) throw(std::bad_alloc); +void * operator new[](size_t size) throw(std::bad_alloc); +void * operator new(size_t size, const char * file, int line) + throw(std::bad_alloc); +void * operator new[](size_t size, const char * file, int line) + throw(std::bad_alloc); + +void operator delete(void * address) throw(); +void operator delete[](void * address) throw(); + +#include "mem_on.h" + +#endif /* MEM_MANAGER_ON */ diff --git a/include/old-mem_off.h b/include/old-mem_off.h new file mode 100644 index 0000000..3b81237 --- /dev/null +++ b/include/old-mem_off.h @@ -0,0 +1,38 @@ +// +// Copyright (C) 2007 by Martin Moracek +// Portions Copyright (C) 2001 by Peter Dalton +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/*! + * @file mem_off.h + * + * @brief Contains macros for disabling the overriden new/delete macros. + */ + +// defines MEM_MANAGER_ON +#include "config.h" + +#ifdef MEM_MANAGER_ON + +#undef new +#undef delete +#undef malloc +#undef calloc +#undef realloc +#undef free + +#endif /* MEM_MANAGER_ON */ diff --git a/include/old-mem_on.h b/include/old-mem_on.h new file mode 100644 index 0000000..4c53ce5 --- /dev/null +++ b/include/old-mem_on.h @@ -0,0 +1,38 @@ +// +// Copyright (C) 2007 by Martin Moracek +// Portions Copyright (C) 2001 by Peter Dalton +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/*! + * @file mem_on.h + * + * @brief Contains macros overring the standard new/delete operators. + */ + +// defines MEM_MANAGER_ON +#include "config.h" + +#ifdef MEM_MANAGER_ON + +#define new new(__FILE__,__LINE__) +#define delete mem::SetOwner(__FILE__,__LINE__),delete +#define malloc(sz) mem::AllocateMemory(__FILE__,__LINE__,sz,mem::mmMalloc) +#define calloc(num,sz) mem::AllocateMemory(__FILE__,__LINE__,sz*num,mem::mmCalloc) +#define realloc(ptr,sz) mem::AllocateMemory(__FILE__,__LINE__,sz,mem::mmRealloc,ptr) +#define free(sz) mem::SetOwner(__FILE__,__LINE__),mem::DeallocateMemory(sz,mem::mmFree) + +#endif /* MEM_MANAGER_ON */ diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 0000000..2803cbd --- /dev/null +++ b/include/platform.h @@ -0,0 +1,149 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file platform.h + * + * Header file for platform dependent macros and constants. + */ + +#pragma once + +/* + * Little/big endianism + */ + +#ifdef IS_BIG_ENDIAN + +# include "types.h" + +# if (IS_BIG_ENDIAN == 1) +# define PLATFORM_BIG_ENDIAN + +// platform conversion functions +inline uint16 ToLittleEndian(uint16 v) +{ + return (0x00FF & v) << 8 | + (0xFF00 & v) >> 8; +} + +inline uint32 ToLittleEndian(uint32 v) +{ + return (0x000000FF & v) << 24 | + (0x0000FF00 & v) << 8 | + (0x00FF0000 & v) >> 8 | + (0xFF000000 & v) >> 24; +} + +inline uint16 ToBigEndian(uint16 v) +{ + return v; +} + +inline uint32 ToBigEndian(uint32 v) +{ + return v; +} + +# else /* (IS_BIG_ENDIAN == 1) */ +# define PLATFORM_LITTLE_ENDIAN + +// platform conversion functions +inline uint16 ToLittleEndian(uint16 v) +{ + return v; +} + +inline uint32 ToLittleEndian(uint32 v) +{ + return v; +} + +inline uint16 ToBigEndian(uint16 v) +{ + return (0x00FF & v) << 8 | + (0xFF00 & v) >> 8; +} + +inline uint32 ToBigEndian(uint32 v) +{ + return (0x000000FF & v) << 24 | + (0x0000FF00 & v) << 8 | + (0x00FF0000 & v) >> 8 | + (0xFF000000 & v) >> 24; +} + +# endif /* (IS_BIG_ENDIAN == 1) */ +#endif /* IS_BIG_ENDIAN */ + +/* + * Platform/compiler detection + */ + +#ifdef _MSC_VER +# define PLATFORM_MSVC +#else +# ifdef __GNUC__ +# define PLATFORM_GCC +# ifdef linux +# define PLATFORM_GCC_LINUX +# else +# define PLATFORM_GCC_WIN +# endif /* linux */ +# else +# error Unknown compiler! +# endif /* __GNUC__ */ +#endif /* _MSC_VER */ + +#if defined(_DEBUG) && !defined(DEBUG) +# define DEBUG +#endif + +/* + * Platform dependent macros + */ +#ifdef PLATFORM_MSVC + +# define lseek _lseek +# define read _read +# define write _write + +# define snprintf _snprintf +# define strcasecmp _stricmp + + // to get clearer compiler output +# pragma warning( disable : 4290 ) +# pragma warning( disable : 4996 ) + +// conversion from 'x' to 'y', possible loss of data +# pragma warning( disable : 4244 ) + +# pragma warning( disable : 4345 ) + +#endif /* PLATFORM_MSVC */ + +#ifdef PLATFORM_GCC + +#define __FUNCTION__ __PRETTY_FUNCTION__ + +#endif /* PLATFORM_GCC */ + +/* + * Build name - for creating project dependent logfiles, etc. + */ +extern const char * gBuildName; diff --git a/include/renderer/buffers.h b/include/renderer/buffers.h new file mode 100644 index 0000000..cdad67d --- /dev/null +++ b/include/renderer/buffers.h @@ -0,0 +1,201 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file buffers.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "stdtypes.h" + +#include "math/vector.h" + +namespace tre { + + typedef uint AttribType; + const AttribType atPosition = 0; + const AttribType atBlendweight = 1; + const AttribType atNormal = 2; + const AttribType atDiffuse = 3; + const AttribType atColour = 3; + const AttribType atSpecular = 4; + const AttribType atSecondaryColour = 4; + const AttribType atTessFactor = 5; + const AttribType atFogCoords = 5; + const AttribType atPointSize = 6; + const AttribType atBlendIndices = 7; + const AttribType atTexCoord0 = 8; + const AttribType atTexCoord1 = 9; + const AttribType atTexCoord2 = 10; + const AttribType atTexCoord3 = 11; + const AttribType atTexCoord4 = 12; + const AttribType atTexCoord5 = 13; + const AttribType atTexCoord6 = 14; + const AttribType atlTexCoord7 = 15; + const AttribType atTangent = 14; + const AttribType atBitangent = 15; + const AttribType atGeneric0 = 0; + const AttribType atGeneric1 = 1; + const AttribType atGeneric2 = 2; + const AttribType atGeneric3 = 3; + const AttribType atGeneric4 = 4; + const AttribType atGeneric5 = 5; + const AttribType atGeneric6 = 6; + const AttribType atGeneric7 = 7; + const AttribType atGeneric8 = 8; + const AttribType atGeneric9 = 9; + const AttribType atGeneric10 = 10; + const AttribType atGeneric11 = 11; + const AttribType atGeneric12 = 12; + const AttribType atGeneric13 = 13; + const AttribType atGeneric14 = 14; + const AttribType atGeneric15 = 15; + + enum AttribDataType { + adFloat1 = 0, + adFloat2, + adFloat3, + adFloat4, + adUInt1, + adUInt2, + adUInt3, + adUInt4 + }; + + enum AccessMode { + amRead = 1, + amWrite, + amReadWrite + }; + + class AttribBufferSet; + class IndexBuffer; + + typedef boost::shared_ptr AttribBufPtr; + typedef boost::weak_ptr AttribBufRef; + typedef boost::shared_ptr IndexBufPtr; + typedef boost::weak_ptr IndexBufRef; + + class AttribBufferSetFactory { + public: + AttribBufferSet * CreateInstance(void); + }; + + class IndexBufferFactory { + public: + IndexBuffer * CreateInstance(void); + }; + + class AttribBufferSet : private boost::noncopyable { + public: + static AttribBufferSetFactory & Factory(void) + { + static AttribBufferSetFactory fac; + return fac; + } + + public: + AttribBufferSet() {} + virtual ~AttribBufferSet() {} + + // initialization & destruction + virtual void Init(AttribType loc, AttribDataType dat, + uint size, AccessMode mode=amRead) = 0; + virtual void Clear(AttribType loc) = 0; + + // memory mapping + virtual void * Lock(AttribType loc, AccessMode mode=amWrite, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void Unlock(AttribType loc) = 0; + + // Set automatically initializes (creates) buffer + virtual void Set(AttribType loc, const FloatVector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const Float2Vector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const Float3Vector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const Float4Vector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const UIntVector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const UInt2Vector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const UInt3Vector & data, + AccessMode mode=amRead) = 0; + virtual void Set(AttribType loc, const UInt4Vector & data, + AccessMode mode=amRead) = 0; + + virtual void UpdateRange(AttribType loc, const FloatVector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const Float2Vector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const Float3Vector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const Float4Vector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const UIntVector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const UInt2Vector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const UInt3Vector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + virtual void UpdateRange(AttribType loc, const UInt4Vector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + }; + + class IndexBuffer : private boost::noncopyable { + public: + static IndexBufferFactory & Factory(void) + { + static IndexBufferFactory fac; + return fac; + } + + public: + // index limits, might be used during rendering + uint vFrom; + uint vTo; + + public: + IndexBuffer() : vFrom(0), vTo(std::numeric_limits::max()) {} + virtual ~IndexBuffer() {} + + // initialization & destruction + virtual void Init(uint size, AccessMode mode=amRead) = 0; + virtual void Clear(void) = 0; + + // memory mapping + virtual uint * Lock(AccessMode mode=amWrite, uint offset=0, + uint size=std::numeric_limits::max()) = 0; + virtual void Unlock(void) = 0; + + // Set automatically initializes (creates) buffer + virtual void Set(const UIntVector & data, AccessMode mode=amRead) = 0; + virtual void UpdateRange(const UIntVector & data, + uint offset=0, uint size=std::numeric_limits::max()) = 0; + }; + +} diff --git a/include/renderer/canvas.h b/include/renderer/canvas.h new file mode 100644 index 0000000..00d18bb --- /dev/null +++ b/include/renderer/canvas.h @@ -0,0 +1,70 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file canvas.h + * + * Ble. + */ + +#pragma once + +#include "stdtypes.h" + +#include "texture.h" + +namespace tre { + + class Canvas; + + typedef boost::shared_ptr CanvasPtr; + typedef boost::weak_ptr CanvasRef; + + class CanvasFactory { + public: + CanvasPtr CreateInstance(void); + CanvasPtr CreateInstance(uint w, uint h); + }; + + class Canvas : private boost::noncopyable { + public: + static CanvasFactory & Factory(void) + { + static CanvasFactory fac; + return fac; + } + + public: + Vector4f bgColour; + + public: + Canvas(uint w, uint h) : bgColour(0.0f), width_(w), height_(h) {} + virtual ~Canvas() {} + + uint GetWidth(void) const {return width_;} + uint GetHeight(void) const {return height_;} + + TexturePtr GetTexture(void) {return texture_;} + + protected: + uint width_; + uint height_; + + TexturePtr texture_; + }; +} diff --git a/include/renderer/effect.h b/include/renderer/effect.h new file mode 100644 index 0000000..d158fa7 --- /dev/null +++ b/include/renderer/effect.h @@ -0,0 +1,134 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file effect.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include "types.h" +#include "cpair.h" +#include "renderer/texture.h" + +namespace tre { + + // data types for uniform variables + enum EffectVarType { + vtFloat1, + vtFloat2, + vtFloat3, + vtFloat4, + vtInt1, + vtInt2, + vtInt3, + vtInt4, + vtTexture + }; + + // builtins for all shader types + enum InternalsType { // Semantic, annotations... + itTime, // Time + itSysTime, // Time, type = "system" + // state matrices + itMVPMatrix, // ModelViewProjection + itMVPMatrixInv, // ModelViewProjection, inverse = true + itMVPMatrixTrans, // ModelViewProjection, transpose=true + itMVPMatrixInvTrans,// ModelViewProjection, inverse = true, transpose=true + itMVMatrix, // ModelView + itMVMatrixInv, // ModelView, inverse = true + itMVMatrixTrans, // ModelView, transpose=true + itMVMatrixInvTrans, // ModelView, transpose=true + itPMatrix, // Projection + itPMatrixInv, // Projection, inverse = true + itPMatrixTrans, // Projection, transpose=true + itPMatrixInvTrans, // Projection, transpose=true + itTMatrix, // Texture + itTMatrixInv, // Texture, inverse = true + itTMatrixTrans, // Texture, transpose=true + itTMatrixInvTrans, // Texture, transpose=true + // last entry + itLast + }; + + // variable declarations for general use + typedef boost::array FxFVar; + typedef boost::array FxIVar; + + typedef cpair FxFPair; + typedef cpair FxIPair; + typedef cpair FxSPair; + + typedef std::vector FVarVector; + typedef std::vector IVarVector; + typedef std::vector SVarVector; + + struct EffectVars { + FVarVector fvars; + IVarVector ivars; + SVarVector samplers; + + EffectVars(); + ~EffectVars(); + + void SetTexture(const std::string & name, const std::string & var); + void SetTexture(const std::string & name, const TexturePtr & var); + }; + + /* + * Effect class + */ + class Effect; + + typedef boost::shared_ptr EffectPtr; + typedef boost::weak_ptr EffectRef; + + class EffectFactory { + public: + const EffectPtr CreateInstance(const std::string & name); + + private: + typedef std::tr1::unordered_map EffectMap; + + private: + EffectMap map_; + }; + + class Effect : private boost::noncopyable { + public: + static EffectFactory & Factory(void) + { + static EffectFactory fac; + return fac; + } + + public: + virtual ~Effect() {} + }; + +} diff --git a/include/renderer/renderer.h b/include/renderer/renderer.h new file mode 100644 index 0000000..cb100a8 --- /dev/null +++ b/include/renderer/renderer.h @@ -0,0 +1,121 @@ +// +// Copyright (C) 2007-2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file renderer.h + * + * Encapsulates chosen renderer/display + */ + +#pragma once + +#include + +#include "types.h" +#include "math/matrix.h" +#include "core/client/display.h" + +namespace tre { + + class PVolume; + class AttribBufferSet; + class IndexBuffer; + class Canvas; + class Effect; + struct EffectVars; + + struct FrameStats { + uint triangles; + uint batches; // number of draw calls + + // visible lights + // fps + + + /* + -frame: + -triangles (unique vs. total) + -batches (unique vs. total) - draw calls + -visible lights + -fps + -seconds per frame + -global: + -total frames + -time spent rendering? + -average fps + -average triangles + -average batches + -average lights + */ + + uint time; + + uint count; // frame count + }; + + class GeometryInfo { + public: + const Matrix4x4f * trans; + const AttribBufferSet * attribs; + const IndexBuffer * indices; + const Effect * effect; + const EffectVars * fxVars; + + // bounding volume? + + public: + GeometryInfo(const Matrix4x4f & t, const AttribBufferSet * a, + const IndexBuffer * i, const Effect * e, const EffectVars & ev) + : trans(&t), attribs(a), indices(i), effect(e), fxVars(&ev) {} + + GeometryInfo(const Matrix4x4f * t, const AttribBufferSet * a, + const IndexBuffer * i, const Effect * e, const EffectVars * ev) + : trans(t), attribs(a), indices(i), effect(e), fxVars(ev) {} + }; + + typedef std::vector GeometryBatch; + + class Renderer { + public: + static bool CheckErrors(const char * msg=NULL, bool confirmOK=false); + + public: + FrameStats frame; + + public: + Renderer() {} + virtual ~Renderer() {} + + virtual void Init(void) = 0; + + virtual void NewFrame(void) = 0; + virtual void FlushFrame(void) = 0; + virtual void PresentFrame(void) = 0; + + virtual void SetCamera(const PVolume & cam) = 0; + virtual void SetCameraTransform(const Matrix4x4f * cnv) = 0; + + virtual void PushCanvas(const Canvas * cnv) = 0; + virtual void PopCanvas(void) = 0; + + virtual void DrawGeometry(const GeometryBatch::iterator & begin, + const GeometryBatch::iterator & end) = 0; + }; + + Renderer & sRenderer(void); +} diff --git a/include/renderer/texture.h b/include/renderer/texture.h new file mode 100644 index 0000000..04783b4 --- /dev/null +++ b/include/renderer/texture.h @@ -0,0 +1,125 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file texture.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include + +#include "stdtypes.h" +#include "math/vector.h" + +namespace tre { + + /* + * Enumerations and constants + */ + enum TextureType { + ttTexture1D, + ttTexture2D, + ttTexture3D, + ttCubeMap + }; + + enum TextureFormat { + tfUnknown, + tfR8G8B8, + tfR8G8B8A8, + + // FIXME: rename to be more OpenGL/D3D10 like (endinanism) + tfA8R8G8B8, + tfX8R8G8B8, + tfA4R4G4B4, + tfR3G3B2, + tfA8R3G3B2, + tfX4R4G4B4, + tfR5G6B5, + tfX1R5G5B5, + tfA1R5G5B5, + tfA8, + tfA2B10G10R10, + tfA2R10G10B10, + tfA8B8G8R8, + tfX8B8G8R8, + tfG16R16, + tfA16B16G16R16, + tfR16F, + tfG16R16F, + tfA16B16G16R16F, + tfR32F, + tfG32R32F, + tfA32B32G32R32F, + tfLast + }; + + /* + * Texture class + */ + + class Texture; + + typedef boost::shared_ptr TexturePtr; + typedef boost::weak_ptr TextureRef; + + class TextureFactory { + public: + const TexturePtr CreateInstance(const std::string & name); + const TexturePtr CreateInstance(const std::string & name, + TextureType type, uint width, uint height, TextureFormat format); + + // create anonymous texture + const TexturePtr CreateInstance(TextureType type, + uint width, uint height, TextureFormat format); + + private: + typedef std::tr1::unordered_map TextureMap; + + private: + TextureMap map_; + }; + + class Texture : private boost::noncopyable { + public: + static TextureFactory & Factory(void) + { + static TextureFactory fac; + return fac; + } + + public: + Texture() {} + virtual ~Texture() {} + + virtual void UpdateRect(const Vector2u & origin, + const Vector2u & size, const ByteVector & data) = 0; + +#ifdef DEBUG + virtual void DumpToFile(const std::string & name) const = 0; +#endif + }; + +} diff --git a/include/stdtypes.h b/include/stdtypes.h new file mode 100644 index 0000000..4120bf4 --- /dev/null +++ b/include/stdtypes.h @@ -0,0 +1,58 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file stdtypes.h +* + * Header file containing definitions of specialized templated data types. + */ + +#pragma once + +#include +#include + +#include "types.h" +#include "math/vector.h" +#include "math/matrix.h" + +/* + * Common vector typedefs + */ + +typedef std::vector BitVector; +typedef std::vector ByteVector; + +typedef std::vector IntVector; +typedef std::vector Int2Vector; +typedef std::vector Int3Vector; +typedef std::vector Int4Vector; + +typedef std::vector UIntVector; +typedef std::vector UInt2Vector; +typedef std::vector UInt3Vector; +typedef std::vector UInt4Vector; + +typedef std::vector FloatVector; +typedef std::vector Float2Vector; +typedef std::vector Float3Vector; +typedef std::vector Float4Vector; + +typedef std::vector StrVector; + +typedef std::vector Mat4Vector; diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000..8d8920b --- /dev/null +++ b/include/types.h @@ -0,0 +1,71 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file types.h + * + * Header file containing definitions of custom data types. + */ + +#pragma once + +#include + +/* + * Common data-types + */ +typedef unsigned char byte; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +/* + * Integral types + */ +typedef char int8; +typedef unsigned char uint8; + +#if SHRT_MAX == 32767 + typedef short int16; + typedef unsigned short int uint16; +#endif + +#if INT_MAX == 2147483647 + typedef int int32; + typedef unsigned int uint32; +#elif SHRT_MAX == 2147483647 + typedef short int32; + typedef unsigned short uint32; +#elif LONG_MAX == 2147483647 + typedef long int32; + typedef unsigned long uint32; +#endif + +#if LONG_MAX == +9223372036854775807 + typedef long int64; + typedef unsigned long uint64; +#elif LLONG_MAX == +9223372036854775807 + typedef long long int64; + typedef unsigned long long uint64; +#endif + +#if POINTER_SIZE == 4 + typedef uint32 uptr; +#elif POINTER_SIZE == 8 + typedef uint64 uptr; +#endif diff --git a/include/utf8.h b/include/utf8.h new file mode 100644 index 0000000..4e44514 --- /dev/null +++ b/include/utf8.h @@ -0,0 +1,34 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/checked.h" +#include "utf8/unchecked.h" + +#endif // header guard diff --git a/include/utf8/checked.h b/include/utf8/checked.h new file mode 100644 index 0000000..8d61a34 --- /dev/null +++ b/include/utf8/checked.h @@ -0,0 +1,318 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" +#include + +namespace utf8 +{ + // Exceptions that may be thrown from the library functions. + class invalid_code_point : public std::exception { + uint32_t cp; + public: + invalid_code_point(uint32_t cp) : cp(cp) {} + virtual const char* what() const throw() { return "Invalid code point"; } + uint32_t code_point() const {return cp;} + }; + + class invalid_utf8 : public std::exception { + uint8_t u8; + public: + invalid_utf8 (uint8_t u) : u8(u) {} + virtual const char* what() const throw() { return "Invalid UTF-8"; } + uint8_t utf8_octet() const {return u8;} + }; + + class invalid_utf16 : public std::exception { + uint16_t u16; + public: + invalid_utf16 (uint16_t u) : u16(u) {} + virtual const char* what() const throw() { return "Invalid UTF-16"; } + uint16_t utf16_word() const {return u16;} + }; + + class not_enough_room : public std::exception { + public: + virtual const char* what() const throw() { return "Not enough space"; } + }; + + /// The library API - functions intended to be called by the users + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = internal::validate_next(start, end); + switch (err_code) { + case internal::OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + throw not_enough_room(); + case internal::INVALID_LEAD: + append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (internal::is_trail(*start) && start != end) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const uint32_t replacement_marker = internal::mask16(0xfffd); + return replace_invalid(start, end, out, replacement_marker); + } + + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (!internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp <= internal::CODE_POINT_MAX) { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12)& 0x3f) | 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else + throw invalid_code_point(cp); + + return result; + } + + template + uint32_t next(octet_iterator& it, octet_iterator end) + { + uint32_t cp = 0; + internal::utf_error err_code = internal::validate_next(it, end, &cp); + switch (err_code) { + case internal::OK : + break; + case internal::NOT_ENOUGH_ROOM : + throw not_enough_room(); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : + throw invalid_utf8(*it); + case internal::INVALID_CODE_POINT : + throw invalid_code_point(cp); + } + return cp; + } + + template + uint32_t peek_next(octet_iterator it, octet_iterator end) + { + return next(it, end); + } + + template + uint32_t prior(octet_iterator& it, octet_iterator start) + { + octet_iterator end = it; + while (internal::is_trail(*(--it))) + if (it < start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return next(temp, end); + } + + /// Deprecated in versions that include "prior" + template + uint32_t previous(octet_iterator& it, octet_iterator pass_start) + { + octet_iterator end = it; + while (internal::is_trail(*(--it))) + if (it == pass_start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return next(temp, end); + } + + template + void advance (octet_iterator& it, distance_type n, octet_iterator end) + { + for (distance_type i = 0; i < n; ++i) + next(it, end); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + next(first, last); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = internal::mask16(*start++); + // Take care of surrogate pairs first + if (internal::is_surrogate(cp)) { + if (start != end) { + uint32_t trail_surrogate = internal::mask16(*start++); + if (trail_surrogate >= internal::TRAIL_SURROGATE_MIN && trail_surrogate <= internal::TRAIL_SURROGATE_MAX) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else + throw invalid_utf16(static_cast(trail_surrogate)); + } + else + throw invalid_utf16(static_cast(*start)); + + } + result = append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = next(start, end); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = next(start, end); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + octet_iterator range_start; + octet_iterator range_end; + public: + iterator () {}; + explicit iterator (const octet_iterator& octet_it, + const octet_iterator& range_start, + const octet_iterator& range_end) : + it(octet_it), range_start(range_start), range_end(range_end) + { + if (it < range_start || it > range_end) + throw std::out_of_range("Invalid utf-8 iterator position"); + } + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return next(temp, range_end); + } + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) + throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + next(it, range_end); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + next(it, range_end); + return temp; + } + iterator& operator -- () + { + prior(it, range_start); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + prior(it, range_start); + return temp; + } + }; // class iterator + +} // namespace utf8 + +#endif //header guard + + diff --git a/include/utf8/core.h b/include/utf8/core.h new file mode 100644 index 0000000..ca8c94a --- /dev/null +++ b/include/utf8/core.h @@ -0,0 +1,259 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include + +namespace utf8 +{ + // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers + // You may need to change them to match your system. + // These typedefs have the same names as ones from cstdint, or boost/cstdint + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + +// Helper code - not intended to be directly called by the library users. May be changed at any time +namespace internal +{ + // Unicode constants + // Leading (high) surrogates: 0xd800 - 0xdbff + // Trailing (low) surrogates: 0xdc00 - 0xdfff + const uint16_t LEAD_SURROGATE_MIN = 0xd800u; + const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; + const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; + const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; + const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); + const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; + + // Maximum valid value for a Unicode code point + const uint32_t CODE_POINT_MAX = 0x0010ffffu; + + template + inline uint8_t mask8(octet_type oc) + { + return static_cast(0xff & oc); + } + template + inline uint16_t mask16(u16_type oc) + { + return static_cast(0xffff & oc); + } + template + inline bool is_trail(octet_type oc) + { + return ((mask8(oc) >> 6) == 0x2); + } + + template + inline bool is_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_code_point_valid(u32 cp) + { + return (cp <= CODE_POINT_MAX && !is_surrogate(cp) && cp != 0xfffe && cp != 0xffff); + } + + template + inline typename std::iterator_traits::difference_type + sequence_length(octet_iterator lead_it) + { + uint8_t lead = mask8(*lead_it); + if (lead < 0x80) + return 1; + else if ((lead >> 5) == 0x6) + return 2; + else if ((lead >> 4) == 0xe) + return 3; + else if ((lead >> 3) == 0x1e) + return 4; + else + return 0; + } + + enum utf_error {OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; + + template + utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t* code_point) + { + uint32_t cp = mask8(*it); + // Check the lead octet + typedef typename std::iterator_traits::difference_type octet_difference_type; + octet_difference_type length = sequence_length(it); + + // "Shortcut" for ASCII characters + if (length == 1) { + if (end - it > 0) { + if (code_point) + *code_point = cp; + ++it; + return OK; + } + else + return NOT_ENOUGH_ROOM; + } + + // Do we have enough memory? + if (std::distance(it, end) < length) + return NOT_ENOUGH_ROOM; + + // Check trail octets and calculate the code point + switch (length) { + case 0: + return INVALID_LEAD; + break; + case 2: + if (is_trail(*(++it))) { + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + } + else { + --it; + return INCOMPLETE_SEQUENCE; + } + break; + case 3: + if (is_trail(*(++it))) { + cp = ((cp << 12) & 0xffff) + ((mask8(*it) << 6) & 0xfff); + if (is_trail(*(++it))) { + cp += (*it) & 0x3f; + } + else { + std::advance(it, -2); + return INCOMPLETE_SEQUENCE; + } + } + else { + --it; + return INCOMPLETE_SEQUENCE; + } + break; + case 4: + if (is_trail(*(++it))) { + cp = ((cp << 18) & 0x1fffff) + ((mask8(*it) << 12) & 0x3ffff); + if (is_trail(*(++it))) { + cp += (mask8(*it) << 6) & 0xfff; + if (is_trail(*(++it))) { + cp += (*it) & 0x3f; + } + else { + std::advance(it, -3); + return INCOMPLETE_SEQUENCE; + } + } + else { + std::advance(it, -2); + return INCOMPLETE_SEQUENCE; + } + } + else { + --it; + return INCOMPLETE_SEQUENCE; + } + break; + } + // Is the code point valid? + if (!is_code_point_valid(cp)) { + for (octet_difference_type i = 0; i < length - 1; ++i) + --it; + return INVALID_CODE_POINT; + } + + if (code_point) + *code_point = cp; + + if (cp < 0x80) { + if (length != 1) { + std::advance(it, -(length-1)); + return OVERLONG_SEQUENCE; + } + } + else if (cp < 0x800) { + if (length != 2) { + std::advance(it, -(length-1)); + return OVERLONG_SEQUENCE; + } + } + else if (cp < 0x10000) { + if (length != 3) { + std::advance(it, -(length-1)); + return OVERLONG_SEQUENCE; + } + } + + ++it; + return OK; + } + + template + inline utf_error validate_next(octet_iterator& it, octet_iterator end) { + return validate_next(it, end, 0); + } + +} // namespace internal + + /// The library API - functions intended to be called by the users + + // Byte order mark + const uint8_t bom[] = {0xef, 0xbb, 0xbf}; + + template + octet_iterator find_invalid(octet_iterator start, octet_iterator end) + { + octet_iterator result = start; + while (result != end) { + internal::utf_error err_code = internal::validate_next(result, end); + if (err_code != internal::OK) + return result; + } + return result; + } + + template + inline bool is_valid(octet_iterator start, octet_iterator end) + { + return (find_invalid(start, end) == end); + } + + template + inline bool is_bom (octet_iterator it) + { + return ( + (internal::mask8(*it++)) == bom[0] && + (internal::mask8(*it++)) == bom[1] && + (internal::mask8(*it)) == bom[2] + ); + } +} // namespace utf8 + +#endif // header guard + + diff --git a/include/utf8/unchecked.h b/include/utf8/unchecked.h new file mode 100644 index 0000000..4009ceb --- /dev/null +++ b/include/utf8/unchecked.h @@ -0,0 +1,228 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" + +namespace utf8 +{ + namespace unchecked + { + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast((cp >> 6) & 0x3f | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast((cp >> 12)& 0x3f | 0x80); + *(result++) = static_cast((cp >> 6) & 0x3f | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + uint32_t next(octet_iterator& it) + { + uint32_t cp = internal::mask8(*it); + typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); + switch (length) { + case 1: + break; + case 2: + it++; + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + break; + case 3: + ++it; + cp = ((cp << 12) & 0xffff) + ((internal::mask8(*it) << 6) & 0xfff); + ++it; + cp += (*it) & 0x3f; + break; + case 4: + ++it; + cp = ((cp << 18) & 0x1fffff) + ((internal::mask8(*it) << 12) & 0x3ffff); + ++it; + cp += (internal::mask8(*it) << 6) & 0xfff; + ++it; + cp += (*it) & 0x3f; + break; + } + ++it; + return cp; + } + + template + uint32_t peek_next(octet_iterator it) + { + return next(it); + } + + template + uint32_t prior(octet_iterator& it) + { + while (internal::is_trail(*(--it))) ; + octet_iterator temp = it; + return next(temp); + } + + // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) + template + inline uint32_t previous(octet_iterator& it) + { + return prior(it); + } + + template + void advance (octet_iterator& it, distance_type n) + { + for (distance_type i = 0; i < n; ++i) + next(it); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + next(first); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = internal::mask16(*start++); + // Take care of surrogate pairs first + if (internal::is_surrogate(cp)) { + uint32_t trail_surrogate = internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + } + result = append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = next(start); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = next(start); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + public: + iterator () {}; + explicit iterator (const octet_iterator& octet_it): it(octet_it) {} + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return next(temp); + } + bool operator == (const iterator& rhs) const + { + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + std::advance(it, internal::sequence_length(it)); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + std::advance(it, internal::sequence_length(it)); + return temp; + } + iterator& operator -- () + { + prior(it); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + prior(it); + return temp; + } + }; // class iterator + + } // namespace utf8::unchecked +} // namespace utf8 + + +#endif // header guard + diff --git a/include/vfs/console.h b/include/vfs/console.h new file mode 100644 index 0000000..f9efd83 --- /dev/null +++ b/include/vfs/console.h @@ -0,0 +1,72 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file console.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "types.h" + +namespace tre { + + /** Default size of IO buffers. */ + const int defConsoleLines = 80; + + class ConsoleBuffer : public std::streambuf { + public: + ConsoleBuffer(uint l) : sq_(l), lines_(l) {} + + protected: + // write one character + int overflow(int c); + + // write multiple characters + std::streamsize xsputn(const char * s, std::streamsize num); + + private: + typedef std::deque StringQueue; + + StringQueue sq_; + uint lines_; + }; + + class ConsoleStream : public std::iostream { + public: + static bool ready; + + public: + ConsoleStream(uint lines=defConsoleLines); + ~ConsoleStream(); + + int format(const char * fmt, ...); + + private: + ConsoleBuffer buf_; + }; + + extern ConsoleStream vOut; + +} diff --git a/include/vfs/export.h b/include/vfs/export.h new file mode 100644 index 0000000..dd0205d --- /dev/null +++ b/include/vfs/export.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2007 by Martin Moracek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file export.h + * + * Contains declarations of functions and variables exported from vfs. + * + * This file contains declarations of functions and variables to be "exported" + * from C++ vfs namespace into ANSI C parts of the program (lua). + */ + +#pragma once + +#include + +typedef void VFS_FILE; +typedef unsigned long vfs_size_t; +typedef unsigned long vfs_fpos_t; + +/* Constants */ +/* Pity this can't be const int because of ANSI C */ +#define VFS_BUFSIZ 8192 +#define VFS_EOF -1 + +#define VFS_FILENAME_MAX 255 +#define VFS_FOPEN_MAX 255 + +/* Not supported */ +#define VFS_L_tmpnam 1 +#define VFS_TMP_MAX 0 + +#define VFS_SEEK_SET 0 +#define VFS_SEEK_CUR 1 +#define VFS_SEEK_END 2 + +/* full/line/no buffering */ +#define VFS_IOFBF 0 +#define VFS_IOLBF 1 +#define VFS_IONBF 2 + +/* Macros */ +#define vfs_setbuf(f,b,s) vfs_setvbuf((f),(b),VFS_IOFBF,VFS_BUFSIZ) + +#define vfs_getc(f) vfs_fgetc(f) +#define vfs_getchar() vfs_fgetc(vfs_stdin) +/* No gets, just fgets */ +#define vfs_gets vfs_fgets +#define vfs_putc(c,s) vfs_fputc((c),(s)) +#define vfs_putchar(c) vfs_fputc((c),vfs_stdout) +#define vfs_puts(s) {vfs_fputs((s),vfs_stdout);vfs_fputc('\n',vfs_stdout);} + +#define vfs_rewind(s) vfs_fseek((s),0,VFS_SEEK_SET) + +/* stdin, stdout, stderr */ +extern VFS_FILE * vfs_stdin; /** Wrapper for game console input. */ +extern VFS_FILE * vfs_stdout; /** Wrapper for game console output. */ +extern VFS_FILE * vfs_stderr; /** Wrapper for game error output. */ + +/* + * Operations on files + */ + +extern int vfs_remove(const char * filename); +extern int vfs_rename(const char * oldname,const char * newname); +extern VFS_FILE * vfs_tmpfile(void); +extern char * vfs_tmpnam(char *s); + +/* + * File access + */ + +extern int vfs_fclose(VFS_FILE * stream); +extern int vfs_fflush(VFS_FILE * stream); +extern VFS_FILE * vfs_fopen(const char * filename,const char * mode); +extern VFS_FILE * vfs_freopen(const char * filename, + const char * mode,VFS_FILE * stream); +extern int vfs_setvbuf(VFS_FILE * file,char * buf,int mode,vfs_size_t size); + +/* + * Formatted input/output + */ + +extern int vfs_fprintf(VFS_FILE * stream,const char * format,...); +extern int vfs_fscanf(VFS_FILE * stream,const char * format,...); +extern int vfs_printf(const char * format,...); +extern int vfs_scanf(const char * format,...); +extern int vfs_vfprintf(VFS_FILE * stream, const char * format,va_list ap); +extern int vfs_vfscanf(VFS_FILE * stream, const char * format,va_list ap); +extern int vfs_vprintf(const char * format,va_list ap); +extern int vfs_vscanf(const char * format,va_list ap); + +/* + * Character input/output + */ + +extern int vfs_fgetc(VFS_FILE * stream); +extern char * vfs_fgets(char * s, int size,VFS_FILE * stream); +extern int vfs_fputc(int c,VFS_FILE * stream); +extern int vfs_fputs(const char * s,VFS_FILE * stream); +extern int vfs_ungetc(int c,VFS_FILE * stream); + +/* + * Direct input/output + */ + +extern vfs_size_t vfs_fread(void * ptr,vfs_size_t size, + vfs_size_t nmemb,VFS_FILE * stream); +extern vfs_size_t vfs_fwrite(const void * ptr,vfs_size_t size, + vfs_size_t nmemb,VFS_FILE * stream); + +/* + * File positioning + */ + +extern int vfs_fgetpos(VFS_FILE * stream,vfs_fpos_t * position); +extern int vfs_fseek(VFS_FILE * stream,long offset,int whence); +extern int vfs_fsetpos(VFS_FILE * stream,const vfs_fpos_t * pos); +extern long vfs_ftell(VFS_FILE * stream); + +/* + * Error-handling + */ + +extern void vfs_clearerr(VFS_FILE * file); +extern int vfs_feof(VFS_FILE * file); +extern int vfs_ferror(VFS_FILE * file); +extern void vfs_perror(const char * s); diff --git a/include/vfs/fstream.h b/include/vfs/fstream.h new file mode 100644 index 0000000..b699581 --- /dev/null +++ b/include/vfs/fstream.h @@ -0,0 +1,109 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file fstream.h + * + * blablabla + */ + +#pragma once + +#include +#include + +#include "types.h" + +namespace tre { + + /* + * File stream classes + * + * names of public methods follow STL naming convention + */ + class FileIStream : public std::istream { + public: + FileIStream(); + FileIStream(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::binary); + ~FileIStream(); + + bool open(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::binary); + + void close(void); + + bool is_open(void) const; + + ulong length(void) const; + + int iformat(const char * fmt, ...); + }; + + class FileOStream : public std::ostream { + public: + FileOStream(); + FileOStream(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::binary + | std::ios_base::trunc); + ~FileOStream(); + + bool open(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::binary + | std::ios_base::trunc); + + void close(void); + + bool is_open(void) const; + + ulong length(void) const; + + int oformat(const char * fmt, ...); + }; + + class FileIOStream : public std::iostream { + public: + FileIOStream(); + FileIOStream(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::binary + | std::ios_base::in); + ~FileIOStream(); + + bool open(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::binary + | std::ios_base::in); + + void close(void); + + bool is_open(void) const; + + ulong length(void) const; + + int iformat(const char * fmt, ...); + int oformat(const char * fmt, ...); + }; + + /* + * FileBuffer interface + */ + class FileBuffer : public std::streambuf { + public: + virtual ulong GetSize(void) const = 0; + }; + +} // vfs diff --git a/include/vfs/init_io.cpp b/include/vfs/init_io.cpp new file mode 100644 index 0000000..ea85ff0 --- /dev/null +++ b/include/vfs/init_io.cpp @@ -0,0 +1,36 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file init_io.cpp + * + * blahblah + */ + +#include "vfs/console.h" +#include "vfs/logfile.h" + +#include "vfs/export.h" + +namespace tre { + ConsoleStream vOut; +} + +VFS_FILE * vfs_stdin = &tre::vLog; +VFS_FILE * vfs_stdout = &tre::vLog; +VFS_FILE * vfs_stderr = &tre::vLog; diff --git a/include/vfs/init_logger.cpp b/include/vfs/init_logger.cpp new file mode 100644 index 0000000..c889b06 --- /dev/null +++ b/include/vfs/init_logger.cpp @@ -0,0 +1,38 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file init_logger.cpp + * + * blahblah + */ + +#include "vfs/logfile.h" + +#ifndef BUILD_NAME +# error BUILD_NAME not defined! +#endif /* BUILD_NAME */ + +namespace tre { + + const char * const buildName = BUILD_NAME; + + /** The main logging facility. */ + LogStream vLog(BUILD_NAME ".log"); + +} diff --git a/include/vfs/interface.h b/include/vfs/interface.h new file mode 100644 index 0000000..7b7b1a3 --- /dev/null +++ b/include/vfs/interface.h @@ -0,0 +1,197 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file interface.h + * + * Contains declarations of common virtual file system interface. + * + * The whole VFS interface is wrapped in vfs namespace in order to + * reinforce it's autonomous nature. + */ + +#pragma once + +#include +#include +#include + +#include "stdtypes.h" + +/** + * @namespace vfs + * + * Encapsulates the whole virtual file system. + * + * Contains all VFS related functions classes. Functionality provided is + * opening and closing files, mounting and unmounting directories (including + * transparent support for zip-like archives), querying directories and + * retrieving basic file related information. + */ +namespace tre { + + /* + * Additional structures + */ + + struct FileInfo { + bool isDir; + bool readOnly; + ulong size; + ulong mtime; + }; + + /* + * Forward class declarations + */ + class Vfs; + class MountNode; + + class FileIStream; + class FileOStream; + class FileIOStream; + + /* + * Global variables + */ + + Vfs & sVfs(void); + + /* + * Class declarations + */ + + /** + * @class Vfs + * + * Interface for all non-file operations. + * + * Contains all mounted directories stored in an array and provides basic + * methods for mounting and unmounting directories. Note that root + * directory must be mounted prior to any file or directory operation. Also + * offers some means for directory parsing. + */ + class Vfs { + public: + struct MountInfo { + std::string name; + std::string path; + bool readOnly; + }; + + typedef std::vector MountInfoVector; + + public: + Vfs(); + ~Vfs(); + + bool MountPath(const std::string & path, const std::string & dir, + bool readOnly=true); + + bool UnMountPath(const std::string & path); + bool UnMountDir(const std::string & dir); + bool UnMountDirPath(const std::string & dir, const std::string & path); + + bool OpenFile(const std::string & filename, FileIStream & file, + std::ios_base::openmode mode=std::ios_base::binary) const; + bool OpenFile(const std::string & filename, FileOStream & file, + std::ios_base::openmode mode=std::ios_base::binary + | std::ios_base::trunc) const; + bool OpenFile(const std::string & filename, FileIOStream & file, + std::ios_base::openmode mode=std::ios_base::binary + | std::ios_base::in) const; + + const std::string TranslatePath(const std::string & filename, + std::ios_base::openmode mode=std::ios_base::in); + + bool Stat(const std::string & filename, FileInfo & info) const; + bool Exists(const std::string & filename) const; + + const StrVector QueryDir(const std::string & dir) const; + const MountInfoVector QueryMounts(void) const; + + private: + typedef std::pair MountPair; + typedef std::vector MountVector; + + private: + MountVector mounts_; /// Mount points + }; + + /** + * @class MountNode + * + * Abstract interface for all mountable sources. + * + * Virtual class serving as a parent for deriving all classes encapsulating + * virtual drives. Provides basic interface. + */ + class MountNode { + public: + MountNode(const std::string & path, bool mode) + : path_(path), readOnly_(mode) {} + + virtual ~MountNode() {} + + /// Simple inspector function returning _strPath member. + const std::string & GetPath(void) const {return path_;} + + bool IsReadOnly(void) const {return readOnly_;} + + /** Opens a file in specified mode diven it's virtual path. + * + * @param[in] filename Name of file to be opened. + * @param[out] file Stream class to be initialized. + * @param[in] mode Mode in which the file should be opened. + * @return true on successfull operation, otherwise false. + */ + virtual bool OpenFile(const std::string & filename, + FileIStream & file, std::ios_base::openmode mode) const = 0; + + virtual bool OpenFile(const std::string & filename, + FileOStream & file, std::ios_base::openmode mode) const = 0; + + virtual bool OpenFile(const std::string & filename, + FileIOStream & file, std::ios_base::openmode mode) const = 0; + + virtual bool Stat(const std::string & filename, + FileInfo & info) const = 0; + + /** Tests if the specified file exists in the vfs or not. + * + * @param[in] filename Virtual path to the file to be tested. + * @return true if the file is found, otherwise false. + */ + virtual bool Exists(const std::string & filename) const = 0; + + virtual const StrVector QueryDir(const std::string & dir) const = 0; + + protected: + std::string path_; /// Real path of the mounted node. + bool readOnly_; + }; + + // Vfs singleton + inline Vfs & sVfs(void) + { + static Vfs vfs; + + return vfs; + } + +} // vfs diff --git a/include/vfs/logfile.h b/include/vfs/logfile.h new file mode 100644 index 0000000..e69f0a9 --- /dev/null +++ b/include/vfs/logfile.h @@ -0,0 +1,165 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file logfile.h + * + * Provides interface for the logging facility. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace tre { + + /* + * Constants and types + */ + + const unsigned int maxOutPerFac = 5; + + enum LogFacility { + lfDefault = 0, + lfSystem, + lfMemory, + lfVideo, + lfAudio, + lfNetwork, + lfDebug, + lfUser, + lfLocal0, + lfLocal1, + lfLocal2, + lfLast + }; + + enum LogType { + ltNone = 0, + ltCerr, + ltConsole, + ltFile + }; + + /* + * Log stream utility stuff + */ + class LogStream; + + class fac { + public: + fac(LogFacility facility=lfDefault) : fc_(facility) {} + friend LogStream & operator << (LogStream & ls, const fac & m); + + private: + LogFacility fc_; + }; + + class msg { + public: + msg(const char * sender=NULL) : snd_(sender) {} + friend std::ostream & operator << (std::ostream & ls, const msg & m); + + private: + const char * snd_; + }; + + class ok { + public: + ok(const char * sender=NULL) : snd_(sender) {} + friend std::ostream & operator << (std::ostream & ls, const ok & m); + + private: + const char * snd_; + }; + + class info { + public: + info(const char * sender=NULL) : snd_(sender) {} + friend std::ostream & operator << (std::ostream & ls, const info & m); + + private: + const char * snd_; + }; + + class warn { + public: + warn(const char * sender=NULL) : snd_(sender) {} + friend std::ostream & operator << (std::ostream & ls, const warn & m); + + private: + const char * snd_; + }; + + class err { + public: + err(const char * sender=NULL) : snd_(sender) {} + friend std::ostream & operator << (std::ostream & ls, const err & f); + + private: + const char * snd_; + }; + + /* + * Class declarations + */ + class LogBuffer : public std::streambuf { + public: + LogBuffer(const char * deffile); + ~LogBuffer(); + + void AddOutput(LogFacility facility, LogType type, + const char * file, bool trunc); + void SetFacility(LogFacility facility) {activeFac_ = facility;} + + protected: + int overflow(int c); + std::streamsize xsputn(const char * s, std::streamsize num); + int sync(void); + + private: + struct OutputSlot { + LogType type; + FILE * file; + }; + + private: + LogFacility activeFac_; // active facility + OutputSlot out_[lfLast][maxOutPerFac]; + }; + + class LogStream : public std::iostream { + public: + LogStream(const char * logfile); + + int oformat(const char * fmt, ...); + + void AddOutput(LogFacility facility, LogType type, + const char * file=NULL, bool trunc=true); + void SetFacility(LogFacility facility) {buf_.SetFacility(facility);} + + private: + LogBuffer buf_; + }; + + extern LogStream vLog; +} diff --git a/include/vfs/operators.h b/include/vfs/operators.h new file mode 100644 index 0000000..e8c13e2 --- /dev/null +++ b/include/vfs/operators.h @@ -0,0 +1,60 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file operators.h + * + * Ble. + */ + +#pragma once + +#include +#include + +#include "stdtypes.h" +#include "math/vector.h" + +std::ostream & operator << (std::ostream & o, const tre::Vector2f & v); +std::ostream & operator << (std::ostream & o, const tre::Vector3f & v); +std::ostream & operator << (std::ostream & o, const tre::Vector4f & v); + +std::ostream & operator << (std::ostream & o, const std::wstring & str); + +template +inline std::ostream & operator << +(std::ostream & o, const std::pair & p) +{ + o << "(" << p.first << ", " << p.second << ")"; + return o; +} + +template +inline std::ostream & operator << (std::ostream & o, const std::vector & vec) +{ + o << "["; + if(!vec.empty()) { + o << vec.front(); + for(typename std::vector::const_iterator pos = vec.begin() + 1; + pos != vec.end(); ++pos) { + o << ", " << *pos; + } + } + o << "]"; + return o; +} diff --git a/include/vfs/vario.h b/include/vfs/vario.h new file mode 100644 index 0000000..64be6a8 --- /dev/null +++ b/include/vfs/vario.h @@ -0,0 +1,50 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file vario.h + * + * Contains declaration of standard var io helper functions. + * + * This file contains declarations of all functions for standard input and + * output with variable arguments. Belongs to the vfs namespace. + */ + +#pragma once + +#include +#include + +#include "platform.h" + +#ifdef PLATFORM_MSVC +# define VFS_VA_LIST va_list& +#else /* PLATFORM_MSVC */ +# define VFS_VA_LIST va_list +#endif /* PLATFORM_MSVC */ + +namespace tre { + + + int StreamScanf(std::istream & is, const char * fmt, ...); + int StreamPrintf(std::ostream & os, const char * fmt, ...); + + int StreamScanfV(std::istream & is, const char * fmt, VFS_VA_LIST l_va); + int StreamPrintfV(std::ostream & os, const char * fmt, VFS_VA_LIST l_va); + +} diff --git a/include/xml/tinyxml.h b/include/xml/tinyxml.h new file mode 100644 index 0000000..c6f40cc --- /dev/null +++ b/include/xml/tinyxml.h @@ -0,0 +1,1802 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +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 TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SNSCANF _snscanf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SNSCANF _snscanf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SNSCANF snscanf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 5; +const int TIXML_PATCH_VERSION = 3; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simple called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknow node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + const TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* Find( const char* _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + #ifdef TIXML_USE_STL + const TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* Find( const std::string& _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + + #endif + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + /* + This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" + but template specialization is hard to get working cross-compiler. Leaving the bug for now. + + // The above will fail for std::string because the space character is used as a seperator. + // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string + template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + */ + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && LoadFile( f.buffer, encoding )); + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && SaveFile( f.buffer )); + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i + +class TiXmlElement; + +namespace tre { + + std::string CheckText(TiXmlElement & el, bool require=true); + + int CheckIntText(TiXmlElement & el, bool require=true, int def=0); + float CheckFloatText(TiXmlElement & el, bool require=true, float def=0.0f); + double CheckFloatText(TiXmlElement & el, bool require=true, double def=0.0); + + std::string CheckAttribute(TiXmlElement & el, + const char * name, bool require=true); + + int CheckIntAttribute(TiXmlElement & el, + const char * name, bool require=true, int def=0); + float CheckFloatAttribute(TiXmlElement & el, + const char * name, bool require=true, float def=0.0f); + float CheckDoubleAttribute(TiXmlElement & el, + const char * name, bool require=true, double def=0.0); + +} diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt new file mode 100644 index 0000000..c9488f2 --- /dev/null +++ b/projects/CMakeLists.txt @@ -0,0 +1,18 @@ +project(terrastrategy) + +cmake_minimum_required(VERSION 2.6) + +add_subdirectory(lib-core) +add_subdirectory(lib-font) +add_subdirectory(lib-gui) +add_subdirectory(lib-input) +add_subdirectory(lib-lua) +add_subdirectory(lib-math) +add_subdirectory(lib-memory) +add_subdirectory(lib-renderer) +add_subdirectory(lib-tinyxml) +add_subdirectory(lib-vfs) +add_subdirectory(terra-client) +add_subdirectory(terra-server) + +add_subdirectory(luac EXCLUDE_FROM_ALL) diff --git a/projects/lib-core/CMakeLists.txt b/projects/lib-core/CMakeLists.txt new file mode 100644 index 0000000..72ddee2 --- /dev/null +++ b/projects/lib-core/CMakeLists.txt @@ -0,0 +1,42 @@ +project(lib-core) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/core) +set(SRC_DIR ../../src/core) + +set(LIB_SOURCES + ${HEADER_DIR}/application.h + ${HEADER_DIR}/timer.h + ${HEADER_DIR}/vmachine.h + ${HEADER_DIR}/script_core.h + + ${SRC_DIR}/application.cpp + ${SRC_DIR}/timer.cpp + ${SRC_DIR}/vmachine.cpp + ${SRC_DIR}/script_core.cpp + ${SRC_DIR}/conf_core.cpp +) + +include_directories(../../include) +link_directories(../../lib) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +add_definitions(-DTIXML_USE_STL) + +# build commands +add_library(core SHARED ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(core PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) + +target_link_libraries(core lua SDL) diff --git a/projects/lib-font/CMakeLists.txt b/projects/lib-font/CMakeLists.txt new file mode 100644 index 0000000..57cd678 --- /dev/null +++ b/projects/lib-font/CMakeLists.txt @@ -0,0 +1,44 @@ +project(lib-font) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/gui/font) +set(SRC_DIR ../../src/gui/font) + +set(LIB_SOURCES + ${HEADER_DIR}/font.h + ${SRC_DIR}/freetype.h + + ${SRC_DIR}/font.cpp + ${SRC_DIR}/freetype.cpp +) + +include_directories(../../include) + +find_package(Freetype REQUIRED) +include_directories(${FREETYPE_INCLUDE_DIRS}) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +add_definitions(-DTIXML_USE_STL) + +# build commands +add_library(font STATIC ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set_target_properties(font PROPERTIES COMPILE_FLAGS + "-fPIC -ansi -pedantic -Wall -Wno-long-long") + else( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) + set_target_properties(font PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") + endif( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) +endif(UNIX OR MINGW) + +target_link_libraries(font ${FREETYPE_LIBRARIES}) \ No newline at end of file diff --git a/projects/lib-gui/CMakeLists.txt b/projects/lib-gui/CMakeLists.txt new file mode 100644 index 0000000..46e9eb7 --- /dev/null +++ b/projects/lib-gui/CMakeLists.txt @@ -0,0 +1,54 @@ +project(lib-gui) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/gui) +set(SRC_DIR ../../src/gui) + +set(LIB_SOURCES + ${HEADER_DIR}/gui.h + ${HEADER_DIR}/widget.h + ${HEADER_DIR}/basic.h + ${HEADER_DIR}/pixmap.h + ${HEADER_DIR}/richtext.h + ${HEADER_DIR}/plaintext.h + + ${SRC_DIR}/skin.h + ${SRC_DIR}/cursor.h + + ${SRC_DIR}/gui.cpp + ${SRC_DIR}/widget.cpp + ${SRC_DIR}/basic.cpp + ${SRC_DIR}/pixmap.cpp + ${SRC_DIR}/skin.cpp + ${SRC_DIR}/cursor.cpp + ${SRC_DIR}/text.cpp + ${SRC_DIR}/richtext.cpp + ${SRC_DIR}/plaintext.cpp +) + +include_directories(../../include) +link_directories(../../lib) + +find_package(Boost COMPONENTS signals REQUIRED) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +add_definitions(-DTIXML_USE_STL) + +# build commands +add_library(gui SHARED ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(gui PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) + +target_link_libraries(gui font math tinyxml vfs renderer + ${Boost_SIGNALS_LIBRARY}) diff --git a/projects/lib-input/CMakeLists.txt b/projects/lib-input/CMakeLists.txt new file mode 100644 index 0000000..19c6f1c --- /dev/null +++ b/projects/lib-input/CMakeLists.txt @@ -0,0 +1,31 @@ +project(lib-input) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/input) +set(SRC_DIR ../../src/input) + +set(LIB_SOURCES + ${HEADER_DIR}/input.h + ${SRC_DIR}/input.cpp +) + +include_directories(../../include) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +# build commands +add_library(input STATIC ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(input PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) + +target_link_libraries(input SDL) \ No newline at end of file diff --git a/projects/lib-lua/CMakeLists.txt b/projects/lib-lua/CMakeLists.txt new file mode 100644 index 0000000..4ed2d66 --- /dev/null +++ b/projects/lib-lua/CMakeLists.txt @@ -0,0 +1,116 @@ +# call this project somehow +project(lib-lua) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/lua) +set(SRC_DIR ../../src/lua) + +set(HEADER2_DIR ../../include/luabind) +set(SRC2_DIR ../../src/luabind) + +set(LUA_SOURCES + # headers + ${HEADER_DIR}/lauxlib.h + ${HEADER_DIR}/luaconf.h + ${HEADER_DIR}/lua.h + ${HEADER_DIR}/lualib.h + + ${SRC_DIR}/lapi.h + ${SRC_DIR}/lcode.h + ${SRC_DIR}/ldebug.h + ${SRC_DIR}/ldo.h + ${SRC_DIR}/lfunc.h + ${SRC_DIR}/lgc.h + ${SRC_DIR}/llex.h + + ${SRC_DIR}/lmem.h + ${SRC_DIR}/lobject.h + ${SRC_DIR}/lopcodes.h + ${SRC_DIR}/lparser.h + ${SRC_DIR}/lstate.h + ${SRC_DIR}/lstring.h + ${SRC_DIR}/ltable.h + ${SRC_DIR}/ltm.h + ${SRC_DIR}/lundump.h + ${SRC_DIR}/lvm.h + ${SRC_DIR}/lzio.h + + # core + ${SRC_DIR}/lapi.cpp + ${SRC_DIR}/lcode.cpp + ${SRC_DIR}/ldebug.cpp + ${SRC_DIR}/ldo.cpp + ${SRC_DIR}/ldump.cpp + ${SRC_DIR}/lfunc.cpp + ${SRC_DIR}/lgc.cpp + ${SRC_DIR}/llex.cpp + + ${SRC_DIR}/lmem.cpp + ${SRC_DIR}/lobject.cpp + ${SRC_DIR}/lopcodes.cpp + ${SRC_DIR}/lparser.cpp + ${SRC_DIR}/lstate.cpp + ${SRC_DIR}/lstring.cpp + ${SRC_DIR}/ltable.cpp + ${SRC_DIR}/ltm.cpp + ${SRC_DIR}/lundump.cpp + ${SRC_DIR}/lvm.cpp + ${SRC_DIR}/lzio.cpp + + # libraries + ${SRC_DIR}/lauxlib.cpp + ${SRC_DIR}/lbaselib.cpp + ${SRC_DIR}/ldblib.cpp + ${SRC_DIR}/liolib.cpp + ${SRC_DIR}/lmathlib.cpp + ${SRC_DIR}/loadlib.cpp + ${SRC_DIR}/loslib.cpp + ${SRC_DIR}/lstrlib.cpp + ${SRC_DIR}/ltablib.cpp + ${SRC_DIR}/linit.cpp +) + +set(LUABIND_SOURCES + # headers should be here, but don't bother + + ${SRC2_DIR}/class.cpp + ${SRC2_DIR}/class_info.cpp + ${SRC2_DIR}/class_registry.cpp + ${SRC2_DIR}/class_rep.cpp + ${SRC2_DIR}/create_class.cpp + ${SRC2_DIR}/error.cpp + ${SRC2_DIR}/exception_handler.cpp + ${SRC2_DIR}/find_best_match.cpp + ${SRC2_DIR}/function.cpp + ${SRC2_DIR}/implicit_cast.cpp + ${SRC2_DIR}/link_compatibility.cpp + ${SRC2_DIR}/object_rep.cpp + ${SRC2_DIR}/open.cpp + ${SRC2_DIR}/overload_rep.cpp + ${SRC2_DIR}/pcall.cpp + ${SRC2_DIR}/ref.cpp + ${SRC2_DIR}/scope.cpp + ${SRC2_DIR}/stack_content_by_name.cpp + ${SRC2_DIR}/weak_ref.cpp + ${SRC2_DIR}/wrapper_base.cpp +) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +include_directories(../../include) +include_directories(../../include/lua) + +# build commands +add_library(lua SHARED ${LUA_SOURCES} ${LUABIND_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(lua PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) diff --git a/projects/lib-math/CMakeLists.txt b/projects/lib-math/CMakeLists.txt new file mode 100644 index 0000000..6076936 --- /dev/null +++ b/projects/lib-math/CMakeLists.txt @@ -0,0 +1,41 @@ +project(lib-math) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/math) +set(SRC_DIR ../../src/math) + +set(LIB_SOURCES + ${HEADER_DIR}/math.h + ${HEADER_DIR}/vector.h + ${HEADER_DIR}/matrix.h + ${HEADER_DIR}/quaternion.h + ${HEADER_DIR}/transform.h + ${HEADER_DIR}/volumes.h + + ${SRC_DIR}/volumes.cpp +) + +include_directories(../../include) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +# build commands +add_library(math STATIC ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set_target_properties(math PROPERTIES COMPILE_FLAGS + "-fPIC -ansi -pedantic -Wall -Wno-long-long") + else( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) + set_target_properties(math PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") + endif( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) +endif(UNIX OR MINGW) + diff --git a/projects/lib-memory/CMakeLists.txt b/projects/lib-memory/CMakeLists.txt new file mode 100644 index 0000000..ba50556 --- /dev/null +++ b/projects/lib-memory/CMakeLists.txt @@ -0,0 +1,47 @@ +project(lib-memory) + +cmake_minimum_required(VERSION 2.6) + +include(CheckTypeSize) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include) +set(SRC_DIR ../../src) + +set(LIB_SOURCES + ${HEADER_DIR}/mem_on.h + ${HEADER_DIR}/mem_off.h + ${HEADER_DIR}/memory/mmgr.h + + ${SRC_DIR}/memory/mmgr.cpp +) + +include_directories(../../include) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +# sizeof(void*) check +CHECK_TYPE_SIZE(void* SIZE_PTR) + +if(SIZE_PTR EQUAL 4) + add_definitions(-DPOINTER_SIZE=4) +elseif(SIZE_PTR EQUAL 8) + add_definitions(-DPOINTER_SIZE=8) +endif(SIZE_PTR EQUAL 4) + +# memory manager tweaks +# add_definitions(-DSTRESS_TEST) +# add_definitions(-DRANDOM_FAILURE=10.0) + +# build commands +add_library(mmgr STATIC ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(mmgr PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) diff --git a/projects/lib-renderer/CMakeLists.txt b/projects/lib-renderer/CMakeLists.txt new file mode 100644 index 0000000..e0b0bcc --- /dev/null +++ b/projects/lib-renderer/CMakeLists.txt @@ -0,0 +1,70 @@ +project(lib-renderer) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +include(TestBigEndian) + +set(HEADER_DIR ../../include/renderer) +set(SRC_DIR ../../src/renderer) + +set(LIB_SOURCES + ${HEADER_DIR}/buffers.h + ${HEADER_DIR}/canvas.h + ${HEADER_DIR}/effect.h + ${HEADER_DIR}/renderer.h + ${HEADER_DIR}/texture.h + + ${SRC_DIR}/gl_buffers.h + ${SRC_DIR}/gl_canvas.h + ${SRC_DIR}/gl_texture.h + ${SRC_DIR}/cg_effect.h + ${SRC_DIR}/cg_renderer.h + ${SRC_DIR}/image_dds.h + ${SRC_DIR}/image_tga.h + + ${SRC_DIR}/gl_buffers.cpp + ${SRC_DIR}/gl_canvas.cpp + ${SRC_DIR}/gl_texture.cpp + ${SRC_DIR}/cg_effect.cpp + ${SRC_DIR}/cg_renderer.cpp + ${SRC_DIR}/image_dds.cpp + ${SRC_DIR}/image_tga.cpp +) + +include_directories(../../include) +link_directories(../../lib) + +find_package(Boost COMPONENTS wave OPTIONAL) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +# Big endianism check +test_big_endian(IS_BIG_ENDIAN) + +if(IS_BIG_ENDIAN EQUAL 1) + add_definitions(-DIS_BIG_ENDIAN=1) +elseif(IS_BIG_ENDIAN EQUAL 0) + add_definitions(-DIS_BIG_ENDIAN=0) +endif(IS_BIG_ENDIAN EQUAL 1) + +# build commands +add_library(renderer SHARED ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(renderer PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) + +if(Boost_WAVE_FOUND AND NOT NO_CG_PREPROCESSOR) + add_definitions(-DBUILD_CG_PREPROCESSOR) + target_link_libraries(renderer GLEW Cg CgGL ${Boost_WAVE_LIBRARY}) +else(Boost_WAVE_FOUND AND NOT NO_CG_PREPROCESSOR) + message("no wave") + target_link_libraries(renderer GLEW Cg CgGL) +endif(Boost_WAVE_FOUND AND NOT NO_CG_PREPROCESSOR) diff --git a/projects/lib-tinyxml/CMakeLists.txt b/projects/lib-tinyxml/CMakeLists.txt new file mode 100644 index 0000000..b25966b --- /dev/null +++ b/projects/lib-tinyxml/CMakeLists.txt @@ -0,0 +1,38 @@ +project(lib-tinyxml) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/xml) +set(SRC_DIR ../../src/xml) + +set(LIB_SOURCES + ${HEADER_DIR}/tinyxml.h + ${HEADER_DIR}/xmlutils.h + + ${SRC_DIR}/tinyxml.cpp + ${SRC_DIR}/tinyxmlerror.cpp + ${SRC_DIR}/tinyxmlparser.cpp + + ${SRC_DIR}/xmlutils.cpp +) + +include_directories(../../include) +include_directories(../../include/xml) + +add_definitions(-DTIXML_USE_STL) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +# build commands +add_library(tinyxml SHARED ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(tinyxml PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) diff --git a/projects/lib-vfs/CMakeLists.txt b/projects/lib-vfs/CMakeLists.txt new file mode 100644 index 0000000..3848a92 --- /dev/null +++ b/projects/lib-vfs/CMakeLists.txt @@ -0,0 +1,59 @@ +project(lib-vfs) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +include(CheckTypeSize) + +set(HEADER_DIR ../../include/vfs) +set(SRC_DIR ../../src/vfs) + +set(LIB_SOURCES + ${HEADER_DIR}/console.h + ${SRC_DIR}/diskfile.h + ${HEADER_DIR}/export.h + ${HEADER_DIR}/fstream.h + ${HEADER_DIR}/interface.h + ${HEADER_DIR}/logfile.h + ${HEADER_DIR}/operators.h + ${HEADER_DIR}/vario.h + ${SRC_DIR}/zipfile.h + + ${SRC_DIR}/console.cpp + ${SRC_DIR}/diskfile.cpp + ${SRC_DIR}/export.cpp + ${SRC_DIR}/fstream.cpp + ${SRC_DIR}/interface.cpp + ${SRC_DIR}/logfile.cpp + ${SRC_DIR}/operators.cpp + ${SRC_DIR}/vario.cpp + ${SRC_DIR}/zipfile.cpp + + #${SRC_DIR}/static.cpp +) + +include_directories(../../include) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +# sizeof(void*) check +CHECK_TYPE_SIZE(void* SIZE_PTR) + +if(SIZE_PTR EQUAL 4) + add_definitions(-DPOINTER_SIZE=4) +elseif(SIZE_PTR EQUAL 8) + add_definitions(-DPOINTER_SIZE=8) +endif(SIZE_PTR EQUAL 4) + +# build commands +add_library(vfs SHARED ${LIB_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(vfs PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) diff --git a/projects/luac/CMakeLists.txt b/projects/luac/CMakeLists.txt new file mode 100644 index 0000000..b7be72e --- /dev/null +++ b/projects/luac/CMakeLists.txt @@ -0,0 +1,91 @@ +project(luac) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(HEADER_DIR ../../include/lua) +set(SRC_DIR ../../src/lua) + +set(LUAC_SOURCES + luac.cpp + print.cpp + vfs_wrapper.cpp +) + +set(LUA_SOURCES + # headers + ${HEADER_DIR}/lauxlib.h + ${HEADER_DIR}/luaconf.h + ${HEADER_DIR}/lua.h + ${HEADER_DIR}/lualib.h + + ${SRC_DIR}/lapi.h + ${SRC_DIR}/lcode.h + ${SRC_DIR}/ldebug.h + ${SRC_DIR}/ldo.h + ${SRC_DIR}/lfunc.h + ${SRC_DIR}/lgc.h + ${SRC_DIR}/llex.h + + ${SRC_DIR}/lmem.h + ${SRC_DIR}/lobject.h + ${SRC_DIR}/lopcodes.h + ${SRC_DIR}/lparser.h + ${SRC_DIR}/lstate.h + ${SRC_DIR}/lstring.h + ${SRC_DIR}/ltable.h + ${SRC_DIR}/ltm.h + ${SRC_DIR}/lundump.h + ${SRC_DIR}/lvm.h + ${SRC_DIR}/lzio.h + + # core + ${SRC_DIR}/lapi.cpp + ${SRC_DIR}/lcode.cpp + ${SRC_DIR}/ldebug.cpp + ${SRC_DIR}/ldo.cpp + ${SRC_DIR}/ldump.cpp + ${SRC_DIR}/lfunc.cpp + ${SRC_DIR}/lgc.cpp + ${SRC_DIR}/llex.cpp + + ${SRC_DIR}/lmem.cpp + ${SRC_DIR}/lobject.cpp + ${SRC_DIR}/lopcodes.cpp + ${SRC_DIR}/lparser.cpp + ${SRC_DIR}/lstate.cpp + ${SRC_DIR}/lstring.cpp + ${SRC_DIR}/ltable.cpp + ${SRC_DIR}/ltm.cpp + ${SRC_DIR}/lundump.cpp + ${SRC_DIR}/lvm.cpp + ${SRC_DIR}/lzio.cpp + + # libraries + ${SRC_DIR}/lauxlib.cpp + #${SRC_DIR}/lbaselib.cpp + #${SRC_DIR}/ldblib.cpp + #${SRC_DIR}/liolib.cpp + ${SRC_DIR}/lmathlib.cpp + #${SRC_DIR}/loadlib.cpp + #${SRC_DIR}/loslib.cpp + #${SRC_DIR}/lstrlib.cpp + #${SRC_DIR}/ltablib.cpp + #${SRC_DIR}/linit.cpp +) + +include_directories(../../include) +include_directories(../../include/lua) +include_directories(../../src/lua) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +add_executable(luac ${LUAC_SOURCES} ${LUA_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS "-O2") + + set_target_properties(luac PROPERTIES COMPILE_FLAGS "-ansi -pedantic -Wall") + target_link_libraries(luac m) +endif(UNIX OR MINGW) diff --git a/projects/luac/luac.cpp b/projects/luac/luac.cpp new file mode 100644 index 0000000..d070173 --- /dev/null +++ b/projects/luac/luac.cpp @@ -0,0 +1,200 @@ +/* +** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", + progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i))->l.p) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + int i,pc; + Proto* f=luaF_newproto(L); + setptvalue2s(L,L->top,f); incr_top(L); + f->source=luaS_newliteral(L,"=(" PROGNAME ")"); + f->maxstacksize=1; + pc=2*n+1; + f->code=luaM_newvector(L,pc,Instruction); + f->sizecode=pc; + f->p=luaM_newvector(L,n,Proto*); + f->sizep=n; + pc=0; + for (i=0; ip[i]=toproto(L,i-n-1); + f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); + f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + } + f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +struct Smain { + int argc; + char** argv; +}; + +static int pmain(lua_State* L) +{ + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); + int argc=s->argc; + char** argv=s->argv; + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + struct Smain s; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=lua_open(); + if (L==NULL) fatal("not enough memory for state"); + s.argc=argc; + s.argv=argv; + if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} diff --git a/projects/luac/print.cpp b/projects/luac/print.cpp new file mode 100644 index 0000000..e240cfc --- /dev/null +++ b/projects/luac/print.cpp @@ -0,0 +1,227 @@ +/* +** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +} diff --git a/projects/luac/vfs_wrapper.cpp b/projects/luac/vfs_wrapper.cpp new file mode 100755 index 0000000..391744d --- /dev/null +++ b/projects/luac/vfs_wrapper.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007 by Martin Moracek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include "vfs/export.h" + +VFS_FILE * vfs_stdin; +VFS_FILE * vfs_stdout; +VFS_FILE * vfs_stderr; + +int vfs_fclose(VFS_FILE * stream) +{ + return fclose(static_cast(stream)); +} + +VFS_FILE * vfs_fopen(const char * filename, const char * mode) +{ + return fopen(filename, mode); +} + +VFS_FILE * vfs_freopen(char const * path, char const * mode, VFS_FILE * stream) +{ + return freopen(path, mode, static_cast(stream)); +} + + +int vfs_fprintf(VFS_FILE * stream, const char * format, ...) +{ + va_list l_va; + int res; + + va_start(l_va, format); + + res = vfprintf(static_cast(stream), format, l_va); + + va_end(l_va); + + return res; +} + +int vfs_fgetc(VFS_FILE * stream) +{ + return fgetc(static_cast(stream)); +} + +int vfs_ungetc(int c, VFS_FILE * stream) +{ + return ungetc(c, static_cast(stream)); +} + +vfs_size_t vfs_fread +(void * ptr, vfs_size_t size, vfs_size_t nmemb, VFS_FILE * stream) +{ + return fread(ptr, size, nmemb, static_cast(stream)); +} + +int vfs_feof(VFS_FILE * stream) +{ + return feof(static_cast(stream)); +} + +int vfs_ferror(VFS_FILE * stream) +{ + return ferror(static_cast(stream)); +} diff --git a/projects/terra-client/CMakeLists.txt b/projects/terra-client/CMakeLists.txt new file mode 100644 index 0000000..8ddd0f1 --- /dev/null +++ b/projects/terra-client/CMakeLists.txt @@ -0,0 +1,60 @@ +project(terra-client) + +cmake_minimum_required(VERSION 2.6) + +set(CMAKE_VERBOSE_MAKEFILE ON) + +set(CORE_HEADER_DIR ../../include/core/client) + +set(SRC_DIR ../../src/client) +set(CORE_SRC_DIR ../../src/core/client) + +set(CLIENT_SOURCES + ${SRC_DIR}/client.h + + ${SRC_DIR}/main.cpp + ${SRC_DIR}/client.cpp +) + +set(STATIC_CL_SOURCES + ${SRC_DIR}/static.cpp +) + +set(CORE_CL_SOURCES + ${CORE_HEADER_DIR}/display.h + ${SRC_DIR}/script_client.h + + ${CORE_SRC_DIR}/display.cpp + ${SRC_DIR}/script_client.cpp + ${SRC_DIR}/conf_client.cpp +) + +include_directories(../../include ../../include/lua) +link_directories(../../lib) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../) + +add_definitions(-DBUILD_NAME="terra-client") + +add_definitions(-DTIXML_USE_STL) + +# build commands +add_library(static-cl STATIC ${STATIC_CL_SOURCES}) +# add_library(core-cl STATIC ${CORE_CL_SOURCES}) +add_executable(terra-client ${CLIENT_SOURCES} ${CORE_CL_SOURCES}) + +if(UNIX OR MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG") + + set_target_properties(static-cl PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") + set_target_properties(terra-client PROPERTIES COMPILE_FLAGS + "-ansi -pedantic -Wall -Wno-long-long") +endif(UNIX OR MINGW) + +target_link_libraries(terra-client static-cl core vfs + mmgr gui input renderer +# efence +) diff --git a/projects/terra-server/CMakeLists.txt b/projects/terra-server/CMakeLists.txt new file mode 100755 index 0000000..bb1295c --- /dev/null +++ b/projects/terra-server/CMakeLists.txt @@ -0,0 +1,146 @@ +# Call this project somehow +PROJECT(terra-server) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# INCLUDE(TestBigEndian) +# INCLUDE(CheckTypeSize) +# +# SET(CMAKE_VERBOSE_MAKEFILE ON) +# +# SET(TERRA_SHARED_SOURCES +# # support sources +# ../../support/vfs_static.cpp +# +# ../../support/vfs.cpp +# ../../support/vfs_vario.cpp +# ../../support/vfs_export.cpp +# ../../support/vfs_logfile.cpp +# ../../support/vfs_diskfile.cpp +# ../../support/vfs_zipfile.cpp +# +# ../../support/memory.cpp +# +# ../../support/res_model_x.cpp +# +# # core sources +# ../../core/math.cpp +# ../../core/math_volumes.cpp +# ../../core/math_transform.cpp +# ../../core/mesh.cpp +# +# # scripting +# ../../framework/entity.cpp +# ../../framework/action.cpp +# ../../framework/attribute.cpp +# ../../framework/semantic.cpp +# ../../framework/spatial.cpp +# ../../framework/script_misc.cpp +# +# ../../framework/model.cpp +# +# # replace this file for custom derived classes +# ../../framework/factory.cpp +# +# ../../framework/application.cpp +# ../../framework/script.cpp +# ../../framework/script_base.cpp +# ../../framework/script_semantic.cpp +# ../../framework/script_spatial.cpp +# ../../framework/script_math.cpp +# ../../framework/script_xml.cpp +# ) +# +# SET(TERRA_SERVER_SOURCES +# server.cpp +# ) +# +# SET(LUA_SOURCES +# # Core +# ../../lua/lapi.cpp +# ../../lua/lcode.cpp +# ../../lua/ldebug.cpp +# ../../lua/ldo.cpp +# ../../lua/ldump.cpp +# ../../lua/lfunc.cpp +# ../../lua/lgc.cpp +# ../../lua/llex.cpp +# +# ../../lua/lmem.cpp +# ../../lua/lobject.cpp +# ../../lua/lopcodes.cpp +# ../../lua/lparser.cpp +# ../../lua/lstate.cpp +# ../../lua/lstring.cpp +# ../../lua/ltable.cpp +# ../../lua/ltm.cpp +# ../../lua/lundump.cpp +# ../../lua/lvm.cpp +# ../../lua/lzio.cpp +# +# # Libraries +# ../../lua/lauxlib.cpp +# ../../lua/lbaselib.cpp +# ../../lua/ldblib.cpp +# ../../lua/liolib.cpp +# ../../lua/lmathlib.cpp +# ../../lua/loadlib.cpp +# ../../lua/loslib.cpp +# ../../lua/lstrlib.cpp +# ../../lua/ltablib.cpp +# ../../lua/linit.cpp +# ) +# +# SET(XML_SOURCES +# ../../xml/tinystr.cpp +# ../../xml/tinyxml.cpp +# ../../xml/tinyxmlerror.cpp +# ../../xml/tinyxmlparser.cpp +# ) +# +# # Big endianism check +# TEST_BIG_ENDIAN(IS_BIG_ENDIAN) +# +# IF(IS_BIG_ENDIAN EQUAL 1) +# ADD_DEFINITIONS(-DIS_BIG_ENDIAN=1) +# ELSEIF(IS_BIG_ENDIAN EQUAL 0) +# ADD_DEFINITIONS(-DIS_BIG_ENDIAN=0) +# ENDIF(IS_BIG_ENDIAN EQUAL 1) +# +# # Sizeof(void*) check +# CHECK_TYPE_SIZE(void* SIZE_PTR) +# +# IF(SIZE_PTR EQUAL 4) +# ADD_DEFINITIONS(-DPOINTER_SIZE=4) +# ELSEIF(SIZE_PTR EQUAL 8) +# ADD_DEFINITIONS(-DPOINTER_SIZE=8) +# ENDIF(SIZE_PTR EQUAL 4) +# +# ADD_DEFINITIONS(-DTIXML_USE_STL) +# +# # Build type +# ADD_DEFINITIONS(-DBUILD_SERVER) +# +# #SET(CMAKE_BUILD_TYPE Debug) +# SET(CMAKE_BUILD_TYPE Release) +# +# # Build commands +# IF(UNIX OR MINGW) +# SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -D_DEBUG") +# SET(CMAKE_CXX_FLAGS_RELEASE "-O2") +# +# ADD_DEFINITIONS(-ansi -pedantic -Wall -Wno-long-long) +# ADD_EXECUTABLE(terra-server ${TERRA_SHARED_SOURCES} ${TERRA_SERVER_SOURCES} +# ${LUA_SOURCES} ${XML_SOURCES}) +# TARGET_LINK_LIBRARIES(terra-server) +# SET_TARGET_PROPERTIES(terra-server PROPERTIES +# OUTPUT_NAME ../../../terra-server) +# #LINK_FLAGS "-pg" +# #COMPILE_FLAGS "-pg") +# ELSEIF(MSVC) +# ADD_EXECUTABLE(terra-server ${TERRA_SHARED_SOURCES} ${TERRA_SERVER_SOURCES} +# ${TERRA_SDL_SOURCES} ${LUA_SOURCES} ${XML_SOURCES}) +# TARGET_LINK_LIBRARIES(terra-server) +# SET_TARGET_PROPERTIES(terra-server PROPERTIES +# OUTPUT_NAME ../../../../terra-server) +# ENDIF(UNIX OR MINGW) diff --git a/src/client/client.cpp b/src/client/client.cpp new file mode 100644 index 0000000..ac96821 --- /dev/null +++ b/src/client/client.cpp @@ -0,0 +1,137 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This pRight_ogram is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your opTop_ion) any later version. +// +// This pRight_ogram is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the impLeft_ied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this pRight_ogram; if not, write to the Free Software +// Foundation, Inc., 59 TempLeft_e Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file client.cpp + * + * blah. + */ + +// #ifdef PLATFORM_GCC +// # include +// # include +// #endif + +#include + +#include "vfs/logfile.h" + +#include "core/vmachine.h" +#include "core/script_core.h" +#include "renderer/renderer.h" +#include "renderer/canvas.h" +#include "input/input.h" + +#include "script_client.h" + +#include "client.h" + +namespace tre { + + GameClient::GameClient() + { + scriptVM_->InitModule(CoreInitializer()); + scriptVM_->InitModule(ClientInitializer()); + + scriptVM_->RunFile("script/init.lua"); + + luabind::object obj(scriptVM_->WrapObject(this)); + + running = scriptVM_->RunGlobalFunction("AppInit", &obj); + + timer.Start(); + } + + GameClient::~GameClient() + { + scriptVM_->RunGlobalFunction("AppEnd"); + } + + void GameClient::Run(void) + { + if(!desktop_) { + vLog << err("App") << "No gui loaded." << std::endl; + return; + } + + // the main "application" loop + while(running) { + sRenderer().NewFrame(); + desktop_->Draw(); + sRenderer().FlushFrame(); + + timer.UpdateTime(); + + ProcessInput(); + + scriptVM_->RunGlobalFunction("AppMain"); + +// #ifdef PLATFORM_GCC +// sched_yield(); +// #endif + + sRenderer().PresentFrame(); + } + + // dump rendering stats + vLog << info("Stats") + << "Batches: " << sRenderer().frame.batches << std::endl + << "Triangles: " << sRenderer().frame.triangles << std::endl + << "Time: " << sRenderer().frame.time << std::endl + << "Frames: " << sRenderer().frame.count << std::endl + << "Average FPS: " << sRenderer().frame.count / + (timer.GetTime() / 1000.0f) << std::endl; + } + + void GameClient::ProcessInput(void) + { + sInput().PumpEvents(); + + Vector2f delta(sInput().GetPositionChange()); + + // since may events are handled in lua, we must check for possible errors + try { + if(delta.x != 0.0f || delta.y != 0.0f) + desktop_->MouseMove(sInput().GetPosition(), delta); + + InputEvent event; + + while(event = sInput().GetNextEvent(), event.type != etNone) { + desktop_->ProcessInput(event); + } + } catch(luabind::error & e) { + luabind::object error_msg(luabind::from_stack(e.state(), -1)); + vLog << err("Script") << error_msg + << "\nin VirtualMachine::ProcessInput()." << std::endl; + } + } + + bool GameClient::SetDesktop + (const std::string & filename, const std::string & skin) + { + GuiPtr newgui = Gui::Factory().CreateInstance(*this, + Canvas::Factory().CreateInstance(), filename, skin); + + if(newgui) { + desktop_ = newgui; + return true; + } + return false; + } + +} diff --git a/src/client/client.h b/src/client/client.h new file mode 100644 index 0000000..5b4608d --- /dev/null +++ b/src/client/client.h @@ -0,0 +1,48 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file cursor.h + * + * Ble. + */ + +#pragma once + +#include "core/application.h" +#include "gui/gui.h" + +namespace tre { + + class GameClient : public Application { + public: + GameClient(); + ~GameClient(); + + void Run(void); + + void ProcessInput(void); + + GuiPtr GetDesktop(void) {return desktop_;} + bool SetDesktop(const std::string & filename, const std::string & skin); + + private: + GuiPtr desktop_; + }; + +} diff --git a/src/client/conf_client.cpp b/src/client/conf_client.cpp new file mode 100644 index 0000000..b0e8d2f --- /dev/null +++ b/src/client/conf_client.cpp @@ -0,0 +1,64 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file conf_client.cpp + * + * blahblah + */ + +#include "exception.h" + +#include "vfs/logfile.h" + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +#include "core/client/display.h" +#include "renderer/renderer.h" + +namespace tre { + + void InitClientConf(TiXmlElement & root) + { + // get the best video mode to serve as fallback + DisplayInfo info = sDisplay().GetDisplayInfo(); + + TiXmlElement * section = root.FirstChildElement("display"); + if(section) { + TiXmlElement * elem = section->FirstChildElement("width"); + if(elem) + info.width = CheckIntText(*elem); + + if((elem = section->FirstChildElement("height"))) + info.height = CheckIntText(*elem); + + if((elem = section->FirstChildElement("bpp"))) + info.bpp = CheckIntText(*elem); + + info.stereo = CheckIntAttribute(*section, "stereo", false) != 0; + info.fullscreen = CheckIntAttribute(*section, "fullscreen", false) != 0; + } else { + vLog << warn("Init") << "Missing display configuration, guessing." + << std::endl; + } + sDisplay().SetDisplayMode(info); + sRenderer().Init(); + } + +} diff --git a/src/client/conf_client.h b/src/client/conf_client.h new file mode 100644 index 0000000..d3285b5 --- /dev/null +++ b/src/client/conf_client.h @@ -0,0 +1,33 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file conf_client.h + * + * Ble. + */ + +#pragma once + +class TiXmlElement; + +namespace tre { + + void InitClientConf(TiXmlElement & root); + +} diff --git a/src/client/main.cpp b/src/client/main.cpp new file mode 100644 index 0000000..5b4373c --- /dev/null +++ b/src/client/main.cpp @@ -0,0 +1,130 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file client/main.cpp + * + * This file contains the main() function for the terra client. + * + * main() simply initializes few core subsystems, parses command line and + * executes the application instance. + */ + +#include + +#include "exception.h" + +#include "vfs/logfile.h" + +#include "client.h" + +#include "xml/tinyxml.h" + +const char * configPath = "config/client.xml"; + +namespace tre { + void InitCoreConf(TiXmlElement & el); + void InitClientConf(TiXmlElement & el); +} + +void ParseArguments(int argc, char * argv[]) +{ + for(int i = 1; i < argc; ++i) { + if(argv[i][0] == '-') { + switch(argv[i][1]) { + case 'c': // config path + if(i >= argc - 2) { + tre::vLog << tre::err("Init") + << "-c option requires one parameter." << std::endl; + exit(EXIT_FAILURE); + } + configPath = argv[i + 1]; + i += 2; + break; + default: + tre::vLog << tre::warn("Init") << "Unknown command line argument '" + << argv[i] << "'." << std::endl; + return; + } + } + } +} + +void LoadConfiguration(const char * path) +{ + try { + // open file + std::ifstream file(path); + if(!file.is_open()) + throw(Exception("Cannot open config file")); + + TiXmlDocument doc; + + if(!(file >> doc) || doc.Error()) + throw(Exception(doc.ErrorDesc())); + + TiXmlElement * section = doc.RootElement(); + DEBUG_ASSERT(section); + if(section->ValueTStr() != "config") + throw(Exception("Wrong root element")); + + tre::InitCoreConf(*section); + tre::InitClientConf(*section); + + tre::vLog << tre::ok("Init") + << "System initialized successfuly." << std::endl; + } catch(Exception & exc) { + tre::vLog << tre::err("Init") << "Unable to load configuration (" << path + << ")\nReason: " << exc.what() << "." << std::endl; + exit(EXIT_FAILURE); + } +} + +int main(int argc, char * argv[]) +{ + try { +#ifdef DEBUG + tre::vLog.AddOutput(tre::lfDefault, tre::ltCerr); +#endif /* DEBUG */ + + // check program arguments + ParseArguments(argc, argv); + + // load configuration + LoadConfiguration(configPath); + + // create and run the game instance + tre::GameClient client; + + client.Run(); + + } catch(std::exception & exc) { + tre::vLog << tre::err() << "Caught fatal exception: " + << exc.what() << "!" << std::endl + << tre::err() << "Program termination imminent!" << std::endl; + return 1; + } catch(...) { + tre::vLog << tre::err() << "Caught unhandled exception!" << std::endl + << tre::err() << "Program termination imminent!" << std::endl; + return 1; + } + + tre::vLog << tre::ok() << "Application finished successfully." << std::endl; + + return 0; +} diff --git a/src/client/script_client.cpp b/src/client/script_client.cpp new file mode 100644 index 0000000..92912eb --- /dev/null +++ b/src/client/script_client.cpp @@ -0,0 +1,126 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file script_client.cpp + * + * blahblah + */ + +#include "lua/lua.h" + +#include "luabind/luabind.hpp" + +#include "exception.h" + +#include "vfs/logfile.h" + +#include "core/client/display.h" +#include "renderer/renderer.h" + +#include "gui/gui.h" +#include "gui/widget.h" +#include "gui/basic.h" + +#include "client.h" +#include "script_client.h" +#include "core/script_core.h" + +namespace tre { + + namespace { + + void GlueDisplayListModes(lua_State* L, const Display & dsp) + { + using namespace luabind; + + const DInfoVector & lst = dsp.ListModes(); + + object res = newtable(L); + for(uint i = 0; i < lst.size(); ++i) { + res[i + 1] = lst[i]; + } + res.push(L); + } + + } + + void ClientInitializer::operator () (lua_State * L) const + { + using namespace luabind; + + module(L) + [ + // display interface + class_("DisplayInfo") + .def_readwrite("width", &DisplayInfo::width) + .def_readwrite("height", &DisplayInfo::height) + .def_readwrite("bpp", &DisplayInfo::bpp) + .def_readwrite("fullscreen", &DisplayInfo::fullscreen) + .def_readwrite("stereo", &DisplayInfo::stereo), + + class_("Display") + .def("GetDriverName", &Display::GetDriverName) + .def("GetDisplayInfo", &Display::GetDisplayInfo) + .def("ListModes", &GlueDisplayListModes, raw(_1)), + + def("Display", &sDisplay), + + // application + + class_("GameClient") + .def("GetDesktop", &GameClient::GetDesktop) + .def("SetDesktop", &GameClient::SetDesktop) + , + + // gui + class_("Gui") + .def("GetSize", &Gui::GetSize) +// .def("Resize", &Gui::Resize) + .def("GetRootWidget", (Widget*(Gui::*)(void))&Gui::GetRootWidget) + .def("GetRootWidget", (const Widget*(Gui::*)(void) const + )&Gui::GetRootWidget) + .def("FindWidget", (Widget*(Gui::*)(const std::string & name) + )&Gui::FindWidget) + .def("FindWidget", (const Widget*(Gui::*)(const std::string & name + ) const)&Gui::FindWidget) + .def("RegisterWidget", &Gui::RegisterWidget) + .def("UnregisterWidget", &Gui::RegisterWidget) + .def("ShowCursor", &Gui::ShowCursor) + .def("SetCursor", &Gui::SetCursor), + + class_("Widget") + .def_readonly("parent", &Widget::parent) + .def_readonly("children", &Widget::children) + .property("name", &Widget::GetName, &Widget::SetName) + .def_readwrite("visible", &Widget::visible) + .def("GetPostion", &Widget::GetPosition) + .def("GetAbsPostion", &Widget::GetAbsPosition) + .def("SetPosition", &Widget::SetPosition) + .def("GetSize", &Widget::GetSize) + .def("SetSize", &Widget::SetSize) + .def("Enable", &Widget::Enable) + .def("SetUserState", &Widget::SetUserState) +, + + class_("PushButton") + .property("caption", &PushButton::GetCaption, &PushButton::SetCaption) + ]; + } + +} diff --git a/src/client/script_client.h b/src/client/script_client.h new file mode 100644 index 0000000..d2ab231 --- /dev/null +++ b/src/client/script_client.h @@ -0,0 +1,41 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file script_client.h + * + * blahblah + */ + +#pragma once + +struct lua_State; + +class GameClient; + +namespace tre { + + class ClientInitializer { + public: + typedef lua_State * first_argument_type; + typedef void result_type; + + void operator () (lua_State * L) const; + }; + +} diff --git a/src/client/static.cpp b/src/client/static.cpp new file mode 100644 index 0000000..6ba658a --- /dev/null +++ b/src/client/static.cpp @@ -0,0 +1,40 @@ +// +// Copyright (C) 2007-2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file static.cpp + * + * Ensures that all static objects are initialized in the right order. + * + * @warning All static objects must be defined in this file for the support + * routines to work correctly. Instances of static classes not + * defined in this file may get initialized sooner and thus cause + * errors and exceptions on program's termination. + */ + +#include "vfs/init_logger.cpp" + +#include "memory/init_mmgr.cpp" + +#include "vfs/init_io.cpp" + +// register dynamic factories +#include "gui/init_basic.cpp" + +// init SDL +#include "core/init_sdl.cpp" diff --git a/src/core/application.cpp b/src/core/application.cpp new file mode 100644 index 0000000..e8d2a65 --- /dev/null +++ b/src/core/application.cpp @@ -0,0 +1,42 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This pRight_ogram is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your opTop_ion) any later version. +// +// This pRight_ogram is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the impLeft_ied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this pRight_ogram; if not, write to the Free Software +// Foundation, Inc., 59 TempLeft_e Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file application.cpp + * + * blah. + */ + +#include "core/application.h" +#include "core/vmachine.h" + +#include "memory/mmgr.h" + +namespace tre { + + Application::Application() + { + scriptVM_ = new VirtualMachine; + } + + Application::~Application() + { + delete scriptVM_; + } + +} diff --git a/src/core/client/display.cpp b/src/core/client/display.cpp new file mode 100644 index 0000000..d09a783 --- /dev/null +++ b/src/core/client/display.cpp @@ -0,0 +1,135 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file display.cpp + * + * blahblah + */ + +#include + +#include "assertion.h" +#include "exception.h" + +#include "vfs/logfile.h" + +#include "core/client/display.h" + +namespace tre { + + Display::Display() : fullscreen_(false), stereo_(false) + { + vLog << info("SDL") << "Initializing display..." << std::endl; + + // init SDL video + if(SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { + vLog << err("SDL") << "Unable to initialize SDL.\nReason: " + << SDL_GetError() << std::endl; + throw(Exception("Error intializing display")); + } + + vLog << ok("SDL") << "Success. Using driver: " + << GetDriverName() << std::endl; + } + + void Display::Init(void) + { + SetDisplayMode(GetDisplayInfo()); + } + + void Display::SetDisplayMode(const DisplayInfo & nfo) + { + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); + + // let's try to create a big depth buffer possible + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + + // disable the default SDL cursor + SDL_ShowCursor(0); + + Uint32 flags = SDL_OPENGL | SDL_HWSURFACE; + if(nfo.fullscreen) + flags |= SDL_FULLSCREEN; + if(nfo.stereo) + flags |= SDL_GL_STEREO; + + stereo_ = nfo.stereo; + fullscreen_ = nfo.fullscreen; + + vLog << info("SDL") << "New video mode: " << nfo.width << "x" + << nfo.height << "x" << nfo.bpp; + if(fullscreen_) + vLog << " [fullscreen]"; + if(stereo_) + vLog << " [stereo]"; + vLog << std::endl; + + if(!SDL_SetVideoMode(nfo.width, nfo.height, nfo.bpp, flags)) { + vLog << err("SDL") << "Unable to set requested video mode.\nReason: " + << SDL_GetError() << std::endl; + throw(Exception("Error intializing display")); + } + } + + const std::string Display::GetDriverName(void) const + { + char tmpstr[40]; + + DEBUG_ASSERT(SDL_VideoDriverName(tmpstr, 40)); + + return std::string(tmpstr); + } + + const DisplayInfo Display::GetDisplayInfo(void) const + { + const SDL_VideoInfo * info = SDL_GetVideoInfo(); + + DisplayInfo res; + res.width = info->current_w; + res.height = info->current_h; + res.bpp = info->vfmt->BitsPerPixel; + res.fullscreen = fullscreen_; + res.stereo = stereo_; + return res; + } + + const DInfoVector Display::ListModes(void) const + { + SDL_Rect ** modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); + + if(!modes) + return DInfoVector(); + + DisplayInfo info; + DInfoVector res; + + uint bits = GetDisplayInfo().bpp; + + for(uint i = 0; modes[i]; ++i) { + info.width = modes[i]->w; + info.height = modes[i]->h; + info.bpp = bits; + info.fullscreen = true; + info.stereo = false; + res.push_back(info); + } + return res; + } + +} diff --git a/src/core/conf_core.cpp b/src/core/conf_core.cpp new file mode 100644 index 0000000..63acb4a --- /dev/null +++ b/src/core/conf_core.cpp @@ -0,0 +1,52 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file conf_core.cpp + * + * blahblah + */ + +#include "vfs/interface.h" + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +namespace tre { + + void InitCoreConf(TiXmlElement & root) + { + std::string dir, path; + bool ro; + + TiXmlElement * section = root.FirstChildElement("vfs"); + if(section) { + TiXmlElement * elem = section->FirstChildElement("mount"); + while(elem) { + dir = CheckAttribute(*elem, "dir"); + path = CheckAttribute(*elem, "path"); + ro = CheckIntAttribute(*elem, "readonly", false, 1) != 0; + + sVfs().MountPath(path, dir, ro); + + elem = elem->NextSiblingElement("mount"); + } + } + } + +} diff --git a/src/core/script_core.cpp b/src/core/script_core.cpp new file mode 100644 index 0000000..8ed7855 --- /dev/null +++ b/src/core/script_core.cpp @@ -0,0 +1,94 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file script_core.cpp + * + * blahblah + */ + +#include "lua/lua.h" + +#include "luabind/luabind.hpp" +#include "luabind/operator.hpp" +#include "luabind/return_reference_to_policy.hpp" + +#include "exception.h" + +#include "core/application.h" +#include "core/timer.h" +#include "vfs/interface.h" +#include "vfs/logfile.h" + +#include "core/script_core.h" + +namespace tre { + + void CoreInitializer::operator () (lua_State * L) const + { + using namespace luabind; + + // register GameClient class + module(L) + [ + class_("Timer") + .def("ScheduleAction", &Timer::ScheduleAction) + .def("RemoveAction", &Timer::RemoveAction) + .def("GetSystemTime", &Timer::GetSystemTime), + + class_("Application") + .def("Quit", &Application::Quit) + .def_readonly("timer", &Application::timer), + + // math classes + class_ >("vec2") + .def(constructor()) + .def(self + other >()) + .def(self - other >()) + .def(self * float()) + .def(self / float()) + .def(self == other >()) + .def("add", &Vector2::operator+=, return_reference_to(_1)) + .def("sub", &Vector2::operator-=, return_reference_to(_1)) + .def("mul", &Vector2::operator*=, return_reference_to(_1)) + .def("div", &Vector2::operator/=, return_reference_to(_1)) + .def("len", &Vector2::Length) + .def("normalize", &Vector2::Normalize) + .def_readwrite("x", &Vector2::x) + .def_readwrite("y", &Vector2::y), + + class_ >("vec3") + .def(constructor()) + .def(self + other >()) + .def(self - other >()) + .def(self * float()) + .def(self / float()) + .def(self == other >()) + .def("add", &Vector3::operator+=, return_reference_to(_1)) + .def("sub", &Vector3::operator-=, return_reference_to(_1)) + .def("mul", &Vector3::operator*=, return_reference_to(_1)) + .def("div", &Vector3::operator/=, return_reference_to(_1)) + .def("len", &Vector3::Length) + .def("normalize", &Vector3::Normalize) + .def_readwrite("x", &Vector3::x) + .def_readwrite("y", &Vector3::y) + .def_readwrite("z", &Vector3::z) + ]; + } + +} diff --git a/src/core/timer.cpp b/src/core/timer.cpp new file mode 100644 index 0000000..4a70996 --- /dev/null +++ b/src/core/timer.cpp @@ -0,0 +1,108 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file timer.cpp + * + * Ble. + */ + +#include + +#include + +#include "vfs/logfile.h" +#include "core/timer.h" + +#include "memory/mmgr.h" + +namespace tre { + + uint32 Timer::GetSystemTime(void) + { + return SDL_GetTicks(); + } + + Timer::Timer() : time_(0), running_(false) + { + } + + void Timer::UpdateTime(void) + { + if(!running_) + return; + + uint tmp_time = GetSystemTime(); + uint time_step = tmp_time - lastTime_; + lastTime_ = tmp_time; + + if(mod > 0.0f) + time_step = static_cast(time_step) * mod; + + time_ += time_step; + + while(!actions_.empty() && actions_.front().first < time_) { + DEBUG_ASSERT(actions_.front().second != 0); + DEBUG_ASSERT(*actions_.front().second != 0); + (*actions_.front().second)(); + actions_.pop_front(); + } + } + + void Timer::Start(void) + { + lastTime_ = GetSystemTime(); + running_ = true; + } + + void Timer::Stop(void) + { + running_ = false; + } + + const Timer::TimerAction * Timer::ScheduleAction + (uint ms, const TimerAction & act) + { + if(!act) { + vLog << warn("Timer") + << "Attempting to register invalid callback!" << std::endl; + return NULL; + } + ActionQueue::iterator pos = std::lower_bound( + actions_.begin(), actions_.end(), ms); + + TimerAction * res = new TimerAction(act); + + actions_.insert(pos, std::make_pair(time_ + ms, res)); + + return res; + } + + bool Timer::RemoveAction(const TimerAction * act) + { + for(ActionQueue::iterator pos = actions_.begin(); + pos != actions_.end(); ++pos) { + if(pos->second == act) { + actions_.erase(pos); + return true; + } + } + return false; + } + +} diff --git a/src/core/vmachine.cpp b/src/core/vmachine.cpp new file mode 100644 index 0000000..61387fb --- /dev/null +++ b/src/core/vmachine.cpp @@ -0,0 +1,233 @@ +// +// Copyright (C) 2007 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file vmachine.cpp + * + * blahblahblah + * + */ + +#include "exception.h" + +#include "vfs/logfile.h" + +#include "core/application.h" +#include "core/vmachine.h" + +#include "lua/lua.h" +#include "lua/lualib.h" +#include "lua/lauxlib.h" + +// #include "luabind/luabind.hpp" + +namespace tre { + + /* + * Virtual machine helper lua functions + */ + + static lua_State * vm_GetThread (lua_State *L, int *arg); + static int vm_Traceback(lua_State * L); + + // must be exported because of ScriptAction + int vm_ErrorHandler(lua_State * L); + + static lua_State * vm_GetThread (lua_State *L, int *arg) + { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } + } + + #define LEVELS1 12 /* size of the first part of the stack */ + #define LEVELS2 10 /* size of the second part of the stack */ + + static int vm_Traceback(lua_State * L) + { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = vm_GetThread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg + 2)) { + level = (int)lua_tointeger(L, arg + 2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg + 1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level + LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level + LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; + } + + #undef LEVELS1 + #undef LEVELS2 + + int vm_ErrorHandler(lua_State * L) + { + std::string message; + + if(lua_isstring(L, -1)) { + message = luaL_checkstring(L, -1); + } + + lua_pop(L, 1); + + vm_Traceback(L); + + if(lua_isstring(L, -1)) { + message.push_back('\n'); + message += luaL_checkstring(L, -1); + } + + lua_pushstring(L, message.c_str()); + return 1; + } + + /* + * VirtualMachine implementation + */ + + VirtualMachine::VirtualMachine(bool libs/*=true*/) + { + luaState_ = lua_open(); + + if (luaState_ == NULL) + throw(Exception("Unable to initialize Lua")); + + // initialize lua standard library functions + if(libs) + luaL_openlibs(luaState_); + + // prepare state for registering new modules with luabind +// luabind::open(luaState_); + + // default error handler for Cpp<->Lua communication +// luabind::set_pcall_callback(vm_ErrorHandler); + } + + VirtualMachine::~VirtualMachine() + { + lua_close(luaState_); + } + + bool VirtualMachine::RunFile(const std::string & filename) + { + int res = luaL_dofile(luaState_, filename.c_str()); + if(res != 0) { + if(lua_isstring(luaState_, -1)) { + vLog << tre::err("Script") + << luaL_checkstring(luaState_, -1) << std::endl; + } + return false; + } + // clear the stack + lua_pop(luaState_, lua_gettop(luaState_)); + return true; + } + + bool VirtualMachine::RunString(const std::string & str) + { + int res = luaL_dostring(luaState_, str.c_str()); + if(res != 0) { + if(lua_isstring(luaState_, -1)) { + vLog << tre::err("Script") + << luaL_checkstring(luaState_, -1) << std::endl; + } + return false; + } + // clear the stack + lua_pop(luaState_, lua_gettop(luaState_)); + return true; + } + + bool VirtualMachine::RunGlobalFunction(const std::string & str, luabind::object * arg/*=NULL*/) + { + try { + if(arg) + luabind::call_function(luaState_, str.c_str(), *arg); + else + luabind::call_function(luaState_, str.c_str()); + } catch(luabind::error & e) { + luabind::object error_msg(luabind::from_stack(e.state(), -1)); + vLog << err("Script") << error_msg + << "\nin VirtualMachine::RunGlobalFunction(" + << str << ")." << std::endl; + return false; + } + return true; + } + + const luabind::object VirtualMachine::CompileScriptChunk + (const std::string & chunk, const std::string & name) + { + luaL_loadbuffer(luaState_, chunk.c_str(), chunk.size(), name.c_str()); + if(lua_isstring(luaState_, -1)) { + vLog << err("Script") << "Error compiling chunk '" << name << "'.\n" + << "Reason: " << luaL_checkstring(luaState_, -1) << std::endl; + lua_pop(luaState_, 1); + return luabind::object(); + } + + luabind::object res(luabind::from_stack(luaState_, -1)); + lua_pop(luaState_, 1); + + return res; + } +} diff --git a/src/gui/basic.cpp b/src/gui/basic.cpp new file mode 100644 index 0000000..6655b98 --- /dev/null +++ b/src/gui/basic.cpp @@ -0,0 +1,746 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This pRight_ogram is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your opTop_ion) any later version. +// +// This pRight_ogram is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the impLeft_ied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this pRight_ogram; if not, write to the Free Software +// Foundation, Inc., 59 TempLeft_e Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file basic.cpp + * + * Provides collection of basic widgets. + */ + +#include +#include + +#include "utf8.h" +#include "exception.h" + +#include "vfs/logfile.h" + +#include "input/input.h" +#include "renderer/renderer.h" + +#include "core/application.h" +#include "core/vmachine.h" + +#include "gui/font/font.h" + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +#include "gui/gui.h" +#include "gui/basic.h" + +#include "skin.h" + +#include "memory/mmgr.h" + +namespace tre { + + /* + * Utility functions + */ + namespace { + + void LoadTextFromXml(PlainText & text, + TiXmlElement & root, const GuiSkinPtr & skin) + { + DEBUG_ASSERT(skin); + const GuiSkin::TextDefaults & defs = skin->GetTextDefaults(); + + // load effect (with fallback) + TiXmlElement * elem = root.FirstChildElement("effect"); + if(elem) + text.SetEffect(CheckText(*elem)); + else if(!defs.effect.empty()) + text.SetEffect(defs.effect); + else + throw(Exception("Missing effect information")); + + if((elem = root.FirstChildElement("font"))) + text.SetFont(CheckText(*elem)); + else if(!defs.font.empty()) + text.SetFont(defs.font); + else + throw(Exception("Missing font information")); + + TextStyle style = defs.plainStyle; + + if((elem = root.FirstChildElement("style"))) { + TiXmlElement * subel = elem->FirstChildElement("size"); + if(subel) + style.size = CheckIntText(*subel); + + if((subel = elem->FirstChildElement("fontStyle"))) { + std::string tmpstr(CheckText(*subel)); + if(tmpstr == "regular") { + style.fstyle = fsRegular; + } else if(tmpstr == "bold") { + style.fstyle = fsBold; + } else if(tmpstr == "italic") { + style.fstyle = fsItalic; + } else if(tmpstr == "boldItalic") { + style.fstyle = fsBoldItalic; + } else { + throw(Exception("Unknown font style")); + } + } + if((subel = elem->FirstChildElement("colour"))) { + style.colour.Set(CheckFloatAttribute(*subel, "r"), + CheckFloatAttribute(*subel, "g"), + CheckFloatAttribute(*subel, "b"), + CheckFloatAttribute(*subel, "a", false, 1.0f)); + } + } + text.SetStyle(style); + + if((elem = root.FirstChildElement("text"))) { + if(elem->Attribute("size")) { + style.size = CheckIntAttribute(*elem, "size", + false, Font::defTextSize); + } + text.SetStyle(style); + + bool aa = CheckIntAttribute(*elem, "smooth", false, 1) != 0; + text.SetAntialias(aa); + + std::string tmp_text(CheckText(*elem, false)); + std::wstring tmp_wtext; + + tmp_wtext.reserve(tmp_text.size()); + utf8::utf8to16(tmp_text.begin(), tmp_text.end(), + std::back_inserter(tmp_wtext)); + + text.SetText(tmp_wtext); + } + } + + void LoadRichTextFromXml(RichText & text, + TiXmlElement & root, const GuiSkinPtr & skin) + { + DEBUG_ASSERT(skin); + const GuiSkin::TextDefaults & defs = skin->GetTextDefaults(); + + // load effect (with fallback) + TiXmlElement * elem = root.FirstChildElement("effect"); + if(elem) + text.SetEffect(CheckText(*elem)); + else if(!defs.effect.empty()) + text.SetEffect(defs.effect); + else + throw(Exception("Missing effect information")); + + if((elem = root.FirstChildElement("font"))) + text.SetFont(CheckText(*elem)); + else if(!defs.font.empty()) + text.SetFont(defs.font); + else + throw(Exception("Missing font information")); + + TextStyle styles[ssLast]; + StyleSheet sheet; + std::string tmpstr; + + for(int i = 0; i < ssLast; ++i) { + styles[i] = defs.richStyles[i]; + } + + // parse all style elements + elem = root.FirstChildElement("style"); + while(elem) { + // determine style type (name) + tmpstr = CheckAttribute(*elem, "type"); + if(tmpstr == "base") { + sheet = ssBase; + } else if(tmpstr == "link") { + sheet = ssLink; + } else if(tmpstr == "linkHover") { + sheet = ssLinkHover; + } else if(tmpstr == "linkPressed") { + sheet = ssLinkPressed; + } else if(tmpstr == "emph") { + sheet = ssEmph; + } else { + throw(Exception("Unknown style sheet")); + } + + TiXmlElement * subel = elem->FirstChildElement("size"); + if(subel) { + styles[sheet].size = CheckIntText(*subel); + } + + if((subel = elem->FirstChildElement("fontStyle"))) { + tmpstr = CheckText(*subel); + if(tmpstr == "regular") { + styles[sheet].fstyle = fsRegular; + } else if(tmpstr == "bold") { + styles[sheet].fstyle = fsBold; + } else if(tmpstr == "italic") { + styles[sheet].fstyle = fsItalic; + } else if(tmpstr == "boldItalic") { + styles[sheet].fstyle = fsBoldItalic; + } else { + throw(Exception("Unknown font style")); + } + } + + if((subel = elem->FirstChildElement("colour"))) { + styles[sheet].colour.Set(CheckFloatAttribute(*subel, "r"), + CheckFloatAttribute(*subel, "g"), + CheckFloatAttribute(*subel, "b"), + CheckFloatAttribute(*subel, "a", false, 1.0f)); + } + elem = elem->NextSiblingElement("style"); + } + + for(int i = 0; i < ssLast; ++i) { + text.SetStyleSheet(static_cast(i), styles[i]); + } + + if((elem = root.FirstChildElement("text"))) { + if(elem->Attribute("size")) { + styles[ssBase].size = CheckIntAttribute(*elem, + "size", false, Font::defTextSize); + text.SetStyleSheet(ssBase, styles[ssBase]); + } + + if(elem->Attribute("halign")) { + tmpstr = CheckAttribute(*elem, "halign"); + if(tmpstr == "left") { + text.SetHAlign(haLeft); + } else if(tmpstr == "center") { + text.SetHAlign(haCenter); + } else if(tmpstr == "right") { + text.SetHAlign(haRight); + } else if(tmpstr == "stretch") { + text.SetHAlign(haStretch); + } else { + throw(Exception("Unknown horizontal alignment")); + } + } + + if(elem->Attribute("valign")) { + tmpstr = CheckAttribute(*elem, "valign"); + if(tmpstr == "top") { + text.SetVAlign(vaTop); + } else if(tmpstr == "middle") { + text.SetVAlign(vaMiddle); + } else if(tmpstr == "bottom") { + text.SetVAlign(vaBottom); + } else { + throw(Exception("Unknown vertical alignment")); + } + } + + bool aa = CheckIntAttribute(*elem, "smooth", false, 1) != 0; + text.SetAntialias(aa); + + bool wr = CheckIntAttribute(*elem, "wrap", false, 1) != 0; + text.SetWrap(wr); + + text.SetText(CheckText(*elem, false)); + } + } + + } + + AbstractStatic::AbstractStatic(Gui & g, Widget * p) + { + Init(g, p); + } + + /* + * Abstract button + */ + AbstractButton::AbstractButton(Gui & g, Widget * p) + { + Init(g, p); + } + + class AbstractButton::OnButtonPressed { + public: + OnButtonPressed(AbstractButton & p) : par_(p) {} + + void operator () (uint id); + private: + AbstractButton & par_; + }; + + class AbstractButton::OnButtonReleased { + public: + OnButtonReleased(AbstractButton & p) : par_(p) {} + + void operator () (uint id); + private: + AbstractButton & par_; + }; + + void AbstractButton::OnMouseEnter() + { + DEBUG_ASSERT(gui_); + + // connect onButton slot + buttonCon1 = gui_->buttonOn.connect(OnButtonPressed(*this)); + + if(wstate_ != wsPressed) + Widget::OnMouseEnter(); + } + + void AbstractButton::OnMouseExit() + { + // connect onButton slot + buttonCon1.disconnect(); + + if(wstate_ != wsPressed) + Widget::OnMouseExit(); + } + + void AbstractButton::OnButtonPressed::operator () (uint id) + { + DEBUG_ASSERT(par_.gui_); + + // left mouse button + if(id == 0) { + par_.SetState(par_.ustate_, wsPressed); + par_.buttonCon2 = par_.gui_->buttonOff.connect(OnButtonReleased(par_)); + } + if(par_.parent) + par_.parent->RaiseChild(&par_); + } + + void AbstractButton::OnButtonReleased::operator () (uint id) + { + DEBUG_ASSERT(par_.gui_); + + // left mouse button + if(id == 0) { + Vector3f pos = par_.gui_->GetMousePosition(); + if(par_.IsInRegion(Vector2f(pos.x, pos.y))) { + par_.SetState(par_.ustate_, wsHover); + par_.clicked(); + } else { + par_.SetState(par_.ustate_, wsNormal); + } + + par_.buttonCon2.disconnect(); + } + } + + /* + * Abstract edit box + */ + AbstractEdit::AbstractEdit(Gui & g, Widget * p) + { + Init(g, p); + } + + class AbstractEdit::OnButtonPressed { + public: + OnButtonPressed(AbstractEdit & p) : par_(p) {} + + void operator () (uint id); + private: + AbstractEdit & par_; + }; + + class AbstractEdit::OnKeyPressed { + public: + OnKeyPressed(AbstractEdit & p) : par_(p) {} + + bool operator () (char chr, KeySym sym); + private: + AbstractEdit & par_; + }; + + void AbstractEdit::OnMouseEnter() + { + DEBUG_ASSERT(gui_); + + // connect onButton slot + buttonCon = gui_->buttonOn.connect(OnButtonPressed(*this)); + + Widget::OnMouseEnter(); + } + + void AbstractEdit::OnButtonPressed::operator () (uint id) + { + DEBUG_ASSERT(par_.gui_); + + // if clicked outside, lose focus + Vector3f pos = par_.gui_->GetMousePosition(); + if(!par_.IsInRegion(Vector2f(pos.x, pos.y))) { + par_.SetUserState(0); + par_.keyCon.disconnect(); + par_.buttonCon.disconnect(); + return; + } + // left mouse button + if(id == 0) { + // set focus + par_.SetUserState(1); + par_.keyCon = par_.gui_->keyOn.connect(OnKeyPressed(par_)); + } + if(par_.parent) + par_.parent->RaiseChild(&par_); + } + + bool AbstractEdit::OnKeyPressed::operator () (char chr, KeySym sym) + { + if(chr == 0) + return false; + + par_.InsertCharacter(chr); + return true; + } + + /* + * Static text widget + */ + Widget * StaticText::CreateWidget(Gui & gui, Widget * parent) + { + return new StaticText(gui, parent); + } + + StaticText::StaticText(Gui & g, Widget * p) + { + Init(g, p); + + text.SetTransform(&trans_.GetWTransform()); + text.SetScaleFactor(g.GetScaleFactor()); + } + + void StaticText::OnGuiResize(const Vector2f & scale) + { + text.SetScaleFactor(scale); + } + + void StaticText::Draw(void) + { + GeometryBatch & batch = text.GetGeometry(); + + if(!batch.empty()) { + sRenderer().DrawGeometry(batch.begin(), batch.end()); + } + } + + void StaticText::LoadFromXml(TiXmlElement & root) + { + DEBUG_ASSERT(gui_); + + Widget::LoadFromXml(root); + + text.SetRect(size_.x, size_.y); + + LoadTextFromXml(text, root, gui_->GetSkin()); + } + + Widget * StaticRichText::CreateWidget(Gui & gui, Widget * parent) + { + return new StaticRichText(gui, parent); + } + + StaticRichText::StaticRichText(Gui & g, Widget * p) + { + Init(g, p); + + text.SetTransform(&trans_.GetWTransform()); + text.SetScaleFactor(g.GetScaleFactor()); + } + + void StaticRichText::OnGuiResize(const Vector2f & scale) + { + text.SetScaleFactor(scale); + } + + void StaticRichText::Draw(void) + { + GeometryBatch & batch = text.GetGeometry(); + + if(!batch.empty()) { + sRenderer().DrawGeometry(batch.begin(), batch.end()); + } + } + + void StaticRichText::LoadFromXml(TiXmlElement & root) + { + DEBUG_ASSERT(gui_); + + Widget::LoadFromXml(root); + + text.SetRect(size_.x, size_.y); + + LoadRichTextFromXml(text, root, gui_->GetSkin()); + } + + /* + * Basic pixmap widget + */ + PixmapWidget::~PixmapWidget() + { + delete pixmap_; + } + + void PixmapWidget::OnGuiResize(const Vector2f & scale) + { + pixmap_->SetScaleFactor(scale); + pixmap_->ResizePixmap(size_); + } + + void PixmapWidget::SetSize(const Vector2f & sz) + { + DEBUG_ASSERT(pixmap_); + + if(sz != size_) { + Widget::SetSize(sz); + pixmap_->ResizePixmap(sz); + } + } + + void PixmapWidget::Draw(void) + { + DEBUG_ASSERT(pixmap_); + + pixmap_->DrawPixmap(); + + // draw children + DrawChildren(); + } + + void PixmapWidget::SetState(uint u, WidgetState w) + { + // no change + if(u == ustate_ && w == wstate_) + return; + + ustate_ = u; + wstate_ = w; + + pixmap_->SetMap(ustate_, wstate_); + } + + /* + * Basic widgets + */ + + /* + * Frame and it's variants + */ + Widget * Frame::CreateWidget(Gui & gui, Widget * parent) + { + return new Frame(gui, parent); + } + + Frame::Frame(Gui & g, Widget * p) : AbstractStatic(g, p), + PixmapWidget(new Pixmap3x3(trans_, g.GetScaleFactor().y)) + { + } + + void Frame::LoadFromXml(TiXmlElement & root) + { + DEBUG_ASSERT(gui_); + + Widget::LoadFromXml(root); + + pixmap_->LoadFromXmlTemplate(root, gui_->GetSkin(), "frame-plain", size_); + pixmap_->SetMap(ustate_, wstate_); + + LoadChildrenFromXml(root); + } + + Widget * FrameRaised::CreateWidget(Gui & gui, Widget * parent) + { + return new FrameRaised(gui, parent); + } + + void FrameRaised::LoadFromXml(TiXmlElement & root) + { + DEBUG_ASSERT(gui_); + + Widget::LoadFromXml(root); + + pixmap_->LoadFromXmlTemplate(root, gui_->GetSkin(), "frame-raised", size_); + pixmap_->SetMap(ustate_, wstate_); + + LoadChildrenFromXml(root); + } + + Widget * FrameSunken::CreateWidget(Gui & gui, Widget * parent) + { + return new FrameSunken(gui, parent); + } + + void FrameSunken::LoadFromXml(TiXmlElement & root) + { + DEBUG_ASSERT(gui_); + + Widget::LoadFromXml(root); + + pixmap_->LoadFromXmlTemplate(root, gui_->GetSkin(), "frame-sunken", size_); + pixmap_->SetMap(ustate_, wstate_); + + LoadChildrenFromXml(root); + } + + /* + * Push button + */ + Widget * PushButton::CreateWidget(Gui & gui, Widget * parent) + { + return new PushButton(gui, parent); + } + + PushButton::PushButton(Gui & g, Widget * p) : AbstractButton(g, p), + PixmapWidget(new Pixmap3x1(trans_, g.GetScaleFactor().y)) + { + caption_.SetTransform(&trans_.GetWTransform()); + caption_.SetScaleFactor(g.GetScaleFactor()); + } + + class PushButton::EventBinder { + public: + EventBinder(PushButton & p, const luabind::object & o) + : par_(&p), func_(o) {} + + void operator () (void) {func_(par_);} + private: + PushButton * par_; + luabind::object func_; + }; + + void PushButton::OnGuiResize(const Vector2f & scale) + { + PixmapWidget::OnGuiResize(scale); + + caption_.SetScaleFactor(scale); + } + + void PushButton::SetSize(const Vector2f & sz) + { + PixmapWidget::SetSize(Vector2f(sz.x, size_.y)); + } + + void PushButton::Draw(void) + { + PixmapWidget::Draw(); + + GeometryBatch & batch = caption_.GetGeometry(); + + if(!batch.empty()) + sRenderer().DrawGeometry(batch.begin(), batch.end()); + } + + void PushButton::LoadFromXml(TiXmlElement & root) + { + DEBUG_ASSERT(gui_); + + Widget::LoadFromXml(root); + + pixmap_->LoadFromXmlTemplate(root, gui_->GetSkin(), "push_button", size_); + pixmap_->SetMap(ustate_, wstate_); + + size_.y = static_cast(pixmap_)->GetHeight(); + + caption_.SetRect(size_.x, size_.y); + caption_.SetHAlign(haCenter); + caption_.SetVAlign(vaMiddle); + + TiXmlElement * elem = root.FirstChildElement("caption"); + if(elem) + LoadTextFromXml(caption_, *elem, gui_->GetSkin()); + + // compile and register events + elem = root.FirstChildElement("event"); + while(elem) { + if(CheckAttribute(*elem, "id") == "clicked") { + luabind::object obj(gui_->GetApplication().GetScriptVM( + )->CompileScriptChunk(CheckText(*elem), "PushButton::clicked()")); + + if(obj.is_valid()) { + clicked.connect(EventBinder(*this, obj)); + } + } + elem = elem->NextSiblingElement("event"); + } + } + + /* + * Edit box + */ +// EditBox::EditBox(Gui & g, Widget * p) : Pixmap3x1(g, p) +// { +// } +// +// EditBox::EditBox(Gui & g, Widget * p, Mesh & pm) : Pixmap3x1(g, p, pm) +// { +// } +// +// void EditBox::LoadFromXml(TiXmlElement & root) +// { +// LoadFromXmlTemplate(root, "edit box"); +// } + + /* + * Check box + */ +// CheckBox::CheckBox(Gui & g, Widget * p) : Pixmap1x1(g, p) +// { +// } +// +// CheckBox::CheckBox(Gui & g, Widget * p, Mesh & pm) : Pixmap1x1(g, p, pm) +// { +// } +// +// void CheckBox::LoadFromXml(TiXmlElement & root) +// { +// LoadFromXmlTemplate(root, "check box"); +// } + + /* + * Radio button + */ + +// RadioButton::RadioButton(Gui & g, Widget * p) : Pixmap1x1(g, p) +// { +// } +// +// RadioButton::RadioButton(Gui & g, Widget * p, Mesh & pm) +// : Pixmap1x1(g, p, pm) +// { +// } +// +// void RadioButton::LoadFromXml(TiXmlElement & root) +// { +// LoadFromXmlTemplate(root, "radio button"); +// } + + /* + * Drop-down list + */ +// DropDownList::DropDownList(Gui & g, Widget * p) : Pixmap3x1(g, p) +// { +// } +// +// DropDownList::DropDownList(Gui & g, Widget * p, Mesh & pm) +// : Pixmap3x1(g, p, pm) +// { +// } +// +// void DropDownList::LoadFromXml(TiXmlElement & root) +// { +// LoadFromXmlTemplate(root, "drop down"); +// } + +} diff --git a/src/gui/cursor.cpp b/src/gui/cursor.cpp new file mode 100644 index 0000000..c1e9ca1 --- /dev/null +++ b/src/gui/cursor.cpp @@ -0,0 +1,237 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file cursor.cpp + * + * blahblah + */ + +#include + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +#include "vfs/fstream.h" +#include "vfs/logfile.h" + +#include "exception.h" +#include "cursor.h" + +namespace tre { + + /* + * Cursor class implementation + */ + void Cursor::Rescale(const Vector2f & scale, Float2Vector & verts) + { + DEBUG_ASSERT(indices); + + verts[indices->vFrom].Set(0.0f, baseSize_.y * scale.y); + verts[indices->vFrom + 1].Set(baseSize_.x * scale.x, baseSize_.y * scale.y); + verts[indices->vFrom + 2].Set(baseSize_.x * scale.x, 0.0f); + verts[indices->vFrom + 3].Set(0.0f, 0.0f); + } + + void Cursor::LoadFromXml(TiXmlElement & root, const Vector2f & scale, + Float2Vector & verts, Float2Vector & coords) + { + uint offset = verts.size(); + + TiXmlElement * elem = root.FirstChildElement("effect"); + if(!elem) + throw(Exception("Missing effect information")); + + effect = Effect::Factory().CreateInstance(CheckText(*elem)); + + elem = root.FirstChildElement("texture"); + if(!elem) + throw(Exception("Missing texture information")); + + vars.SetTexture("gui_Texture", CheckText(*elem)); + + elem = root.FirstChildElement("rect"); + if(!elem) + throw(Exception("Missing rectangle information")); + + float tex_scale = CheckFloatAttribute(*elem, "scale", false, 1.0f); + + float left = CheckFloatAttribute(*elem, "left"); + float right = CheckFloatAttribute(*elem, "right"); + float bottom = CheckFloatAttribute(*elem, "bottom"); + float top = CheckFloatAttribute(*elem, "top"); + + baseSize_.x = right - left; + baseSize_.y = top - bottom; + + baseOffset_ = 0.0f; + elem = root.FirstChildElement("offset"); + if(elem) { + baseOffset_.x = CheckFloatAttribute(*elem, "x", false, 0.0f); + baseOffset_.y = CheckFloatAttribute(*elem, "y", false, 0.0f); + } + + left /= tex_scale; + right /= tex_scale; + top /= tex_scale; + bottom /= tex_scale; + + coords.push_back(Vector2f(left, top)); + coords.push_back(Vector2f(left, bottom)); + coords.push_back(Vector2f(right, top)); + coords.push_back(Vector2f(right, bottom)); + + elem = root.FirstChildElement("scale"); + if(elem) { + baseSize_.x *= CheckFloatAttribute(*elem, "x", false, 1.0f); + baseOffset_.x *= CheckFloatAttribute(*elem, "x", false, 1.0f); + baseSize_.y *= CheckFloatAttribute(*elem, "y", false, 1.0f); + baseOffset_.y *= CheckFloatAttribute(*elem, "y", false, 1.0f); + } + + indices = IndexBufPtr(IndexBuffer::Factory().CreateInstance()); + indices->vFrom = verts.size(); + + verts.push_back(Vector2f(baseOffset_.x * scale.x, + baseOffset_.y * scale.y)); + verts.push_back(Vector2f(baseOffset_.x * scale.x, + (baseSize_.y + baseOffset_.y) * scale.y)); + verts.push_back(Vector2f((baseSize_.x + baseOffset_.x) * scale.x, + baseOffset_.y * scale.y)); + verts.push_back(Vector2f((baseSize_.x + baseOffset_.x) * scale.x, + (baseSize_.y + baseOffset_.y) * scale.y)); + + indices->vTo = verts.size(); + + uint inds[] = {offset + 1, offset + 3, offset + 2, + offset + 1, offset + 2, offset}; + + indices->Init(6); + uint * ptr = indices->Lock(); + DEBUG_ASSERT(ptr); + memcpy(ptr, inds, sizeof(uint) * 6); + indices->Unlock(); + indices->vFrom = 0; + indices->vTo = 6; + } + + /* + * CursorSetFactory class implementation + */ + const CursorSetPtr CursorSetFactory::CreateInstance + (const std::string & filename, const Vector2f & scale) + { + CursorMap::iterator pos = cursorMap_.find(filename); + + if(pos != cursorMap_.end() && !pos->second.expired()) { + return pos->second.lock(); + } + + CursorSetPtr newset; + + try { + FileIStream file(filename.c_str()); + if(!file.is_open()) + throw(Exception("Cannot open GUI cursor file")); + + TiXmlDocument doc; + + if(!(file >> doc) || doc.Error()) + throw(Exception(doc.ErrorDesc())); + + TiXmlElement * section = doc.RootElement(); + DEBUG_ASSERT(section); + if(section->ValueTStr() != "cursorSet") + throw(Exception("Wrong root element")); + + newset = CursorSetPtr(new CursorSet); + newset->LoadFromXml(*section, scale); + } catch(Exception & exc) { + vLog << err("Gui") << "Error loading cursor set (" << filename + << ")\nReason: " << exc.what() << "." << std::endl; + return CursorSetPtr(); + } + + cursorMap_[filename] = newset; + return newset; + } + + const CursorSetPtr CursorSetFactory::CreateInstance + (TiXmlElement & root, const Vector2f & scale) + { + CursorSetPtr newset; + + newset = CursorSetPtr(new CursorSet); + newset->LoadFromXml(root, scale); + + return newset; + } + + /* + * CursorSet class implementation + */ + const Cursor * CursorSet::GetCursor(const std::string & name) const + { + CursorVector::const_iterator pos = std::lower_bound( + cursors_.begin(), cursors_.end(), name); + + if(pos == cursors_.end() || pos->first != name) + return NULL; + + return &pos->second; + } + + void CursorSet::OnGuiResize(const Vector2f & scale) + { + Float2Vector verts; + verts.resize(bufSize_); + + for(CursorVector::iterator itr = cursors_.begin(); + itr != cursors_.end(); ++itr) { + itr->second.Rescale(scale, verts); + } + + if(!verts.empty()) + attribs_->Set(atPosition, verts); + } + + void CursorSet::LoadFromXml(TiXmlElement & root, const Vector2f & scale) + { + attribs_ = AttribBufPtr(AttribBufferSet::Factory().CreateInstance()); + Float2Vector verts, coords; + + TiXmlElement * elem = root.FirstChildElement("cursor"); + while(elem) { + cursors_.push_back(std::make_pair(CheckAttribute(*elem, "id"), Cursor())); + cursors_.back().second.attribs = attribs_; + cursors_.back().second.LoadFromXml(*elem, scale, verts, coords); + + elem = elem->NextSiblingElement("cursor"); + } + std::sort(cursors_.begin(), cursors_.end()); + + bufSize_ = verts.size(); + + // if there's at least one cursor, create buffers + if(bufSize_) { + attribs_->Set(atPosition, verts); + attribs_->Set(atTexCoord0, coords); + } + } + +} diff --git a/src/gui/cursor.h b/src/gui/cursor.h new file mode 100644 index 0000000..8398a62 --- /dev/null +++ b/src/gui/cursor.h @@ -0,0 +1,113 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file cursor.h + * + * Ble. + */ + +#pragma once + +#include +#include +#include + +#include "platform.h" + +#ifdef PLATFORM_MSVC +# include +#else /* PLATFORM_MSVC */ +# include +#endif /* PLATFORM_MSVC */ + +#include "cpair.h" + +#include "renderer/buffers.h" +#include "renderer/effect.h" + +#include "math/vector.h" + +class TiXmlElement; + +namespace tre { + + class Cursor { + public: + AttribBufPtr attribs; + IndexBufPtr indices; + EffectPtr effect; + EffectVars vars; + + public: + void Rescale(const Vector2f & scale, Float2Vector & verts); + + void LoadFromXml(TiXmlElement & root, const Vector2f & scale, + Float2Vector & verts, Float2Vector & coords); + + private: + Vector2f baseSize_; + Vector2f baseOffset_; + }; + + class CursorSet; + + typedef boost::shared_ptr CursorSetPtr; + typedef boost::weak_ptr CursorSetRef; + + class CursorSetFactory { + public: + const CursorSetPtr CreateInstance(const std::string & filename, + const Vector2f & scale); + const CursorSetPtr CreateInstance(TiXmlElement & root, + const Vector2f & scale); + + private: + typedef std::tr1::unordered_map CursorMap; + + private: + CursorMap cursorMap_; + }; + + class CursorSet { + public: + static CursorSetFactory & Factory(void) + { + static CursorSetFactory fac; + return fac; + } + + public: + typedef cpair CursorPair; + typedef std::vector CursorVector; + + public: + const Cursor * GetCursor(const std::string & name) const; + + void OnGuiResize(const Vector2f & scale); + + void LoadFromXml(TiXmlElement & root, const Vector2f & scale); + + private: + CursorVector cursors_; + + AttribBufPtr attribs_; + ushort bufSize_; + }; + +} diff --git a/src/gui/font/font.cpp b/src/gui/font/font.cpp new file mode 100644 index 0000000..1921ea1 --- /dev/null +++ b/src/gui/font/font.cpp @@ -0,0 +1,169 @@ +// +// Copyright (C) 2007-2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file font.cpp + * + * Ble. + */ + +#include + +#include "types.h" +#include "exception.h" + +#include "vfs/fstream.h" +#include "vfs/logfile.h" + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +#include "gui/font/font.h" +#include "freetype.h" + +namespace tre { + + const FontPtr FontFactory::CreateInstance(const std::string & name) + { + FontMap::iterator pos = map_.find(name); + + if(pos != map_.end() && !pos->second.expired()) + return pos->second.lock(); + + if(pos == map_.end()) + pos = map_.insert(pos, std::make_pair(name, FontPtr())); + + DEBUG_ASSERT(pos != map_.end()); + + FontPtr res; + try { + // need to pass the name stored in the element + res = FontPtr(new Font()); + res->LoadFromXml(name); + + vLog << ok("Font") << "Font loaded successfully (" + << name << ")." << std::endl; + } catch(Exception & exc) { + vLog << err("Font") << "Unable to load font (" + name + ").\nReason: " + << exc.what() << std::endl; + } + pos->second = res; + return res; + } + + /* + * Font class implementation + */ + const GlyphInfo * Font::GetFillerGlyph(void) + { + return sFontLib().GetFillerGlyph(); + } + + Font::Font() : aalias_(false), size_(defTextSize) + { + memset(faces_, 0, sizeof(FontFace*) * fsLast); + } + + Font::~Font() + { + for(uint i = 0; i < fsLast; ++i) { + if(faces_[i]) { + sFontLib().ClearFace(faces_[i]); + } + } + } + + const GlyphInfo * Font::GetGlyph(wchar_t chr, FontStyle style/*=fsRegular*/) + { + DEBUG_ASSERT(style < fsLast); + + if(!faces_[style]) + faces_[style] = sFontLib().LoadFace(files_[style]); + + if(!faces_[style]) + return NULL; + + return faces_[style]->GetGlyph(chr, size_, aalias_); + } + + int Font::GetKerning + (wchar_t chr1, wchar_t chr2, FontStyle style/*=fsRegular*/) + { + DEBUG_ASSERT(style < fsLast); + + if(!faces_[style]) + faces_[style] = sFontLib().LoadFace(files_[style]); + + if(!faces_[style]) + return NULL; + + return faces_[style]->GetKerning(chr1, chr2, size_); + } + + const FaceInfo Font::GetFaceInfo(FontStyle style/*=fsRegular*/) + { + DEBUG_ASSERT(style < fsLast); + + if(!faces_[style]) + faces_[style] = sFontLib().LoadFace(files_[style]); + + if(!faces_[style]) + return FaceInfo(); + + return faces_[style]->GetFaceInfo(size_); + } + + void Font::LoadFromXml(const std::string & path) + { + FileIStream file(path.c_str()); + if(!file.is_open()) + throw(Exception("Cannot open font file")); + + TiXmlDocument doc; + + if(!(file >> doc) || doc.Error()) + throw(Exception(doc.ErrorDesc())); + + TiXmlElement * root = doc.RootElement(); + DEBUG_ASSERT(root); + if(root->ValueTStr() != "font") + throw(Exception("Wrong root element")); + + TiXmlElement * elem = root->FirstChildElement("regular"); + if(elem) + files_[fsRegular] = CheckText(*elem); + else + throw(Exception("Regular style is not specified")); + + if((elem = root->FirstChildElement("bold"))) + files_[fsBold] = CheckText(*elem); + else + files_[fsBold] = files_[fsRegular]; + + if((elem = root->FirstChildElement("italic"))) + files_[fsItalic] = CheckText(*elem); + else + files_[fsItalic] = files_[fsRegular]; + + if((elem = root->FirstChildElement("boldItalic"))) + files_[fsBoldItalic] = CheckText(*elem); + else + files_[fsBoldItalic] = files_[fsRegular]; + } + +} diff --git a/src/gui/font/freetype.cpp b/src/gui/font/freetype.cpp new file mode 100644 index 0000000..04fb5cf --- /dev/null +++ b/src/gui/font/freetype.cpp @@ -0,0 +1,396 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file freetype.cpp + * + * blahblah + */ + +#include +#include + +#include "config.h" +#include "exception.h" + +#include "vfs/logfile.h" +#include "vfs/fstream.h" + +#include "freetype.h" + +namespace tre { + + /* + * FontFace class + */ + FontFace::FontFace(const std::string & path) : face_(NULL), buffer_(NULL) + { + uint buf_siz; + + // load from file + FileIStream file(path); + + if(!file.is_open()) + throw(Exception("Unable to open the font file!")); + + try { + buf_siz = file.length(); + buffer_ = new byte[buf_siz]; + + if(!file.read(reinterpret_cast(buffer_), buf_siz)) + throw(Exception("Unable to read the font file!")); + + if(FT_New_Memory_Face(sFontLib().lib_, buffer_, buf_siz, 0, &face_) != 0) + throw(Exception("Error initializing font face!")); + + if((face_->face_flags & FT_FACE_FLAG_SCALABLE) == 0) + throw(Exception("Font is not scalable!")); + + // set default size + SetSize(Font::defTextSize); + } catch(Exception &) { + delete [] buffer_; + throw; + } + } + + FontFace::~FontFace() + { + FT_Done_Face(face_); + delete [] buffer_; + + // clear glyphs + for(GlyphRefVector::iterator pos = glyphs_.begin(); + pos != glyphs_.end(); ++pos) { + sFontLib().RemoveGlyph(*pos); + } + } + + const GlyphInfo * FontFace::GetGlyph(wchar_t chr, uint size, bool aalias) + { + DEBUG_ASSERT(face_); + + if(size != size_) + SetSize(size); + + uint index = FT_Get_Char_Index(face_, chr); + + FontLib::GlyphKey key(this, chr, size, aalias); + + FontLib::GlyphMap::iterator pos = sFontLib().glyphs_.find(key); + + if(pos != sFontLib().glyphs_.end()) + return &pos->second; + +#ifdef FONT_FORCE_AUTOHINT + uint loadMode = FT_LOAD_FORCE_AUTOHINT; +#else /* FONT_FORCE_AUTOHINT */ + uint loadMode = FT_LOAD_DEFAULT; +#endif /* FONT_FORCE_AUTOHINT */ + + if(FT_Load_Glyph(face_, index, loadMode) != 0) { + vLog << err("Font") << "Unable to load glyph!" << std::endl; + return NULL; + } + + FT_GlyphSlot slot = face_->glyph; + + Vector2u origin; + Vector2u dims((slot->metrics.width >> 6) + 2 * glyphPadding, + (slot->metrics.height >> 6) + 2 * glyphPadding); + GlyphInfo glyph; + + glyph = sFontLib().RequestTextureSpace(dims, origin); + + glyph.code = chr; + glyph.bearing_x = (slot->metrics.horiBearingX >> 6) - glyphPadding; + glyph.bearing_y = (slot->metrics.horiBearingY >> 6) + glyphPadding; + glyph.advance_x = slot->metrics.horiAdvance >> 6; + + pos = sFontLib().glyphs_.lower_bound(key); + pos = sFontLib().glyphs_.insert(pos, std::make_pair(key, glyph)); + + ByteVector data; + data.resize(dims.x * dims.y * 4); + + byte c; + + if(aalias) { + if(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL) != 0) { + vLog << err("Font") << "Unable to render glyph!" << std::endl; + return NULL; + } + + for(int i = 0, k = glyphPadding; i < slot->bitmap.rows; ++i, ++k) { + for(int j = 0, l = glyphPadding; j < slot->bitmap.width; ++j, ++l) { + c = slot->bitmap.buffer[i*slot->bitmap.pitch + j]; + data[4 * (dims.y - k - 1) * dims.x + 4 * l] = c; + data[4 * (dims.y - k - 1) * dims.x + 4 * l + 1] = c; + data[4 * (dims.y - k - 1) * dims.x + 4 * l + 2] = c; + data[4 * (dims.y - k - 1) * dims.x + 4 * l + 3] = c; + } + } + } else { + if(FT_Render_Glyph(slot, FT_RENDER_MODE_MONO) != 0) { + vLog << err("Font") << "Unable to render glyph!" << std::endl; + return NULL; + } + + for(int i = 0, k = glyphPadding; i < slot->bitmap.rows; ++i, ++k) { + for(int j = 0, l = glyphPadding; j < slot->bitmap.width; ++j, ++l) { + c = slot->bitmap.buffer[i * slot->bitmap.pitch + (j >> 3)] + & (0x80 >> (j & 7)) ? 255 : 0; + data[4 * (dims.y - k - 1) * dims.x + 4 * l] = c; + data[4 * (dims.y - k - 1) * dims.x + 4 * l + 1] = c; + data[4 * (dims.y - k - 1) * dims.x + 4 * l + 2] = c; + data[4 * (dims.y - k - 1) * dims.x + 4 * l + 3] = c; + } + } + } + + DEBUG_ASSERT(glyph.texture); + glyph.texture->UpdateRect(origin, dims, data); + + return &pos->second; + } + + int FontFace::GetKerning(wchar_t chr1, wchar_t chr2, uint size) + { + DEBUG_ASSERT(face_); + + if(size != size_) + SetSize(size); + + uint index1 = FT_Get_Char_Index(face_, chr1); + uint index2 = FT_Get_Char_Index(face_, chr2); + + FT_Vector delta; + FT_Get_Kerning(face_, index1, index2, FT_KERNING_DEFAULT, &delta); + return delta.x >> 6; + } + + const FaceInfo FontFace::GetFaceInfo(uint size) + { + DEBUG_ASSERT(face_); + + if(size != size_) + SetSize(size); + + FaceInfo res; + res.height = face_->size->metrics.height >> 6; + res.ascender = face_->size->metrics.ascender >> 6; + res.descender = face_->size->metrics.descender >> 6; + return res; + } + + void FontFace::SetSize(uint sz) + { + size_ = sz; + if(FT_Set_Pixel_Sizes(face_, 0, size_) != 0) { + vLog << warn("Font") << "Unable to set font size correctly." << std::endl; + } + } + + /* + * GlyphKey + */ + FontLib::GlyphKey::GlyphKey(FontFace * f, uint idx, uint sz, bool aa) + : face(f) + { + num = idx; + num = num << 32; + num += sz << 1; + if(aa) + num += 1; + } + + /* + * FontLib class + */ + FontLib::FontLib() : lib_(NULL) + { +#ifdef LOG_SINGLETONS + vLog << info() << "Initializing font lib." << std::endl; +#endif /* LOG_SINGLETONS */ + + if(FT_Init_FreeType(&lib_) != 0) { + vLog << err("Font") << "Unable to initialize freetype library!" + << std::endl; + } + + // init filler glyph + Vector2u origin; + filler_ = RequestTextureSpace(Vector2u(1, 1), origin); + filler_.code = 0; + filler_.bearing_x = 0; + filler_.bearing_y = 0; + filler_.advance_x = 0; + + ByteVector data(4, 255); + filler_.texture->UpdateRect(origin, Vector2u(1,1), data); + } + + FontLib::~FontLib() + { +#ifdef LOG_SINGLETONS + vLog << info() << "Releasing font lib." << std::endl; +#endif /* LOG_SINGLETONS */ + + // release faces + for(FaceVector::iterator pos = faces_.begin(); pos != faces_.end(); ++pos) { + delete pos->second; + } + faces_.clear(); + + FT_Done_FreeType(lib_); + } + + void FontLib::ClearFace(FontFace * face) + { + DEBUG_ASSERT(face); + +#ifdef LOG_RESOURCES + vLog << info("Res") << "Releasing font face: '"; +#endif /* LOG_RESOURCES */ + + for(FaceVector::iterator pos = faces_.begin(); pos != faces_.end(); ++pos) { + if(pos->second == face) { +#ifdef LOG_RESOURCES + vLog << pos->first << "'." << std::endl; +#endif /* LOG_RESOURCES */ + faces_.erase(pos); + delete face; + return; + } + } + } + + FontFace * FontLib::LoadFace(const std::string & filename) + { + FaceVector::iterator pos = std::lower_bound( + faces_.begin(), faces_.end(), filename); + + if(pos != faces_.end() && pos->first == filename) + return pos->second; + +#ifdef LOG_RESOURCES + vLog << info("Res") << "Loading font face: " + << filename << "." << std::endl; +#endif /* LOG_RESOURCES */ + + FontFace * res = NULL; + + try { + res = new FontFace(filename); + + faces_.insert(pos, std::make_pair(filename, res)); + } catch(Exception & exc) { + vLog << err("Font") << "Error loading font face (" + << filename << ")\nReason: " << exc.what() << std::endl; + } + return res; + } + + const GlyphInfo * FontLib::GetFillerGlyph(void) + { + return &filler_; + } + + void FontLib::RemoveGlyph(GlyphMap::iterator & itr) + { + // TODO: HAHAHAHAHA, we are not removing any glyphs at this time :D + } + + const GlyphInfo FontLib::RequestTextureSpace(Vector2u dims, Vector2u & origin) + { + GlyphInfo res; + uint y_off; + + res.width = dims.x; + res.height = dims.y; + + // try to find a free space in one of the textures + for(TexVector::iterator itr = textures_.begin(); + itr != textures_.end(); ++itr) { + y_off = 0; + for(TexLineVector::iterator itr2 = itr->lines.begin(); + itr2 != itr->lines.end(); y_off += (itr2++)->first) { + // does glyph fit in the line? + if(itr2->first < dims.y) + continue; + + for(std::vector::iterator itr3 = itr2->second.begin(); + itr3 != itr2->second.end();) { + // is this interval wide enough? + if(itr3->y < dims.x) { + ++itr3; + continue; + } + + // reduce the interval and fill the origin var + origin.x = itr3->x; + origin.y = y_off; + itr3->x += dims.x; + itr3->y -= dims.x; + if(itr3->y == 0) + itr3 = itr2->second.erase(itr3); + + // fill texture related part of the GlyphInfo structure + res.texture = itr->tex; + res.texCoords.Set(origin.x, origin.y + dims.y, + origin.x + dims.x, origin.y); + res.texCoords /= static_cast(fontTextureSize); + return res; + } + } + // try to add a new line + if(y_off + dims.y <= fontTextureSize) { + itr->lines.push_back(std::make_pair(dims.y, + std::vector(1, Vector2u(dims.x, + fontTextureSize - dims.x)))); + + origin.x = 0; + origin.y = y_off; + res.texture = itr->tex; + res.texCoords.Set(origin.x, origin.y + dims.y, + origin.x + dims.x, origin.y); + res.texCoords /= static_cast(fontTextureSize); + return res; + } + } + + // otherwise create new texture with single level in it + TexturePtr ptr(Texture::Factory().CreateInstance(ttTexture2D, + fontTextureSize, fontTextureSize, tfR8G8B8A8)); + + TextureInfo newtex; + newtex.tex = ptr; + newtex.lines.push_back(std::make_pair(dims.y, + std::vector(1, Vector2u(dims.x, + fontTextureSize - dims.x)))); + textures_.push_back(newtex); + + origin.x = 0; + origin.y = 0; + res.texture = ptr; + res.texCoords.Set(origin.x, origin.y + dims.y, origin.x + dims.x, origin.y); + res.texCoords /= static_cast(fontTextureSize); + return res; + } + +} diff --git a/src/gui/font/freetype.h b/src/gui/font/freetype.h new file mode 100644 index 0000000..26ffb3c --- /dev/null +++ b/src/gui/font/freetype.h @@ -0,0 +1,136 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file freetype.h + * + * Ble. + */ + +#pragma once + +#include +#include FT_FREETYPE_H + +#include +#include +#include +#include + +#include "stdtypes.h" +#include "cpair.h" + +#include "gui/font/font.h" +#include "renderer/texture.h" + +namespace tre { + + const uint fontTextureSize = 512; + const uint glyphPadding = 1; + + struct GlyphInfo; + class FontFace; + + class FontLib { + public: + FontLib(); + ~FontLib(); + + void ClearFace(FontFace * face); + FontFace * LoadFace(const std::string & filename); + + const GlyphInfo * GetFillerGlyph(void); + + friend class FontFace; + + private: + struct GlyphKey { + FontFace * face; + uint64 num; + + GlyphKey(FontFace * f, uint idx, uint sz, bool aa); + + bool operator < (const GlyphKey & r) const + { + return face < r.face || (face == r.face && num < r.num); + } + }; + + typedef cpair > TexLinePair; + typedef std::vector TexLineVector; + + struct TextureInfo { + TexturePtr tex; + TexLineVector lines; + }; + + class FaceLess; + + typedef cpair FacePair; + typedef std::vector FaceVector; + typedef std::map GlyphMap; + typedef std::vector TexVector; + + private: + FT_Library lib_; + + FaceVector faces_; + TexVector textures_; + + GlyphMap glyphs_; + + GlyphInfo filler_; /// 1px dot, used for underlining and caret + + private: + void RemoveGlyph(GlyphMap::iterator & itr); + const GlyphInfo RequestTextureSpace(Vector2u dims, Vector2u & origin); + }; + + class FontFace : private boost::noncopyable { + public: + FontFace(const std::string & path); + ~FontFace(); + + const GlyphInfo * GetGlyph(wchar_t chr, uint size, bool aalias); + int GetKerning(wchar_t chr1, wchar_t chr2, uint size); + + const FaceInfo GetFaceInfo(uint size); + + private: + typedef std::vector GlyphRefVector; + typedef std::vector TexVector; + + private: + FT_Face face_; + byte * buffer_; + + GlyphRefVector glyphs_; + uint size_; + + TexVector textures_; + + private: + void SetSize(uint sz); + }; + + inline FontLib & sFontLib(void) + { + static FontLib f; + return f; + } +} diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp new file mode 100644 index 0000000..2ac035d --- /dev/null +++ b/src/gui/gui.cpp @@ -0,0 +1,363 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file gui.cpp + * + * blahblah + */ + +#include "vfs/fstream.h" +#include "vfs/logfile.h" + +#include "exception.h" +#include "math/vector.h" + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +#include "core/application.h" + +#include "gui/gui.h" +#include "gui/widget.h" + +#include "core/client/display.h" +#include "math/volumes.h" +#include "renderer/renderer.h" +#include "renderer/canvas.h" + +#include "skin.h" +#include "cursor.h" + +#include "memory/mmgr.h" + +namespace tre { + + /* + * Local helper functions + */ + namespace { + + Widget * GetTopmostWidget(const Vector2f & pos, Widget & wdg) + { + for(Widget::WdgVector::reverse_iterator itr = wdg.children.rbegin(); + itr != wdg.children.rend(); ++itr) { + DEBUG_ASSERT(*itr); + + if((*itr)->IsInRegion(pos)) + return GetTopmostWidget(pos, *(*itr)); + } + return &wdg; + } + + } + + /* + * GuiFactory class implementation + */ + GuiPtr GuiFactory::CreateInstance(Application & app, const CanvasPtr & canvas, + const std::string & filename, const std::string & skin) + { + Gui * res = NULL; + + try { + if(!canvas) { + throw(Exception("Invalid canvas"));} + + res = new Gui(app, canvas); + + if(!res->UseSkin(skin)) { + throw(Exception("Error loading skin"));} + + res->LoadFromFile(filename); // throws + } catch(Exception & exc) { + vLog << err("App") << "Error loading GUI (" << filename + << ")\nReason: " << exc.what() << "." << std::endl; + delete res; + res = NULL; + } + return GuiPtr(res); + } + + /* + * Gui class implementation + */ + Gui::Gui(Application & app, const CanvasPtr & cnv) : app_(app), + canvas_(cnv), rootWdg_(NULL), lastTop_(NULL), actCursor_(NULL) + { + } + + Gui::~Gui() + { + delete rootWdg_; + } + + Vector2f Gui::GetScaleFactor(void) const + { + return Vector2f(size_.x / scaleBase_.x, size_.y / scaleBase_.y); + } + + /** + * Also resizes the GUI to fit the new canvas + * @param cnv new canvas + */ + void Gui::SetCanvas(const CanvasPtr & cnv) + { + if(!cnv) { + vLog << warn("App") << "Attempting to assign invalid canvas to a gui. " + << "Operation ignored." << std::endl; + return; + } + + canvas_ = cnv; + size_.Set(cnv->GetWidth(), cnv->GetHeight()); + + if(!scale_) + scaleBase_ = size_; + + // update camera + cam_.SetOrtho(0.0f, canvas_->GetWidth(), + canvas_->GetHeight(), 0.0f, -1.0f, 1.0f); + + if(cursors_) + cursors_->OnGuiResize(GetScaleFactor()); + + if(rootWdg_) + rootWdg_->OnGuiResize(GetScaleFactor()); + } + + const Widget * Gui::FindWidget(const std::string & name) const + { + WidgetMap::const_iterator pos = wdgRegistry_.find(name); + + if(pos != wdgRegistry_.end()) + return pos->second; + return NULL; + } + + Widget * Gui::FindWidget(const std::string & name) + { + WidgetMap::iterator pos = wdgRegistry_.find(name); + + if(pos != wdgRegistry_.end()) + return pos->second; + return NULL; + } + + bool Gui::RegisterWidget(Widget * wdg, const std::string & name) + { + DEBUG_ASSERT(wdg); + + WidgetMap::iterator pos = wdgRegistry_.find(name); + + if(pos != wdgRegistry_.end()) { + vLog << warn("Gui") << "Unable to register widget name '" << name << "'" + << ", name already in use." << std::endl; + return false; + } + + wdgRegistry_.insert(std::make_pair(name, wdg)); + return true; + } + + void Gui::UnregisterWidget(const std::string & name) + { + WidgetMap::iterator pos = wdgRegistry_.find(name); + + if(pos != wdgRegistry_.end()) + wdgRegistry_.erase(pos); + } + + bool Gui::UseSkin(const std::string & filename) + { + GuiSkinPtr newskin = GuiSkin::Factory().CreateInstance(filename); + + if(newskin) { + skin_ = newskin; + return true; + } + return false; + } + + void Gui::ResetSkin(void) + { + skin_.reset(); + } + + void Gui::ShowCursor(bool on) + { + if(cursors_) + showCursor_ = on; + } + + void Gui::SetCursor(const std::string & name) + { + if(cursors_ && curName_ != name) { + actCursor_ = cursors_->GetCursor(name); + curName_ = name; + } + } + + void Gui::MouseMove(const Vector2f & abs, const Vector2f & rel) + { + if(rel.x == 0.0f && rel.y == 0.0f) + return; + + mousePos_.SetOPosition(Vector3f(abs.x, abs.y, 0.0f)); + + Widget * newtop = NULL; + + // mouseEnter event + if(lastTop_ && lastTop_->IsInRegion(abs)) + newtop = GetTopmostWidget(abs, *lastTop_); + else if(rootWdg_) + newtop = GetTopmostWidget(abs, *rootWdg_); + + if(newtop != lastTop_) { + if(lastTop_) + lastTop_->OnMouseExit(); + if(newtop) + newtop->OnMouseEnter(); + lastTop_ = newtop; + } + mouseMove(rel); + } + + bool Gui::ProcessInput(const InputEvent & event) + { + switch(event.type) { + case etQuit: + // Alt+F4 in windowed mode + app_.Quit(); + return true; + case etButtonOn: + buttonOn(event.button); + break; + case etButtonOff: + buttonOff(event.button); + break; + case etKeyOn: +// safeguard (for now) +app_.Quit(); + return keyOn(event.key.chr, event.key.sym); + case etKeyOff: + return keyOff(event.key.chr, event.key.sym); + break; + default: + return false; + } + return true; + } + + void Gui::Draw(void) + { + if(!rootWdg_) + return; + + sRenderer().PushCanvas(canvas_.get()); + + sRenderer().SetCamera(cam_); + + rootWdg_->Draw(); + + // draw cursor if required + if(showCursor_ && actCursor_) { + GeometryBatch batch(1, GeometryInfo(mousePos_.GetWTransform(), + actCursor_->attribs.get(), actCursor_->indices.get(), + actCursor_->effect.get(), actCursor_->vars)); + + sRenderer().DrawGeometry(batch.begin(), batch.end()); + } + + sRenderer().PopCanvas(); + } + + void Gui::LoadFromFile(const std::string & filename) + { + FileIStream file(filename.c_str()); + if(!file.is_open()) + throw(Exception("Cannot open GUI file")); + + TiXmlDocument doc; + + if(!(file >> doc) || doc.Error()) + throw(Exception(doc.ErrorDesc())); + + TiXmlElement * root = doc.RootElement(); + DEBUG_ASSERT(root); + if(root->ValueTStr() != "gui") + throw(Exception("Wrong root element")); + + TiXmlElement * elem = root->FirstChildElement("dimensions"); + scaleBase_ = 0; + if(elem) { + scaleBase_.x = CheckIntAttribute(*elem, "x", false); + scaleBase_.y = CheckIntAttribute(*elem, "y", false); + + scale_ = CheckIntAttribute(*elem, "scale", false, 1) != 0; + } + // auto-resize + if(scaleBase_.x == 0) + scaleBase_.x = canvas_->GetWidth(); + if(scaleBase_.y == 0) + scaleBase_.y = canvas_->GetHeight(); + + // scale + size_.x = canvas_->GetWidth(); + size_.y = canvas_->GetHeight(); + + // only resize if requested + if(!scale_) + scaleBase_ = size_; + + // update camera + cam_.SetOrtho(0.0f, canvas_->GetWidth(), + canvas_->GetHeight(), 0.0f, -1.0f, 1.0f); + + showCursor_ = false; + elem = root->FirstChildElement("cursorSet"); + if(elem) { + if(elem->Attribute("import")) { + cursors_ = CursorSet::Factory().CreateInstance( + CheckAttribute(*elem, "import"), GetScaleFactor()); + } else { + // NOTE: another try-catch block? + cursors_ = CursorSet::Factory().CreateInstance( + *elem, GetScaleFactor()); + } + if(cursors_) { + actCursor_ = cursors_->GetCursor("default"); + showCursor_ = CheckIntAttribute(*elem, "show", false, 1) != 0; + } + } + + elem = root->FirstChildElement("root"); + if(!elem) + throw(Exception("Missing root widget")); + + delete rootWdg_; + rootWdg_ = NULL; + + if(elem->Attribute("import")) { + rootWdg_ = Widget::Factory().CreateInstance( + CheckAttribute(*elem, "import"), *this); + } else { + rootWdg_ = Widget::Factory().CreateInstance(*elem, *this); + } + } +} diff --git a/src/gui/pixmap.cpp b/src/gui/pixmap.cpp new file mode 100644 index 0000000..8ee6b58 --- /dev/null +++ b/src/gui/pixmap.cpp @@ -0,0 +1,355 @@ +// +// Copyright (C) 2008 by Martin Moracek +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +/** + * @file pixmap.cpp + * + * blahblah + */ + +#include "xml/tinyxml.h" +#include "xml/xmlutils.h" + +#include "exception.h" +#include "renderer/effect.h" +#include "renderer/buffers.h" +#include "renderer/renderer.h" + +#include "gui/gui.h" + +#include "gui/pixmap.h" +#include "skin.h" + +namespace tre { + + Pixmap::Pixmap(Transformf & t, float scale/*=1.0f*/) : attribs_(NULL), + indices_(NULL), scaleFactor_(scale), trans_(t) + { + attribs_ = AttribBufferSet::Factory().CreateInstance(); + indices_ = IndexBuffer::Factory().CreateInstance(); + } + + Pixmap::~Pixmap() + { + delete attribs_; + delete indices_; + } + + void Pixmap::SetMap(uint u, WidgetState w) + { + // initialize default state + if(maps_[u][w]) { + vars_.SetTexture("gui_Texture", maps_[u][w]); + } + } + + void Pixmap::DrawPixmap(void) + { + GeometryBatch batch(1, GeometryInfo(&trans_.GetWTransform(), attribs_, + indices_, effect_.get(), &vars_)); + + sRenderer().DrawGeometry(batch.begin(), batch.end()); + } + + void Pixmap::LoadFromXmlTemplate(TiXmlElement & root, + const GuiSkinPtr & skin, const std::string & name, const Vector2f & sz) + { + if(!skin) + throw(Exception("Missing skin")); + + // at first check gui file for