Skip to content
Browse files

Initial version.

  • Loading branch information...
1 parent 1bd1141 commit 6f314a31da43316786a577bd9679b19468b9f6a4 @aerique committed Jun 19, 2009
Showing with 11,331 additions and 3 deletions.
  1. +24 −0 CMakeLists.txt
  2. +32 −0 LICENSE
  3. +0 −3 README
  4. +91 −0 README.1st
  5. +62 −0 README.MinGW
  6. +133 −0 bindings-generator/bindings-generator.lisp
  7. +1,519 −0 bindings-generator/cfg/okra.doxygen
  8. +90 −0 bindings-generator/common-lisp-config.lisp
  9. +266 −0 bindings-generator/common-lisp.lisp
  10. +186 −0 bindings-generator/common.lisp
  11. +297 −0 bindings-generator/config.lisp
  12. +92 −0 bindings-generator/cpp-config.lisp
  13. +325 −0 bindings-generator/cpp.lisp
  14. 0 bindings-generator/generated/.gitignore
  15. 0 bindings-generator/generated/libokra/.gitignore
  16. 0 bindings-generator/generated/libokra/build/.gitignore
  17. 0 bindings-generator/generated/libokra/src/.gitignore
  18. 0 bindings-generator/generated/src-bindings/.gitignore
  19. +130 −0 bindings-generator/lxml-util.lisp
  20. +13 −0 bindings-generator/package.lisp
  21. +28 −0 bindings-generator/templates/cl-asd.t
  22. +22 −0 bindings-generator/templates/cl-enums.t
  23. +41 −0 bindings-generator/templates/cl-file.t
  24. +19 −0 bindings-generator/templates/cl-package.t
  25. +20 −0 bindings-generator/templates/cl-typedefs.t
  26. +18 −0 bindings-generator/templates/cpp-cmakelists.t
  27. +41 −0 bindings-generator/templates/cpp-file.t
  28. 0 bindings-generator/xml/.gitignore
  29. +462 −0 cmake-modules/FindOGRE.cmake
  30. +141 −0 cmake-modules/FindPkgMacros.cmake
  31. +60 −0 cmake-modules/PreprocessorUtils.cmake
  32. +5 −0 examples/physics-and-input-ccl.sh
  33. +5 −0 examples/physics-and-input.bat
  34. +593 −0 examples/physics-and-input.lisp
  35. +7 −0 examples/physics-and-input.sh
  36. BIN examples/resources/GLX_icon.png
  37. BIN examples/resources/fonts/DejaVuSans.ttf
  38. BIN examples/resources/fonts/DejaVuSansMono.ttf
  39. BIN examples/resources/fonts/DejaVuSerif.ttf
  40. BIN examples/resources/fonts/Inconsolata.otf
  41. BIN examples/resources/grass_1024.jpg
  42. BIN examples/resources/mouse-pointer.png
  43. +34 −0 examples/resources/okra.fontdef
  44. +320 −0 examples/resources/okra.material
  45. +24 −0 examples/resources/okra.overlay
  46. BIN examples/resources/r2skin.jpg
  47. BIN examples/resources/robot.mesh
  48. BIN examples/resources/robot.skeleton
  49. BIN examples/resources/rockwall.tga
  50. +5 −0 examples/simple-okra-ccl.sh
  51. +5 −0 examples/simple-okra.bat
  52. +88 −0 examples/simple-okra.lisp
  53. +5 −0 examples/simple-okra.sh
  54. 0 lib/.gitignore
  55. +18 −0 libokra/build/CMakeLists.txt
  56. +139 −0 libokra/src/handwritten.cpp
  57. +688 −0 libokra/src/ogre-camera.cpp
  58. +520 −0 libokra/src/ogre-entity.cpp
  59. +614 −0 libokra/src/ogre-frustum.cpp
  60. +455 −0 libokra/src/ogre-light.cpp
  61. +353 −0 libokra/src/ogre-manual-object.cpp
  62. +449 −0 libokra/src/ogre-movable-object.cpp
  63. +415 −0 libokra/src/ogre-node.cpp
  64. +454 −0 libokra/src/ogre-overlay-element.cpp
  65. +229 −0 libokra/src/ogre-overlay-manager.cpp
  66. +272 −0 libokra/src/ogre-overlay.cpp
  67. +419 −0 libokra/src/ogre-render-target.cpp
  68. +169 −0 libokra/src/ogre-render-window.cpp
  69. +369 −0 libokra/src/ogre-resource-group-manager.cpp
  70. +565 −0 libokra/src/ogre-root.cpp
Sorry, we could not display the entire diff because it was too big.
View
24 CMakeLists.txt
@@ -0,0 +1,24 @@
+# CMakeLists.txt
+#
+# author: Erik Winkels (aerique@xs4all.nl)
+#
+# See the LICENSE file in the Okra root directory for more info.
+
+cmake_minimum_required(VERSION 2.6)
+
+project(libokra)
+
+option(BUILD_SHARED_LIBS "build libokra shared" ON)
+
+add_definitions(-g -O0 -Wall)
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-modules")
+
+find_package(OGRE REQUIRED)
+include_directories(${OGRE_INCLUDE_DIR})
+
+# Set some directories / variables.
+set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR})
+set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
+
+add_subdirectory(${CMAKE_SOURCE_DIR}/libokra/build)
View
32 LICENSE
@@ -0,0 +1,32 @@
+The BSD License
+
+Copyright (c) 2009, Erik Winkels
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * The name of its contributor may not be used to endorse or
+ promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View
3 README
@@ -1,3 +0,0 @@
-Coming Soon! (tm)
-
-Cleaning up some code...
View
91 README.1st
@@ -0,0 +1,91 @@
+
+ What you need and should know to get the examples running
+ =========================================================
+
+ General
+ -------
+ The startup scripts (the *.sh and *.bat files) expect to be
+ run from the examples directory.
+
+ Linux
+ -----
+ All examples expect Ogre to be installed so download the
+ source from: http://www.ogre3d.org/download/source (you'll
+ need "OGRE 1.6.x Source for Linux / OSX").
+
+ Configure, compile and install in /use/local. Ogre has some
+ dependencies which need to be installed first. Also, see here
+ for more information on the whole process:
+ http://www.ogre3d.org/wiki/index.php/Building_From_Source#Linux
+
+ The Linux startup scripts are written and tested using SBCL
+ (1.0.25.debian at the time of writing) and expect to find
+ 'sbcl' in the path.
+
+ They expect to find the necessary Ogre libraries in
+ /usr/local/lib/OGRE and all others in lib directory of the
+ Okra distribution.
+
+ All these options are set in the *.sh files and can be changed
+ there.
+
+ Windows
+ -------
+ All examples depend on the Ogre SDK to be installed so
+ download it from: http://www.ogre3d.org/download/sdk (you'll
+ need "OGRE 1.6.x SDK for Code::Blocks + MinGW C++ Toolbox").
+
+ Copy the following libraries from <ogre-sdk>/bin/Release to
+ the Okra lib directory: cg.dll, OgreMain.dll, OIS.dll,
+ Plugin_CgProgramManager.dll, Plugin_OctreeSceneManager.dll,
+ RenderSystem_Direct3D9.dll and RenderSystem_GL.dll.
+
+ The Windows startup scripts are written and tested using
+ Clozure CL and expect to find 'wx86cl' in the path.
+
+ All libraries are expected to be found in the lib directory of
+ the Okra distribution.
+
+ All these settings are in the *.bat files and can be changed
+ there.
+
+ Compiling libokra yourself
+ --------------------------
+ If the libokra library that comes with the Okra distribution
+ doesn't work you'll need to compile it yourself. You'll need
+ CMake for that:
+ http://www.cmake.org/cmake/resources/software.html
+
+ If you have installed CMake on Linux you should issue:
+
+ > cmake -G "Unix Makefiles"
+
+ If you're on Windows you should read "README.MinGW" in this
+ directory.
+
+
+ Examples
+ ========
+
+ Start with the simplest example first: simple-okra.
+
+ physics-and-input
+ -----------------
+ This example depends on both Buclet and clois-lane which you
+ can find at:
+
+ http://common-lisp.net/project/buclet/
+ http://common-lisp.net/project/clois-lane/
+
+ Make sure both are installed correctly and if you're on
+ Windows copy over the DLLs from both the Buclet and clois-lane
+ lib directories to the Okra lib directory. If you're on Linux
+ copy over the libclois-lane.so file from the clois-lane lib
+ directory to Okra's lib directory.
+
+ If you don't want to copy over library files for the above
+ examples you'll need to make sure the OS can find them. (By
+ adapting the example startup scripts for example.)
+
+
+ Erik Winkels, 2009-06-19
View
62 README.MinGW
@@ -0,0 +1,62 @@
+
+ This README is aimed at Windows users. If you're on a Unix
+ system I'm expecting you to be able to take care of yourself
+ and also expect you're using a distribution with a fairly
+ complete and non-retarded packaging system.
+
+ If your libs directory is empty you'll either to download them
+ from the homepage or you can try to compile them yourself in
+ which case you'll need to download and install MinGW, MSYS and
+ CMake:
+
+ o CMake: http://www.cmake.org/cmake/resources/software.html#latest
+ o MinGW: http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=240780
+ o MSYS: http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=24963
+ http://sourceforge.net/project/downloading.php?group_id=2435&filename=MSYS-1.0.10.exe&a=14697658
+
+ Install MinGW first and then MSYS. Use MSYS version 1.0.10.
+ There's guides and information on www.mingw.org if needed.
+ (http://www.mingw.org/wiki/HOWTO_Install_the_MinGW_GCC_Compiler_Suite)
+
+ I suggest first trying the libraries that come with Okra and
+ only then the MinGW route unless you're familiar with the
+ latter.
+
+ You will need the DLLs from the OgreSDK. You can download
+ the SDK at: http://www.ogre3d.org/download/sdk
+ You need the Code::Blocks + MinGW version (which is currently
+ at version 1.6.1 but this doesn't matter). You will need at
+ least the following DLLs (from bin/Release):
+
+ o cg.dll
+ o OgreMain.dll
+ o OIS.dll
+ o Plugin_CgProgramManager.dll
+ o Plugin_OctreeSceneManager.dll
+ o RenderSystem_Direct3D9.dll
+ o RenderSystem_GL.dll
+
+ and ofcourse: libokra.dll (and libclois-lane.dll if you want
+ to run the demo that depends on clois-lane). These last two
+ you will need to compile for yourself.
+
+ The CMake scripts do not find Ogre correctly on MinGW yet so
+ you'll have to check CMakeLists.txt in the Okra directory and
+ change it to point to the correct locations (the two lines
+ below "if (MINGW)").
+
+ If all of this is done you can issue:
+
+ > cmake -G "MSYS Makefiles"
+
+ (not "MinGW Makefiles"!)
+
+ and then:
+
+ > make
+
+ and if everything goes right (probably not) it should end up
+ in the lib directory.
+
+
+ Erik Winkels, 2009-06-02
View
133 bindings-generator/bindings-generator.lisp
@@ -0,0 +1,133 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP -*-
+;;;;
+;;;; bindings-generator.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :okra-bindings-generator)
+
+
+;;; Functions
+
+;; see OgreRenderSystemCapabilities.h (especially because this is untested!)
+;; #define CAPS_CATEGORY_SIZE 4
+;; #define OGRE_CAPS_BITSHIFT (32 - CAPS_CATEGORY_SIZE)
+;; #define OGRE_CAPS_VALUE(cat, val) ((cat << OGRE_CAPS_BITSHIFT) | (1 << val))
+(defun enum-caps-value (string)
+ (cl-ppcre:register-groups-bind (cat val)
+ ("OGRE_CAPS_VALUE\\((\\S+), (\\d+)\\)" string)
+ (logior (ash (gethash cat *enums*) 28)
+ (ash 1 (parse-number val)))))
+
+
+(defun enum-value (string)
+ (cond ((cl-ppcre:scan *regex-dec* string)
+ (parse-number (first-match *regex-dec* string)))
+ ((cl-ppcre:scan *regex-hex* string)
+ (parse-number (mkstr "#x" (first-match *regex-hex* string))))
+ ((cl-ppcre:scan *regex-con* string)
+ (let ((constant (first-match *regex-con* string)))
+ (cond ((gethash constant *enums*) (gethash constant *enums*))
+ ((equal (subseq constant 0 16) "OGRE_CAPS_VALUE(")
+ (enum-caps-value constant))
+ ;; hardcoding these enum values for now, since Doxygen
+ ;; doesn't put them in the xml
+ ((equal constant "HardwareBuffer::HBU_STATIC") 1)
+ ((equal constant "HardwareBuffer::HBU_DYNAMIC") 2)
+ ((equal constant "HardwareBuffer::HBU_WRITE_ONLY") 4)
+ ((equal constant "HardwareBuffer::HBU_STATIC_WRITE_ONLY") 5)
+ ((equal constant "HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY") 6)
+ ((equal constant "HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE") 14)
+ ((equal constant "TU_AUTOMIPMAP | TU_STATIC_WRITE_ONLY") 3)
+ (t (error "Could not parse enum constant: ~S" constant)))))
+ (t (error "Could not parse enum: ~S" string))))
+
+
+(defun parse-doxygen-enums-file (file)
+ (iter (for enum in (node '(:|compounddef| :|sectiondef| :|memberdef|)
+ (parse-xml-file file)))
+ (unless (and (equal (attribute :|kind| enum) "enum")
+ (equal (attribute :|prot| enum) "public"))
+ (next-iteration))
+ (as type-name = (value-of (first (node :|name| enum))))
+ (iter (with previous-value = 0)
+ (for value in (node :|enumvalue| enum))
+ (as initializer = (value-of (first (node :|initializer| value))))
+ (as name = (value-of (first (node :|name| value))))
+ (push name (gethash type-name *enum-types*))
+ (if (equal initializer "")
+ (progn (setf (gethash name *enums*) previous-value)
+ (incf previous-value))
+ (setf (gethash name *enums*) (enum-value initializer))))))
+
+
+(defun parse-doxygen-typedefs-file (file)
+ (iter (for typedef in (node '(:|compounddef| :|sectiondef| :|memberdef|)
+ (parse-xml-file file)))
+ (unless (equal (attribute :|kind| typedef) "typedef")
+ (next-iteration))
+ (as name = (value-of (first (node :|name| typedef))))
+ (as type = (value-of (first (node :|type| typedef))))
+ ;(format t "Considering: ~S => ~S...~%" name type)
+ ;; only very basic types are handled
+ (when (or (and (not (equal type "UTFString"))
+ (cl-ppcre:scan *regex-caps* type))
+ (cl-ppcre:scan *regex-crap* type)
+ (cl-ppcre:scan *regex-stl* type)
+ (string-equal "real" name))
+ (next-iteration))
+ (setf (gethash name *typedefs*) type)))
+
+
+(defun parse-doxygen-files (&optional (files *doxygen-files*))
+ (clrhash *typedefs*)
+ (format t "Parsing Doxygen files for typedefs...~%")
+ (iter (for file in *doxygen-typedefs-files*)
+ (parse-doxygen-typedefs-file file))
+ (clrhash *enum-types*)
+ (clrhash *enums*)
+ (format t "Parsing Doxygen files for enums...~%")
+ (iter (for file in *doxygen-enums-files*)
+ (parse-doxygen-enums-file file))
+ (clrhash *base-classes*)
+ (clrhash *classes*)
+ (iter (for file in files)
+ (as xml = (parse-xml-file file))
+ (as base-class-name = (ogre-base-class-name xml))
+ (as class-name = (ogre-class-name xml))
+ (format t "Parsing Doxygen file for ~A class...~%" class-name)
+ (setf (gethash class-name *base-classes*) base-class-name)
+ (iter (for node in (node '(:|compounddef| :|sectiondef|) xml))
+ ;; we're only interested in public methods
+ ;(unless (or (equal (attribute :|kind| node) "public-static-func")
+ ; (equal (attribute :|kind| node) "public-func"))
+ (unless (equal (attribute :|kind| node) "public-func")
+ (next-iteration))
+ (iter (for memberdef in (node :|memberdef| node))
+ (as name = (memberdef-name memberdef))
+ (when (or ;; skip constructors
+ (equal name class-name)
+ ;; skip deconstructors
+ (equal (elt name 0) #\~)
+ ;; skip member names starting with an underscore
+ (equal (elt name 0) #\_))
+ (next-iteration))
+ (as type = (memberdef-type memberdef))
+ (as args = (memberdef-args memberdef))
+ (push (list :name name :type type :args args)
+ (gethash class-name *classes*))))))
+
+
+;;; Main Program
+
+(defun generate-bindings (&optional (verbose nil))
+ (setf *verbose* verbose)
+ (parse-doxygen-files)
+ (generate-cpp-bindings)
+ (generate-lisp-bindings))
+
+
+;; for development
+(generate-bindings t)
View
1,519 bindings-generator/cfg/okra.doxygen
1,519 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
90 bindings-generator/common-lisp-config.lisp
@@ -0,0 +1,90 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP -*-
+;;;;
+;;;; common-lisp-config.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Variables
+
+;(defparameter *lisp-out-dir* "generated/src-bindings/")
+(defparameter *lisp-out-dir* "../src-bindings/")
+
+(defparameter *lisp-files* nil) ; for ASDF
+(defparameter *lisp-symbols* nil) ; for package.lisp
+
+;;; I've declared a lot of crap here as a :pointer of which I don't
+;;; even know what it is. (Generally camelCaps names that don't end
+;;; with a '*' or 'Ptr'.)
+(defparameter *lisp-type-mapping*
+ '(;; standard types
+ ("void" . ":void")
+ ("bool" . ":boolean")
+ ("double" . ":double")
+ ("float" . ":float")
+ ("int" . ":int")
+ ("long" . ":long")
+ ("size_t" . ":unsigned-int")
+ ("std::string" . ":string")
+ ("uchar" . ":unsigned-char")
+ ("uint" . ":unsigned-int")
+ ("uint8" . ":uint8")
+ ("uint16" . ":uint16")
+ ("uint32" . ":uint32")
+ ("unsigned char" . ":unsigned-char")
+ ("unsigned int" . ":unsigned-int")
+ ("unsigned long" . ":unsigned-long")
+ ("unsigned long long" . ":unsigned-long-long")
+ ("unsigned short" . ":unsigned-short")
+ ("time_t" . ":long") ; at least on my machine :-)
+ ;; Ogre types
+ ("AxisAlignedBox" . cl-array6) ; does this compute with cpp-config.lisp?
+ ("AnimableValuePtr" . ":pointer")
+ ("AnimationStateIterator" . ":pointer")
+ ("ChildNodeIterator" . ":pointer")
+ ("ChildObjectListIterator" . ":pointer")
+ ("ConstChildNodeIterator" . ":pointer")
+ ("ConstObjectIterator" . ":pointer")
+ ("ConstShadowTextureConfigIterator" . ":pointer")
+ ("DataStreamListPtr" . ":pointer")
+ ("DataStreamPtr" . ":pointer")
+ ("FileInfoListPtr" . ":pointer")
+ ("Light::LightTypes" . "light-types")
+ ("Matrix3" . ":pointer")
+ ("MeshPtr" . ":pointer")
+ ("SceneManagerEnumerator::MetaDataIterator" . ":pointer")
+ ("ObjectIterator" . ":pointer")
+ ("Overlay2DElementsIterator" . ":pointer")
+ ("OverlayMapIterator" . ":pointer")
+ ("PlaneBoundedVolume" . ":pointer")
+ ("Ray" . cl-array6)
+ ("Real" . "okra-real")
+ ("RenderOperation::OperationType" . "operation-type")
+ ("RenderSystemList*" . cl-render-system-list)
+ ("SceneManagerEnumerator::SceneManagerIterator" . ":pointer")
+ ("ShadowRenderableListIterator" . ":pointer")
+ ("String" . ":string")
+ ("StringVector" . ":pointer")
+ ("StringVectorPtr" . ":pointer")
+ ("TemplateIterator" . ":pointer")
+ ("TransformSpace" . ":pointer")
+ ("UTFString" . ":string")
+ ("Vector3" . cl-array3)
+ ("Vector4" . cl-array4)
+ ("ViewPoint" . ":pointer")
+ ("const String&" . ":string")
+ ("const AxisAlignedBox&" . cl-array6)
+ ("const ColourValue&" . cl-array4)
+ ("const DisplayString&" . ":string")
+ ("const Matrix4&" . cl-array16)
+ ("const Quaternion&" . cl-array4)
+ ("const Plane&" . cl-plane)
+ ("const Radian&" . "okra-real")
+ ("const Sphere&" . cl-array4)
+ ("const String&" . ":string")
+ ("const Vector3&" . cl-array3)
+ ("const Vector3*" . cl-array3)))
View
266 bindings-generator/common-lisp.lisp
@@ -0,0 +1,266 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;;;
+;;;; common-lisp.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Functions
+
+(defun add-lisp-symbol (name)
+ (pushnew (list :symbol (string-downcase name)) *lisp-symbols* :test 'equal))
+
+
+(defun base-class-name (class-name)
+ (let ((base-class-name (gethash class-name *base-classes*)))
+ (cond ((and base-class-name
+ ;; are we generating wrappers for this base-class?
+ (gethash base-class-name *classes*))
+ (lisp-name base-class-name))
+ ;; in case we don't have this class' base-class
+ (t "ogre-object"))))
+
+
+(defun cl-args (args)
+ (iter (for arg in args)
+ (as name = (lisp-name (cdr arg)))
+ (as type = (if (stringp (lisp-type (car arg)))
+ (lisp-type (car arg))
+ (funcall (lisp-type (car arg)) :arg-type)))
+ (collect (list :arg-name name :arg-type type))))
+
+
+(defun generate-asdf-file (&optional (file-name "okra-bindings.asd"))
+ ;(t2f *cl-asd-template* (mkstr "generated/" file-name)
+ (t2f *cl-asd-template* (mkstr "../" file-name)
+ (list :date (current-date-time-string)
+ :file-name file-name
+ :files *lisp-files*)))
+
+
+(defun generate-enums-file (&key (file-name "enums") (extension ".lisp"))
+ (pushnew (list :file file-name) *lisp-files* :test 'equal)
+ (t2f *cl-enums-template* (mkstr *lisp-out-dir* file-name extension)
+ (list :date (current-date-time-string)
+ :file-name (mkstr file-name extension)
+ :enum-types
+ (iter (for (enum enums) in-hashtable *enum-types*)
+ (as type-name = (lisp-name enum))
+ (collect
+ (list :type-name type-name
+ :enums
+ (iter (for name in (reverse enums))
+ (collect
+ (list :name
+ (lisp-name (string-downcase name))
+ :type (gethash name *enums*))))))))))
+
+
+(defun generate-lisp-bindings (&optional (classes *classes*))
+ (loop for name being the hash-keys in classes
+ do (format t "Generating Common Lisp bindings for ~A class...~%" name)
+ (generate-lisp-file name))
+ (format t "Generating Common Lisp enums file...~%")
+ (generate-enums-file)
+ (format t "Generating Common Lisp typedefs file...~%")
+ (generate-typedefs-file)
+ (format t "Generating Common Lisp package file...~%")
+ (generate-package-file)
+ (format t "Generating Common Lisp ASDF file...~%")
+ (generate-asdf-file))
+
+
+(defun generate-lisp-file (class-name &optional (extension ".lisp"))
+ (let ((file-name (lisp-name class-name))
+ (members (gethash class-name *classes*)))
+ (add-lisp-symbol (lisp-name class-name))
+ (pushnew (list :file file-name) *lisp-files* :test 'equal)
+ (t2f *cl-file-template* (mkstr *lisp-out-dir* file-name extension)
+ (list :date (current-date-time-string)
+ :file-name (mkstr file-name extension)
+ :base-class-name (base-class-name class-name)
+ :class-name (lisp-name class-name)
+ :f-and-m (iter (for member in (reverse members))
+ (unless (blacklisted member)
+ (collect (generate-lisp-member class-name
+ member))))))))
+
+
+(defun generate-lisp-member (class-name member)
+ (let* ((*print-pretty* nil) ; we want the comments below to stay on one line
+ (args (getf member :args))
+ (name (getf member :name))
+ (type (lisp-type (getf member :type)))
+ (c-name (c-name (mkstr class-name "_" name)))
+ (lisp-name (lisp-name name))
+ (lispefied-c-name (lisp-name c-name))
+ (return-type (if (stringp type) type (funcall type :return-type))))
+ (add-lisp-symbol lisp-name)
+ (list :after (if (stringp type) nil (funcall type :after))
+ :args (cl-args args)
+ :before (if (stringp type) nil (funcall type :before))
+ :c-name c-name
+ :lispefied-c-name lispefied-c-name
+ :name lisp-name
+ ;; use one of the *-to-string functions instead of format?
+ :ogre-name (format nil "~S" name)
+ :ogre-type (format nil "~S" (getf member :type))
+ :ogre-args (format nil "~S" args)
+ :return-arg (if (stringp type) nil (funcall type :return-arg))
+ :return-type (if (stringp return-type) return-type (car return-type))
+ :return-type-arg (unless (stringp return-type) (cdr return-type)))))
+
+
+(defun generate-package-file (&optional (file-name "package.lisp"))
+ (t2f *cl-package-template* (mkstr *lisp-out-dir* file-name)
+ (list :date (current-date-time-string)
+ :file-name file-name
+ :symbols *lisp-symbols*)))
+
+
+(defun generate-typedefs-file (&key (file-name "typedefs") (extension ".lisp"))
+ (pushnew (list :file file-name) *lisp-files* :test 'equal)
+ (t2f *cl-typedefs-template* (mkstr *lisp-out-dir* file-name extension)
+ (list :date (current-date-time-string)
+ :file-name (mkstr file-name extension)
+ :typedefs (iter (for (name type) in-hashtable *typedefs*)
+ (as lisp-name = (lisp-name name))
+ (as lisp-type = (lisp-type type))
+ (collect (list :name lisp-name
+ :type lisp-type))))))
+
+
+;;;# Type Handlers
+
+;;;## Type Handler Keywords
+
+;;;### :after
+;;;
+;;; Code that comes on the line after the call to the cfun.
+
+;;;### :arg-type
+;;;
+;;; The argument type it should take in the defcfun.
+
+;;;### :before
+;;;
+;;; Code that precedes the line of the call to the cfun.
+
+;;;### :return-arg
+;;;
+;;; Ogre returns Vector3, Quaternions and other objects. I have
+;;; chosen to pass a CFFI allocated array by reference to the wrapper
+;;; functions and have that array filled with the relevant values of
+;;; the returned object. If you check the CL-ARRAY3 function below
+;;; you'll see that the :below line allocates the array and
+;;; :return-arg makes sure that what was actually a returned object by
+;;; Ogre is now the name of the array reference.
+
+;;;### :return-type
+;;;
+;;; This is either a string or a cons. If it is a it just signifies
+;;; what the return type of the defcfun should be. If it is a cons
+;;; then its car signifies the return type of the defcfun (generally
+;;; :bool or :void) and its cdr signifies that we should also generate
+;;; an argument for to the C wrapper function. This is usually to
+;;; pass an array by reference instead of returning a pointer. To take
+;;; CL-ARRAY3 as an example again, this is often used for Ogre
+;;; functions that return a Vector3. Instead of returning a pointer
+;;; to a Vector3 object we allocate an array that can hold 3
+;;; Ogre::Reals, pass that to the C-wrapper which fills it with the x,
+;;; y and z values of the Vector3 object and a CFFI translator returns
+;;; it as a (vector x y z). Oh, and the array gets deallocated again
+;;; by CFFI.
+
+;;;## Type Handler Functions
+
+(defun cl-array3 (type)
+ (case type
+ (:after (mkfstr "(vector (mem-aref array 'okra-real 0) "
+ "(mem-aref array 'okra-real 1)~%"
+ " (mem-aref array 'okra-real 2))"))
+ (:arg-type "okra-array3")
+ (:before "(with-foreign-object (array 'okra-real 3)")
+ (:return-arg "array")
+ (:return-type '(":void" . "(array3 :pointer)"))
+ (otherwise nil)))
+
+
+(defun cl-array4 (type)
+ (case type
+ (:after (mkfstr "(vector (mem-aref array 'okra-real 0) "
+ "(mem-aref array 'okra-real 1)~%"
+ " (mem-aref array 'okra-real 2) "
+ "(mem-aref array 'okra-real 3))"))
+ (:arg-type "okra-array4")
+ (:before "(with-foreign-object (array 'okra-real 4)")
+ (:return-arg "array")
+ (:return-type '(":void" . "(array4 :pointer)"))
+ (otherwise nil)))
+
+
+(defun cl-array6 (type)
+ (case type
+ (:after (mkfstr "(vector (mem-aref array 'okra-real 0) "
+ "(mem-aref array 'okra-real 1)~%"
+ " (mem-aref array 'okra-real 2) "
+ "(mem-aref array 'okra-real 3)~%"
+ " (mem-aref array 'okra-real 4) "
+ "(mem-aref array 'okra-real 5))"))
+ (:arg-type "okra-array6")
+ (:before "(with-foreign-object (array 'okra-real 6)")
+ (:return-arg "array")
+ (:return-type '(":void" . "(array6 :pointer)"))
+ (otherwise nil)))
+
+
+(defun cl-array16 (type)
+ (case type
+ (:after (mkfstr "(vector (mem-aref array 'okra-real 0) "
+ "(mem-aref array 'okra-real 1)~%"
+ " (mem-aref array 'okra-real 2) "
+ "(mem-aref array 'okra-real 3)~%"
+ " (mem-aref array 'okra-real 4) "
+ "(mem-aref array 'okra-real 5)~%"
+ " (mem-aref array 'okra-real 6) "
+ "(mem-aref array 'okra-real 7)~%"
+ " (mem-aref array 'okra-real 8) "
+ "(mem-aref array 'okra-real 9)~%"
+ " (mem-aref array 'okra-real 10) "
+ "(mem-aref array 'okra-real 11)~%"
+ " (mem-aref array 'okra-real 12) "
+ "(mem-aref array 'okra-real 13)~%"
+ " (mem-aref array 'okra-real 14) "
+ "(mem-aref array 'okra-real 15))"))
+ (:arg-type "okra-array16")
+ (:before "(with-foreign-object (array 'okra-real 16)")
+ (:return-arg "array")
+ (:return-type '(":void" . "(array16 :pointer)"))
+ (otherwise nil)))
+
+
+(defun cl-plane (type)
+ (case type
+ (:arg-type "okra-array4")
+ (:return-type ":pointer")
+ (otherwise nil)))
+
+
+;;; First try to return a CPP vector as a dynamically sized array. Leaks
+;;; like a sieve in combination with c-render-system-list.
+;;; (foreign-free rs-list) possibly doesn't work and even if it does it'll
+;;; only free the rs-list memory and not that which all of its pointers are
+;;; pointing to.
+(defun cl-render-system-list (type)
+ (case type
+ (:after
+ (mkfstr "for i from 1 to (parse-integer (mem-aref rs-list :string 0))~%"
+ " collect (mem-aref rs-list :string i)~%"
+ " finally (foreign-free rs-list)"))
+ (:before "(loop with rs-list =") ; should be :before-call like in cpp
+ (:return-type ":pointer")
+ (otherwise nil)))
View
186 bindings-generator/common.lisp
@@ -0,0 +1,186 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;;;
+;;;; common.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+;;;# Information
+;;;
+;;; This file contains all kinds of assorted functions and macros that I (Erik
+;;; Winkels) use, sometimes only during development from the REPL.
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Functions
+
+(defun blacklisted (member)
+ (member member *blacklist* :test 'equal))
+
+
+(defun c-name (name &optional (no-ogre nil))
+ (iter (with prev-char = nil)
+ (for char in-string name)
+ (cond ;; "X" => "_x"
+ ((and (upper-case-p char)
+ (> (length result) 1) ; don't put a #\_ at the front
+ (not (upper-case-p prev-char))) ; don't seperate abbrevs
+ (collecting #\_ into result)
+ (collecting char into result))
+ ;; " " => "_"
+ ((equal char #\Space) (collecting #\_ into result))
+ ;; Otherwise just collect the char.
+ (t (collecting char into result)))
+ (setf prev-char char)
+ (finally (return (mkstr (if no-ogre "" "ogre_")
+ (string-downcase (coerce result 'string)))))))
+
+
+(defparameter *c-type-mapping* nil) ; redefined in cpp-config.lisp
+
+(defun c-type (type)
+ (cond ;; mappings
+ ((assoc type *c-type-mapping* :test 'equal)
+ (cdr (assoc type *c-type-mapping* :test 'equal)))
+ ;; pointers (that didn't need mapping)
+ ((and (> (length type) 1)
+ (or (equal (subseq type (- (length type) 1)) "&")
+ (equal (subseq type (- (length type) 1)) "*")))
+ type)
+ ;; enums
+ ((gethash type *enum-types*) type)
+ ;; typedefs
+ ((gethash type *typedefs*) (gethash type *typedefs*))
+ ;; unknown types
+ (t (error "[c-type] Unknown type: ~S~%" type))))
+
+
+(defun chop-namespace (string &optional (namespace "Ogre::"))
+ "Chops the string NAMESPACE (by default \"Ogre::\") from STRING."
+ (let ((ns-length (length namespace)))
+ (if (and (>= (length string) ns-length)
+ (equal (subseq string 0 ns-length) namespace))
+ (subseq string ns-length)
+ string)))
+
+
+(defun first-match (regex string)
+ (elt (nth-value 1 (cl-ppcre:scan-to-strings regex string)) 0))
+
+
+(defun lisp-name (name)
+ (iter (with prev-char = nil)
+ (for char in-string name)
+ (cond ;; "X" => "-x"
+ ((and (upper-case-p char)
+ (> (length result) 1) ; don't put a #\- at the front
+ (not (upper-case-p prev-char))) ; don't seperate abbrevs
+ (collecting #\- into result)
+ (collecting char into result))
+ ;; " " => "-"
+ ((equal char #\Space) (collecting #\- into result))
+ ;; "_" => "-"
+ ((equal char #\_)
+ (when (> (length result) 1) ; don't put a #\- at the front
+ (collecting #\- into result)))
+ ;; Otherwise just collect the char.
+ (t (collecting char into result)))
+ (setf prev-char char)
+ (finally (return (string-downcase (coerce result 'string))))))
+
+
+(defparameter *lisp-type-mapping* nil) ; redefined in common-lisp-config.lisp
+
+(defun lisp-type (type)
+ (cond ;; mappings
+ ((assoc type *lisp-type-mapping* :test 'equal)
+ (cdr (assoc type *lisp-type-mapping* :test 'equal)))
+ ;; pointers
+ ((and (> (length type) 1)
+ (or (equal (subseq type (- (length type) 1)) "&")
+ (equal (subseq type (- (length type) 1)) "*")))
+ ":pointer")
+ ;; enums
+ ((gethash type *enum-types*) (lisp-name type))
+ ;; typedefs
+ ((gethash type *typedefs*) (lisp-type (gethash type *typedefs*)))
+ ;; everything else
+ (t (error "[lisp-type] Unknown type: ~S~%" type))))
+
+
+(defun memberdef-args (md)
+ (let ((params (node :|param| md)))
+ (when (and (equal (length params) 1)
+ (equal (values-of (first (children (first params)))) '("void")))
+ (return-from memberdef-args "void"))
+ (iter (for param in params)
+ (as declname = (first (children (first (node :|declname| param)))))
+ (as type = (normalised-values-of (first (node :|type| param)) t))
+ (collecting (cons type declname)))))
+
+
+(defun memberdef-name (md)
+ (first (children (first (node :|name| md)))))
+
+
+(defun memberdef-type (md)
+ (normalised-values-of (first (node :|type| md)) t))
+
+
+(defun normalised-values-of (element &optional (as-string nil))
+ (let ((result (iter (for value in (values-of element))
+ (collecting (normalise-space value)))))
+ (if as-string
+ (let ((result (subseq (format nil "~{ ~A~}" result) 1)))
+ (cond ((and (> (length result) 2)
+ (equal (subseq result (- (length result) 2)) " *"))
+ (mkstr (subseq result 0 (- (length result) 2)) "*"))
+ ((and (> (length result) 2)
+ (equal (subseq result (- (length result) 2)) " &"))
+ (mkstr (subseq result 0 (- (length result) 2)) "&"))
+ (t result)))
+ result)))
+
+
+(defun ogre-base-class-name (node)
+ (chop-namespace
+ (first
+ (normalised-values-of
+ (first (node '(:|compounddef| :|basecompoundref|) node))))))
+
+
+(defun ogre-class-name (node)
+ (chop-namespace
+ (first
+ (normalised-values-of
+ (first (node '(:|compounddef| :|compoundname|) node))))))
+
+
+;; XXX: for development (horrible code duplication)
+(defun reload-templates ()
+ (setf *cl-asd-template* (create-template-printer #p"cl-asd.t"))
+ (setf *cl-enums-template* (create-template-printer #p"cl-enums.t"))
+ (setf *cl-file-template* (create-template-printer #p"cl-file.t"))
+ (setf *cl-package-template* (create-template-printer #p"cl-package.t"))
+ (setf *cl-typedefs-template* (create-template-printer #p"cl-typedefs.t"))
+ (setf *cpp-cmakelists-template*
+ (create-template-printer #p"cpp-cmakelists.t"))
+ (setf *cpp-file-template* (create-template-printer #p"cpp-file.t")))
+
+
+(defun template-to-file (template/printer file values)
+ (with-open-file (f file :direction :output :if-exists :supersede)
+ (fill-and-print-template template/printer values :stream f)))
+
+(defun t2f (template/printer file values)
+ (template-to-file template/printer file values))
+
+
+(defun template-to-string (template/printer values)
+ (with-output-to-string (string)
+ (fill-and-print-template template/printer values :stream string)))
+
+(defun t2str (template/printer values)
+ (template-to-string template/printer values))
View
297 bindings-generator/config.lisp
@@ -0,0 +1,297 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;;;
+;;;; config.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Variables
+
+(defparameter *verbose* nil)
+
+(defparameter *base-classes* (make-hash-table :test 'equal))
+(defparameter *classes* (make-hash-table :test 'equal))
+(defparameter *enum-types* (make-hash-table :test 'equal))
+(defparameter *enums* (make-hash-table :test 'equal))
+(defparameter *typedefs* (make-hash-table :test 'equal))
+
+;;; Bindings should be generated for the following files. Maybe at some
+;;; indefinite time in the future we'll be able to process all files.
+;;; (I doubt it and I'm not even sure we'd want to do that.)
+(defparameter *doxygen-files*
+ '("xml/class_ogre_1_1_camera.xml"
+ "xml/class_ogre_1_1_entity.xml"
+ "xml/class_ogre_1_1_frustum.xml"
+ "xml/class_ogre_1_1_light.xml"
+ "xml/class_ogre_1_1_manual_object.xml"
+ "xml/class_ogre_1_1_movable_object.xml"
+ "xml/class_ogre_1_1_node.xml"
+ "xml/class_ogre_1_1_overlay.xml"
+ "xml/class_ogre_1_1_overlay_element.xml"
+ "xml/class_ogre_1_1_overlay_manager.xml"
+ "xml/class_ogre_1_1_render_operation.xml"
+ "xml/class_ogre_1_1_render_target.xml"
+ "xml/class_ogre_1_1_render_window.xml"
+ "xml/class_ogre_1_1_resource_group_manager.xml"
+ "xml/class_ogre_1_1_root.xml"
+ "xml/class_ogre_1_1_scene_manager.xml"
+ "xml/class_ogre_1_1_scene_node.xml"
+ "xml/class_ogre_1_1_timer.xml"
+ "xml/class_ogre_1_1_viewport.xml"
+ ;"xml/class_ogre_1_1_window_event_utilities.xml"
+ ))
+
+(defparameter *doxygen-enums-files* (append1 *doxygen-files*
+ "xml/namespace_ogre.xml"))
+(defparameter *doxygen-typedefs-files* (append1 *doxygen-files*
+ "xml/namespace_ogre.xml"))
+
+;; regular expressions
+(defparameter *regex-con* (cl-ppcre:create-scanner "^\\s*(.*?)\\s*$"))
+(defparameter *regex-dec* (cl-ppcre:create-scanner "^\\s*(-?\\d+?)\\s*$"))
+(defparameter *regex-hex* (cl-ppcre:create-scanner "^\\s*0x(\\S+?)\\s*$"))
+
+(defparameter *regex-caps* (cl-ppcre:create-scanner "[A-Z]"))
+(defparameter *regex-crap* (cl-ppcre:create-scanner "\\("))
+(defparameter *regex-stl* (cl-ppcre:create-scanner "\\S+< .* >"))
+
+;; used by the HTML-TEMPLATE package
+(setf *default-template-pathname* (merge-pathnames "templates/"))
+(setf *string-modifier* #'cl:identity)
+(setf *template-start-marker* "[")
+(setf *template-end-marker* "]")
+
+;; templates
+(defparameter *cl-asd-template* (create-template-printer #p"cl-asd.t"))
+(defparameter *cl-enums-template* (create-template-printer #p"cl-enums.t"))
+(defparameter *cl-file-template* (create-template-printer #p"cl-file.t"))
+(defparameter *cl-package-template* (create-template-printer #p"cl-package.t"))
+(defparameter *cl-typedefs-template*
+ (create-template-printer #p"cl-typedefs.t"))
+(defparameter *cpp-file-template* (create-template-printer #p"cpp-file.t"))
+(defparameter *cpp-cmakelists-template*
+ (create-template-printer #p"cpp-cmakelists.t"))
+
+;;; *blacklist* is basically a dump for members that I don't want to or don't
+;;; know how to deal with.
+(defparameter *blacklist*
+ '(
+ (:name "addListener" :type "void" :args (("Listener*" . "s")))
+ ;; preferring ColourValue version
+ (:name "colour" :type "void" :args (("Real" . "r") ("Real" . "g") ("Real" . "b") ("Real" . "a")))
+ (:name "copyContentsToMemory" :type "void" :args (("const PixelBox&" . "dst") ("FrameBuffer" . "buffer")))
+ ;; arbitrarily preferring RenderWindow version
+ (:name "create" :type "Overlay*" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ (:name "createChild" :type "Node*" :args (("const Vector3&" . "translate") ("const Quaternion&" . "rotate")))
+ ;; arbitrarily preferring the string version
+ (:name "createChildSceneNode" :type "SceneNode*" :args (("const Vector3&" . "translate") ("const Quaternion&" . "rotate")))
+ ;; preferring the enum version
+ (:name "createEntity" :type "Entity*" :args (("const String&" . "entityName") ("const String&" . "meshName")))
+ ;; arbitrary choice
+ (:name "createParticleSystem" :type "ParticleSystem*" :args (("const String&" . "name") ("const String&" . "templateName")))
+ ;; should try this one out instead of the string version
+ (:name "createSceneManager" :type "SceneManager*" :args (("SceneTypeMask" . "typeMask") ("const String&" . "instanceName")))
+ ;; arbitrarily preferring the string version
+ (:name "createSceneNode" :type "SceneNode*" :args "void")
+ ;; arbitrary choice
+ (:name "declareResource" :type "void" :args (("const String&" . "name") ("const String&" . "resourceType") ("const String&" . "groupName") ("ManualResourceLoader*" . "loader") ("const NameValuePairList&" . "loadParameters")))
+ ;; arbitrarily preferring RenderWindow version
+ (:name "destroy" :type "void" :args (("Overlay*" . "overlay")))
+ ;; preferring the pointer version
+ (:name "destroy" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyBillboardChain" :type "void" :args (("BillboardChain*" . "obj")))
+ (:name "destroyBillboardChain" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyBillboardSet" :type "void" :args (("BillboardSet*" . "set")))
+ (:name "destroyBillboardSet" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyCamera" :type "void" :args (("Camera*" . "cam")))
+ (:name "destroyCamera" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyEntity" :type "void" :args (("Entity*" . "ent")))
+ (:name "destroyEntity" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyInstancedGeometry" :type "void" :args (("InstancedGeometry*" . "geom")))
+ (:name "destroyInstancedGeometry" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyLight" :type "void" :args (("Light*" . "light")))
+ (:name "destroyLight" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyManualObject" :type "void" :args (("ManualObject*" . "obj")))
+ (:name "destroyManualObject" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyMovableObject" :type "void" :args (("MovableObject*" . "m")))
+ (:name "destroyMovableObject" :type "void" :args (("const String&" . "name") ("const String&" . "typeName")))
+ ;; preferring the pointer version
+ (:name "destroyOverlayElement" :type "void" :args (("const String&" . "instanceName") ("bool" . "isTemplate")))
+ ;; blacklisting with extreme prejudice
+ (:name "getOverlayElementFactoryMap" :type "const FactoryMap&" :args NIL)
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyParticleSystem" :type "void" :args (("ParticleSystem*" . "obj")))
+ (:name "destroyParticleSystem" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ (:name "detachRenderTarget" :type "void" :args (("RenderTarget*" . "pWin")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyRibbonTrail" :type "void" :args (("RibbonTrail*" . "obj")))
+ (:name "destroyRibbonTrail" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroySceneNode" :type "void" :args (("SceneNode*" . "sn")))
+ (:name "destroySceneNode" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ ;(:name "destroyStaticGeometry" :type "void" :args (("StaticGeometry*" . "geom")))
+ (:name "destroyStaticGeometry" :type "void" :args (("const String&" . "name")))
+ ;; arbitrarily preferring the string version
+ (:name "detachObject" :type "MovableObject*" :args (("unsigned short" . "index")))
+ (:name "detachObject" :type "void" :args (("MovableObject*" . "obj")))
+ ;; arbitrarily preferring the string version
+ (:name "detachObjectFromBone" :type "MovableObject*" :args (("const String&" . "movableName")))
+ ;; arbitrary choice
+ (:name "enableCustomNearClipPlane" :type "void" :args (("const Plane&" . "plane")))
+ ;; arbitrary choice
+ (:name "enableReflection" :type "void" :args (("const Plane&" . "p")))
+ ;; arbitrarily preferring the string version
+ (:name "estimateWorldGeometry" :type "size_t" :args (("DataStreamPtr&" . "stream") ("const String&" . "typeName")))
+ ;; arbitrarily preferring the string version
+ (:name "extractMovableObject" :type "void" :args (("MovableObject*" . "m")))
+ (:name "forwardIntersect" :type "void" :args (("const Plane&" . "worldPlane") ("std::vector< Vector4 >*" . "intersect3d")))
+ (:name "getAnimationIterator" :type "AnimationIterator" :args "void")
+ ;; arbitrarily preferring the string version
+ (:name "getAttachedObject" :type "MovableObject*" :args (("unsigned short" . "index")))
+ ;; arbitrary choice
+ (:name "getAttachedObjectIterator" :type "ConstObjectIterator" :args "void")
+ ;; preferring the Viewport one
+ (:name "getCamera" :type "Camera*" :args (("const String&" . "name")))
+ (:name "getCameraIterator" :type "CameraIterator" :args "void")
+ (:name "getCameraToViewportBoxVolume" :type "void" :args (("Real" . "screenLeft") ("Real" . "screenTop") ("Real" . "screenRight") ("Real" . "screenBottom") ("PlaneBoundedVolume*" . "outVolume") ("bool" . "includeFarPlane")))
+ (:name "getCameraToViewportRay" :type "void" :args (("Real" . "screenx") ("Real" . "screeny") ("Ray*" . "outRay")))
+ ;; returns an uint16* (UTF char)
+ (:name "getCaption" :type "const DisplayString&" :args "void")
+ ;; arbitrarily preferring the string version
+ (:name "getChild" :type "Node*" :args (("unsigned short" . "index")))
+ ;; arbitrary choice
+ (:name "getChildIterator" :type "ConstChildNodeIterator" :args "void")
+ (:name "getDerivedPosition" :type "const Vector3&" :args (("bool" . "cameraRelativeIfSet")))
+ ;; dunno what to do with the type (wtf is :args nil?)
+ (:name "getInstalledPlugins" :type "const PluginInstanceList&" :args nil)
+ (:name "getListener" :type "Listener*" :args "void")
+ ;; arbitrary choice for RenderTarget version
+ (:name "getMetrics" :type "void" :args (("unsigned int&" . "width") ("unsigned int&" . "height") ("unsigned int&" . "colourDepth") ("int&" . "left") ("int&" . "top")))
+ (:name "getMovableObjectFactoryIterator" :type "MovableObjectFactoryIterator" :args "void")
+ (:name "getMovableObjectIterator" :type "MovableObjectIterator" :args (("const String&" . "typeName")))
+ (:name "getQueuedRenderableVisitor" :type "SceneMgrQueuedRenderableVisitor*" :args "void")
+ (:name "getResourceDeclarationList" :type "ResourceDeclarationList" :args (("const String&" . "groupName")))
+ (:name "getResourceManagerIterator" :type "ResourceManagerIterator" :args NIL)
+ ;; used in Camera but different from the one in Root
+ (:name "getSceneManager" :type "SceneManager*" :args "void")
+ ;; we need the handwritten version
+ ;(:name "getSingletonPtr" :type "ResourceGroupManager*" :args "void")
+ (:name "getSkyBoxGenParameters" :type "const SkyBoxGenParameters&" :args "void")
+ (:name "getSkyDomeGenParameters" :type "const SkyDomeGenParameters&" :args "void")
+ (:name "getSkyPlaneGenParameters" :type "const SkyPlaneGenParameters&" :args "void")
+ (:name "getSpecialCaseRenderQueueMode" :type "SpecialCaseRenderQueueMode" :args "void")
+ (:name "getStatistics" :type "const FrameStats&" :args "void")
+ ;; arbitrarily preferring the string version
+ (:name "getSubEntity" :type "SubEntity*" :args (("unsigned int" . "index")))
+ ;; dunno why it doesn't work
+ (:name "getViewMatrix" :type "const Matrix4&" :args "void")
+ ;; preferring the member in Viewport
+ (:name "getViewport" :type "Viewport*" :args "void")
+ ;; no support for std::vector yet
+ (:name "getWindowPlanes" :type "const std::vector< Plane >&" :args "void")
+ ;; the Root version is required
+ (:name "initialise" :type "void" :args "void")
+ ;; arbitrary choice for Vector3 version
+ (:name "isVisible" :type "bool" :args "void")
+ ;; arbitrary choice for Vector3 version
+ (:name "isVisible" :type "bool" :args (("const AxisAlignedBox&" . "bound") ("FrustumPlane*" . "culledBy")))
+ ;; arbitrary choice for Vector3 version
+ (:name "isVisible" :type "bool" :args (("const Sphere&" . "bound") ("FrustumPlane*" . "culledBy")))
+ ;; preferring lookAt(Vector3)
+ (:name "lookAt" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ ;; interferes with a more generic version
+ (:name "lookAt" :type "void" :args (("const Vector3&" . "targetPoint") ("TransformSpace" . "relativeTo") ("const Vector3&" . "localDirectionVector")))
+ ;; preferring Vector3 version
+ (:name "normal" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ ;; interferes with more generic function
+ (:name "pitch" :type "void" :args (("const Radian&" . "angle") ("TransformSpace" . "relativeTo")))
+ ;; preferring Vector3 version
+ (:name "position" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ ;; arbitrarily preferring the string version
+ (:name "prepareWorldGeometry" :type "void" :args (("DataStreamPtr&" . "stream") ("const String&" . "typeName")))
+ ;; no idea how to handle this one
+ (:name "projectSphere" :type "bool" :args (("const Sphere&" . "sphere") ("Real*" . "left") ("Real*" . "top") ("Real*" . "right") ("Real*" . "bottom")))
+ ;; arbitrarily preferring the string version
+ (:name "removeAndDestroyChild" :type "void" :args (("unsigned short" . "index")))
+ ;; arbitrarily preferring the string version
+ (:name "removeChild" :type "Node*" :args (("unsigned short" . "index")))
+ (:name "removeChild" :type "Node*" :args (("Node*" . "child")))
+ (:name "removeListener" :type "void" :args (("Listener*" . "s")))
+ (:name "resourceExists" :type "bool" :args (("ResourceGroup*" . "group") ("const String&" . "filename")))
+ (:name "resourceModifiedTime" :type "time_t" :args (("ResourceGroup*" . "group") ("const String&" . "filename")))
+ ;; interferes with more generic function
+ (:name "roll" :type "void" :args (("const Radian&" . "angle") ("TransformSpace" . "relativeTo")))
+ ;; interferes with more generic function
+ (:name "rotate" :type "void" :args (("const Quaternion&" . "q") ("TransformSpace" . "relativeTo")))
+ ;; preferring rotate(Quaternion)
+ (:name "rotate" :type "void" :args (("const Vector3&" . "axis") ("const Radian&" . "angle")))
+ (:name "rotate" :type "void" :args (("const Vector3&" . "axis") ("const Radian&" . "angle") ("TransformSpace" . "relativeTo")))
+ ;; preferring scale(Vector3)
+ (:name "scale" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ ;; arbitrary choice
+ (:name "setAutoTracking" :type "void" :args (("bool" . "enabled") ("SceneNode*" . "target") ("const Vector3&" . "localDirectionVector") ("const Vector3&" . "offset")))
+ ;; arbitrary choice
+ (:name "setDebugDisplayEnabled" :type "void" :args (("bool" . "enabled") ("bool" . "cascade")))
+ ;; preferring setDiffuseColour(const ColourValue&) since functions return
+ ;; values in that format as well
+ (:name "setDiffuseColour" :type "void" :args (("Real" . "red") ("Real" . "green") ("Real" . "blue")))
+ ;; OverlayElement version preferred
+ (:name "setDimensions" :type "void" :args (("Real" . "left") ("Real" . "top") ("Real" . "width") ("Real" . "height")))
+ ;; preferring setDirection(Vector3)
+ (:name "setDirection" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ (:name "setDirection" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z") ("TransformSpace" . "relativeTo") ("const Vector3&" . "localDirectionVector")))
+ ;; interferes with a more generic version
+ (:name "setDirection" :type "void" :args (("const Vector3&" . "vec") ("TransformSpace" . "relativeTo") ("const Vector3&" . "localDirectionVector")))
+ ;; preferring setFrustumOffset(Vector2)
+ (:name "setFrustumOffset" :type "void" :args (("Real" . "horizontal") ("Real" . "vertical")))
+ (:name "setListener" :type "void" :args (("Listener*" . "listener")))
+ ;; conflicts with more generic definition
+ (:name "setMaterialName" :type "void" :args (("size_t" . "subindex") ("const String&" . "name")))
+ ;; preferring setOrientation(Quaternion)
+ (:name "setOrientation" :type "void" :args (("Real" . "w") ("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ ;; from OverlayElement
+ (:name "setPosition" :type "void" :args (("Real" . "left") ("Real" . "top")))
+ ;; preferring setPosition(Vector3)
+ (:name "setPosition" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ (:name "setQueuedRenderableVisitor" :type "void" :args (("SceneMgrQueuedRenderableVisitor*" . "visitor")))
+ (:name "setScale" :type "void" :args (("Real" . "x") ("Real" . "y")))
+ ;; preferring setScale(Vector3)
+ (:name "setScale" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z")))
+ (:name "setShadowTextureConfig" :type "void" :args (("size_t" . "shadowIndex") ("const ShadowTextureConfig&" . "config")))
+ ;; preferring setSpecualrColour(const ColourValue&) since functions return
+ ;; values in that format as well
+ (:name "setSpecularColour" :type "void" :args (("Real" . "red") ("Real" . "green") ("Real" . "blue")))
+ ;; interferes with a more generic version
+ (:name "setVisible" :type "void" :args (("bool" . "visible") ("bool" . "cascade")))
+ ;; arbitrarily preferring the string version
+ (:name "setWorldGeometry" :type "void" :args (("DataStreamPtr&" . "stream") ("const String&" . "typeName")))
+ ;; preferring Vector2 version
+ (:name "textureCoord" :type "void" :args (("Real" . "u")))
+ (:name "textureCoord" :type "void" :args (("Real" . "u") ("Real" . "v")))
+ (:name "textureCoord" :type "void" :args (("Real" . "u") ("Real" . "v") ("Real" . "w")))
+ (:name "textureCoord" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z") ("Real" . "w")))
+ (:name "textureCoord" :type "void" :args (("const Vector3&" . "uvw")))
+ (:name "textureCoord" :type "void" :args (("const Vector4&" . "xyzw")))
+ ;; "Ignore what you don't understand."
+ (:name "translate" :type "void" :args (("Real" . "x") ("Real" . "y") ("Real" . "z") ("TransformSpace" . "relativeTo")))
+ (:name "translate" :type "void" :args (("const Matrix3&" . "axes") ("const Vector3&" . "move") ("TransformSpace" . "relativeTo")))
+ (:name "translate" :type "void" :args (("const Matrix3&" . "axes") ("Real" . "x") ("Real" . "y") ("Real" . "z") ("TransformSpace" . "relativeTo")))
+ (:name "update" :type "void" :args "void")
+ ;; interferes with a more generic version
+ (:name "yaw" :type "void" :args (("const Radian&" . "angle") ("TransformSpace" . "relativeTo")))
+ ))
View
92 bindings-generator/cpp-config.lisp
@@ -0,0 +1,92 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;;;
+;;;; cpp-config.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Variables
+
+;(defparameter *cpp-build-dir* "generated/libokra/build/")
+;(defparameter *cpp-src-dir* "generated/libokra/src/")
+(defparameter *cpp-build-dir* "../libokra/build/")
+(defparameter *cpp-src-dir* "../libokra/src/")
+
+(defparameter *cpp-files* nil) ; for CMakeLists.txt
+
+;; XXX: why do I sometimes see ":args nil"?
+(defparameter *c-type-mapping*
+ '(;; standard types (if not in *typedefs*)
+ ("void" . "void")
+ ("bool" . "bool")
+ ("float" . "float")
+ ("int" . "int")
+ ("long" . "long")
+ ("size_t" . "size_t")
+ ;("uchar" . "uchar")
+ ;("uint" . "unsigned int")
+ ;("uint8" . "uint8")
+ ;("uint32" . "uint32")
+ ("unsigned int" . "unsigned int")
+ ("unsigned long" . "unsigned long")
+ ("unsigned short" . "unsigned short")
+ ("time_t" . "time_t")
+ ;; Ogre types
+ ("AxisAlignedBox" . "AxisAlignedBox") ; no clue what I'm doing here
+ ("AnimableValuePtr" . "AnimableValuePtr")
+ ("AnimationStateIterator" . "AnimationStateIterator")
+ ("ChildNodeIterator" . "Node::ChildNodeIterator")
+ ("ChildObjectListIterator" . "Entity::ChildObjectListIterator")
+ ("ConstChildNodeIterator" . "Node::ConstChildNodeIterator")
+ ("ConstObjectIterator" . "SceneNode::ConstObjectIterator")
+ ("ConstShadowTextureConfigIterator" . "ConstShadowTextureConfigIterator")
+ ("DataStreamPtr" . "DataStreamPtr")
+ ("DataStreamListPtr" . "DataStreamListPtr")
+ ("FileInfoListPtr" . "FileInfoListPtr")
+ ("Light::LightTypes" . "Light::LightTypes")
+ ("LightTypes" . "Light::LightTypes")
+ ("Listener*" . "Node::Listener*")
+ ("Matrix3" . "Matrix3")
+ ("ManualObjectSection*" . "ManualObject::ManualObjectSection*")
+ ("MeshPtr" . "MeshPtr")
+ ("SceneManagerEnumerator::MetaDataIterator" . "SceneManagerEnumerator::MetaDataIterator")
+ ("ObjectIterator" . "SceneNode::ObjectIterator")
+ ("Overlay2DElementsIterator" . "Overlay::Overlay2DElementsIterator")
+ ("OverlayMapIterator" . "OverlayManager::OverlayMapIterator")
+ ("RenderOperation::OperationType" . "RenderOperation::OperationType")
+ ("PlaneBoundedVolume" . "PlaneBoundedVolume")
+ ("PrefabType" . "SceneManager::PrefabType")
+ ("Ray" . "Ray")
+ ("Real" . "Real")
+ ("RenderSystemList*" . c-render-system-list)
+ ("SceneManagerEnumerator::SceneManagerIterator" . "SceneManagerEnumerator::SceneManagerIterator")
+ ("ShadowRenderableListIterator" . "Entity::ShadowRenderableListIterator")
+ ("SpecialCaseRenderQueueMode" . "SceneManager::SpecialCaseRenderQueueMode")
+ ("String" . "const char*")
+ ("StringVector" . "StringVector")
+ ("StringVectorPtr" . "StringVectorPtr")
+ ("TemplateIterator" . "OverlayManager::TemplateIterator")
+ ("TransformSpace" . "SceneNode::TransformSpace")
+ ;("Vector3" . "Vector3")
+ ("Vector3" . c-vector3)
+ ("Vector4" . "Vector4") ; XXX: this will lead to memory faults in CL
+ ("VertexDataBindChoice" . "Entity::VertexDataBindChoice")
+ ("ViewPoint" . "ViewPoint")
+ ("const AxisAlignedBox&" . c-axis-aligned-box)
+ ("const ColourValue&" . c-colour-value)
+ ("const DisplayString&" . "const char*")
+ ("const EntitySet*" . "const Entity::EntitySet*")
+ ("const Matrix4&" . c-matrix4)
+ ("const Plane&" . c-plane)
+ ("const PlaneBoundedVolume&" . "const PlaneBoundedVolume&")
+ ("const Quaternion&" . c-quaternion)
+ ("const Radian&" . c-radian)
+ ("const Sphere&" . c-sphere)
+ ("const String&" . "const char*")
+ ("const Vector3&" . c-vector3)
+ ("const Vector3*" . "const Vector3*")
+ ))
View
325 bindings-generator/cpp.lisp
@@ -0,0 +1,325 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP -*-
+;;;;
+;;;; cpp.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Functions
+
+;;; ARG-CODE, C-ARGS and CALL-ARGS should probably be merged.
+
+(defun arg-code (args)
+ (if (equal args "void")
+ nil
+ (iter (with result = "")
+ (for arg in args)
+ (as name = (cdr arg))
+ (as type = (if (stringp (c-type (car arg)))
+ ""
+ (regex-replace-all "ARG"
+ (funcall (c-type (car arg)) :arg-code) name)))
+ (setf result (mkstr result (if type type "")))
+ (finally (if (equal result "")
+ (return nil)
+ (return result))))))
+
+
+(defun c-args (args &key (omit-name nil))
+ (if (equal args "void")
+ nil
+ (iter (with result = "")
+ (for arg in args)
+ (as name = (cdr arg))
+ ;; (funcall ... :arg-type) always returns a string
+ (as type = (if (stringp (c-type (car arg)))
+ (c-type (car arg))
+ (funcall (c-type (car arg)) :arg-type)))
+ (setf result (mkstr result ", " type (if omit-name
+ ""
+ (mkstr " " name))))
+ (finally (return result)))))
+
+
+(defun call-args (args)
+ (iter (with result = "")
+ (for arg in args)
+ (for i from 0)
+ (as name = (cdr arg))
+ (as type = (if (stringp (c-type (car arg)))
+ nil
+ (funcall (c-type (car arg)) :arg-code)))
+ (unless (= i 0)
+ (setf result (mkstr result ", ")))
+ (setf result (mkstr result (if type "ogre_" "") name))
+ (finally (return result))))
+
+
+(defun generate-c-fun (class-name member)
+ (let* ((*print-pretty* nil) ; for format below
+ (args (getf member :args))
+ (c-name (c-name (mkstr class-name "_" (getf member :name))))
+ (type (c-type (getf member :type)))
+ (return-type (if (stringp type) type (funcall type :return-type)))
+ (return-type-arg nil))
+ (unless (stringp return-type)
+ (setf return-type-arg (mkstr (cadr return-type) " " (cddr return-type)))
+ (setf return-type (car return-type)))
+ (list :name (getf member :name)
+ :type (format nil "~S" (getf member :type))
+ :args (format nil "~S" (getf member :args))
+ ;; make sure a const char* is returned (XXX: check for String!)
+ :after-call (if (equal return-type "const char*") ".c_str()" nil)
+ :arg-code (arg-code args)
+ :before-call (unless (stringp type) (funcall type :before-call))
+ :c-args (c-args args)
+ :c-name c-name
+ :call-args (call-args args)
+ :class class-name
+ :class-name (c-name class-name t)
+ :return (if (or (equal return-type "void")
+ ;; see c-render-system-list
+ (unless (stringp type) (funcall type :no-return)))
+ nil
+ "return ")
+ :return-type return-type
+ :return-type-arg return-type-arg
+ :post-code (unless (stringp type) (funcall type :post-code)))))
+
+
+(defun generate-cmakelists (&optional (file-name "CMakeLists.txt"))
+ (t2f *cpp-cmakelists-template* (mkstr *cpp-build-dir* file-name)
+ (list :date (current-date-time-string)
+ :file-name file-name
+ :files (reverse *cpp-files*))))
+
+
+(defun generate-cpp-bindings (&optional (classes *classes*))
+ (iter (for (class-name nil) in-hashtable classes)
+ (format t "Generating C++ bindings for ~A class...~%" class-name)
+ (generate-cpp-file class-name))
+ (format t "Generating C++ CMakeLists.txt...~%")
+ (generate-cmakelists))
+
+
+(defun generate-cpp-file (class-name &optional (extension ".cpp"))
+ (let ((file-name (lisp-name (mkstr "ogre" class-name extension)))
+ (members (gethash class-name *classes*)))
+ (pushnew (list :file file-name) *cpp-files* :test 'equal)
+ (t2f *cpp-file-template* (mkstr *cpp-src-dir* file-name)
+ (list :date (current-date-time-string)
+ :class-name class-name
+ :file-name file-name
+ :functions (iter (for member in (reverse members))
+ (when (blacklisted member)
+ (next-iteration))
+ (when *verbose*
+ (format t "Handling ~S...~%" member))
+ (collect (generate-c-fun class-name member)))
+ :prototypes (generate-prototypes class-name members)))))
+
+
+(defun generate-prototypes (class-name members)
+ (iter (for member in (reverse members))
+ (when (blacklisted member)
+ (next-iteration))
+ (as args = (getf member :args))
+ (as c-name = (c-name (mkstr class-name "_" (getf member :name))))
+ (as return-type = (if (stringp (c-type (getf member :type)))
+ (c-type (getf member :type))
+ (funcall (c-type (getf member :type))
+ :return-type)))
+ (as return-type-arg = (if (stringp return-type)
+ nil
+ (cadr return-type)))
+ (unless (stringp return-type)
+ (setf return-type (car return-type)))
+ (collect (list :return-type return-type
+ :name c-name
+ :class class-name
+ :return-type-arg return-type-arg
+ :args (c-args args :omit-name t)))))
+
+
+;;;# Type Handlers
+
+;;;## Type Handler Keywords
+
+;;;### :arg-code
+;;;
+;;; Basically translates an argument passed to the C wrapper to an
+;;; argument suitable for Ogre. If you check C-AXIS-ALIGNED-BOX
+;;; you'll see that its argument type (:arg-type) for the C-wrapper
+;;; function is "const okraArray6" and that the code defined in
+;;; :arg-code creates an Ogre::AxisAlignedBox from that.
+
+;;;### :arg-type
+;;;
+;;; The argument type it should take in the defcfun.
+
+;;;### :before-call
+;;;
+;;; Code that precedes the call to the cfun (on the same line).
+
+;;;### :no-return
+;;;
+;;; It is generally deduced from the :return-type line whether a
+;;; "return " is put in front of the cfun call. This doesn't always
+;;; work correctly so you can specify here that no "return " should be
+;;; generated. This is a bit of a hack.
+
+;;;### :post-code
+;;;
+;;; Code that comes on the line after the call to the cfun.
+
+;;;### :return-arg
+;;;
+;;; Ogre returns Vector3, Quaternions and other objects. I have
+;;; chosen to pass a CFFI allocated array by reference to the wrapper
+;;; functions and have that array filled with the relevant values of
+;;; the returned object. If you check the CL-ARRAY3 function below
+;;; you'll see that the :below line allocates the array and
+;;; :return-arg makes sure that what was actually a returned object by
+;;; Ogre is now the name of the array reference.
+
+;;;### :return-type
+;;;
+;;; This is either a string or a cons. If it is a string it just
+;;; signifies what the return type of the wrapper function should be.
+;;; If it is a cons then its car signifies the return type of the
+;;; wrapper function (generally bool or void) and its cdr signifies
+;;; that we should also generate an argument for the C wrapper
+;;; function. This is usually to pass an array by reference instead
+;;; of returning a pointer. Take CL-VECTOR3 as an example, this is
+;;; used for Ogre functions that return a Vector3. Instead of
+;;; returning a pointer to a Vector3 object we get passed a reference
+;;; to an array created by CFFI that can hold 3 Ogre::Reals. We
+;;; specify its type and its name in the cdr and fill it using the
+;;; code in :post-code.
+
+;;;## Type Handler Functions
+
+(defun c-axis-aligned-box (type)
+ (case type
+ (:arg-code (mkstr "AxisAlignedBox ogre_ARG = AxisAlignedBox(ARG[0], "
+ "ARG[1], ARG[2], ARG[3], ARG[4], ARG[5]);"))
+ (:arg-type "const okraArray6")
+ (:return-type "const AxisAlignedBox&")
+ (otherwise nil)))
+
+
+(defun c-colour-value (type)
+ (case type
+ (:arg-type "const okraArray4")
+ (:arg-code (mkstr "ColourValue ogre_ARG = ColourValue(ARG[0], ARG[1], "
+ "ARG[2], ARG[3]);"))
+ (:before-call "ColourValue ogre_cv = ")
+ (:post-code (mkfstr "cv[0] = ogre_cv.r;~% cv[1] = ogre_cv.g;~%"
+ " cv[2] = ogre_cv.b;~% cv[3] = ogre_cv.a;"))
+ (:return-type '("void" . ("okraArray4" . "cv")))
+ (otherwise nil)))
+
+
+(defun c-matrix4 (type)
+ (case type
+ (:arg-code (mkstr "Matrix4 ogre_ARG = Matrix4(ARG[0], ARG[1], ARG[2], "
+ "ARG[3], ARG[4], ARG[5], ARG[6], ARG[7], ARG[8], "
+ "ARG[9], ARG[10], ARG[11], ARG[12], ARG[13], ARG[14], "
+ "ARG[15]);"))
+ (:arg-type "const okraArray16")
+ (:before-call "Matrix4 ogre_m4 = ")
+ (:post-code (mkfstr "m4[ 0] = *(ogre_m4[ 0]); m4[ 1] = *(ogre_m4[ 1]);~%"
+ " m4[ 2] = *(ogre_m4[ 2]); m4[ 3] = *(ogre_m4[ 3]);~%"
+ " m4[ 4] = *(ogre_m4[ 4]); m4[ 5] = *(ogre_m4[ 5]);~%"
+ " m4[ 6] = *(ogre_m4[ 6]); m4[ 7] = *(ogre_m4[ 7]);~%"
+ " m4[ 8] = *(ogre_m4[ 8]); m4[ 9] = *(ogre_m4[ 9]);~%"
+ " m4[10] = *(ogre_m4[10]); m4[11] = *(ogre_m4[11]);~%"
+ " m4[12] = *(ogre_m4[12]); m4[13] = *(ogre_m4[13]);~%"
+ " m4[14] = *(ogre_m4[14]); m4[15] = *(ogre_m4[15]);"))
+ (:return-type '("void" . ("okraArray16" . "m4")))
+ (otherwise nil)))
+
+
+(defun c-plane (type)
+ (case type
+ (:arg-type "const okraArray4")
+ (:arg-code "Plane ogre_ARG = Plane(ARG[0], ARG[1], ARG[2], ARG[3]);")
+ (:return-type "const Plane&")
+ (otherwise nil)))
+
+
+(defun c-quaternion (type)
+ (case type
+ (:arg-code (mkstr "Quaternion ogre_ARG = Quaternion(ARG[0], ARG[1], "
+ "ARG[2], ARG[3]);"))
+ (:arg-type "const okraArray4")
+ (:before-call "Quaternion ogre_q = ")
+ (:post-code (mkfstr "q[0] = ogre_q[0];~% q[1] = ogre_q[1];~%"
+ " q[2] = ogre_q[2];~% q[3] = ogre_q[3];"))
+ (:return-type '("void" . ("okraArray4" . "q")))
+ (otherwise nil)))
+
+
+(defun c-radian (type)
+ (case type
+ (:arg-type "Real")
+ (:before-call "Radian ogre_r = ")
+ (:arg-code "Radian ogre_ARG = Radian(ARG);")
+ (:post-code "return ogre_r.valueRadians();")
+ (:no-return t)
+ (:return-type "okraReal")
+ (otherwise nil)))
+
+
+(defun c-ray (type)
+ (case type
+ (:arg-type "const okraArray6")
+ (:arg-code (mkstr "Ray ogre_ARG = Ray(Vector3(ARG[0], ARG[1], ARG[2]), "
+ "Vector3(ARG[3], ARG[4], ARG[5]));"))
+ (:return-type "Ray*")
+ (otherwise nil)))
+
+
+;;; First try to return a CPP vector as a dynamically sized array. Leaks
+;;; like a sieve in combination with cl-render-system-list.
+(defun c-render-system-list (type)
+ (case type
+ (:before-call "RenderSystemList* rsl = ")
+ (:post-code
+ (mkfstr "const char** list = new const char*[rsl->size()+1];~%~%"
+ " String size = StringConverter::toString(rsl->size());~%"
+ " list[0] = new char[size.length()];~%"
+ " list[0] = size.c_str();~%~%"
+ " for (size_t i = 0; i < rsl->size(); i++)~% {~%"
+ " RenderSystem* rs = rsl->at(i);~%"
+ " String name = rs->getName();~%"
+ " list[i+1] = new char[name.length()];~%"
+ " list[i+1] = name.c_str();~% }~%~%"
+ " return list;"))
+ (:no-return t)
+ (:return-type "const char**")
+ (otherwise nil)))
+
+
+(defun c-sphere (type)
+ (case type
+ (:arg-type "const okraArray4")
+ (:arg-code (mkstr "Sphere ogre_ARG = Sphere(Vector3(ARG[0], ARG[1], "
+ "ARG[2]), ARG[3]);"))
+ (:return-type "const Sphere&")
+ (otherwise nil)))
+
+
+(defun c-vector3 (type)
+ (case type
+ (:arg-type "const okraArray3")
+ (:arg-code "Vector3 ogre_ARG = Vector3(ARG[0], ARG[1], ARG[2]);")
+ (:before-call "Vector3 ogre_v = ")
+ (:post-code (mkfstr "v[0] = ogre_v[0];~% v[1] = ogre_v[1];~%"
+ " v[2] = ogre_v[2];"))
+ (:return-type '("void" . ("okraArray3" . "v")))
+ (otherwise nil)))
View
0 bindings-generator/generated/.gitignore
No changes.
View
0 bindings-generator/generated/libokra/.gitignore
No changes.
View
0 bindings-generator/generated/libokra/build/.gitignore
No changes.
View
0 bindings-generator/generated/libokra/src/.gitignore
No changes.
View
0 bindings-generator/generated/src-bindings/.gitignore
No changes.
View
130 bindings-generator/lxml-util.lisp
@@ -0,0 +1,130 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;;;
+;;;; lxml-util.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+;;;# Information
+;;;
+;;; Functions for navigating and retrieving from XML parsed into LXML
+;;; form. This is the default format for S-XML (and maybe XMLS iirc).
+
+(in-package :okra-bindings-generator)
+
+
+;;;# Functions
+
+(defun attributes? (element)
+ "ELEMENT must be a valid LXML element. Results are undefined if it isn't."
+ (when (listp element)
+ (listp (car element))))
+
+
+(defun attributes (element)
+ "ELEMENT must be a valid LXML element. Results are undefined if it isn't."
+ (when (attributes? element)
+ (cdr (car element))))
+
+
+(defun attribute (attribute element)
+ "ELEMENT must be a valid LXML element. Results are undefined if it isn't.
+ Returns the value of ATTRIBUTE of ELEMENT."
+ (when (attributes? element)
+ (getf (attributes element) attribute)))
+
+
+(defun children? (element)
+ "ELEMENT must be a valid LXML element. Results are undefined if it isn't."
+ (when (listp element)
+ (> (length element) 1)))
+
+
+(defun children (element)
+ "ELEMENT must be a valid LXML element. Results are undefined if it isn't."
+ (when (children? element)
+ (cdr element)))
+
+
+(defun name (element)
+ "ELEMENT must be a valid LXML element. Results are undefined if it isn't."
+ (cond ((attributes? element) (car (car element)))
+ ((listp element) (car element))
+ (t element)))
+
+
+(defun normalise-space (string)
+ "Removes the leading and trailing whitespace from a string. The official
+ XPath function also replaces multiple whitespaces within the string with
+ one space, but this function does not do that yet."
+ (let ((vector
+ (nth-value 1 (cl-ppcre:scan-to-strings "^\\s*(.*?)\\s*$" string))))
+ (if vector
+ (elt vector 0)
+ string)))
+
+
+(defun normalize-space (string)
+ "Calls NORMALISE-SPACE."
+ (normalise-space string))
+
+
+(defun value-of (element)
+ "Returns the text-nodes of ELEMENT concatenated as a string."
+ (iter (with result = "")
+ (for child in (children element))
+ (cond ((stringp child)
+ (setf result (concatenate 'string result child)))
+ ((listp child)
+ (setf result (concatenate 'string result (value-of child))))
+ (t (format *error-output*
+ "[VALUE-OF] Unexpected child: ~S~%" child)))
+ (finally (return result))))
+
+
+(defun values-of (element)
+ "Returns a list with the contents of all the text-nodes of ELEMENT."
+ (iter (for child in (children element))
+ (cond ((stringp child) (collecting child))
+ ((listp child) (appending (values-of child)))
+ (t (format *error-output*
+ "[VALUES-OF] Unexpected child: ~S~%" child)))))
+
+
+;; Still need to add support for:
+;; o :|@attribute| - can only be the last item of a list
+;; o :|element[n]| - only the nth element (see XPath)
+(defun node (path element)
+ "PATH can either be a symbol or a list of symbols.
+ ELEMENT must be a valid LXML element.
+
+ XPath Lite: returns a list of elements. (Take note: a LIST of elements!)
+
+ Examples for the following (parsed) XML: (:|root|
+ (:|element| (:|child| \"foo\"))
+ (:|element| (:|child| \"bar\")))
+ These two examples are equivalent:
+ o (NODE :|element| ROOT) => ((:|element| (:|child| \"foo\"))
+ (:|element| (:|child| \"bar\")))
+ o (NODE '(:|element|) ROOT) => ((:|element| (:|child| \"foo\"))
+ (:|element| (:|child| \"bar\")))
+
+ A real path:
+ o (NODE '(:|element| :|child|) ROOT) => ((:|child| \"foo\")
+ (:|child| \"bar\"))"
+ (labels ((node-recurser (path element)
+ (if (= (length path) 1)
+ (node (car path) element)
+ (iter (for child in (children element))
+ (with name = (car path))
+ (as child-name = (name child))
+ (when (equal child-name name)
+ (appending (node-recurser (cdr path) child)))))))
+ (if (listp path)
+ (node-recurser path element)
+ (iter (for child in (children element))
+ (if (equal path :|*|)
+ (collecting child)
+ (when (equal path (name child))
+ (collecting child)))))))
View
13 bindings-generator/package.lisp
@@ -0,0 +1,13 @@
+;;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;;;
+;;;; package.lisp
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+
+(in-package :cl-user)
+
+(defpackage :okra-bindings-generator
+ (:use :cl :cl-ppcre :html-template :iterate :okra-common :parse-number
+ :s-xml))
View
28 bindings-generator/templates/cl-asd.t
@@ -0,0 +1,28 @@
+;;;; [TMPL_VAR "file-name"]
+;;;;
+;;;; This file has been generated by the Okra Bindings Generator.
+;;;; You should not edit this file unless you know what you're doing.
+;;;; Any changes you've made directly to this file will not be retained
+;;;; when a new instance of this file is generated.
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+;;;;
+;;;; This file was generated on: [TMPL_VAR "date"].
+
+(in-package :cl-user)
+
+(defpackage :okra-system
+ (:use :cl :asdf))
+
+(in-package :okra-system)
+
+(asdf:defsystem :okra-bindings
+ :version "1.6.2.1"
+ :components
+ ((:module src-bindings
+ :serial t
+ :components
+ ((:file "package") (:file "ogre-lib")[TMPL_LOOP "files"] (:file "[TMPL_VAR "file"]")[/TMPL_LOOP] (:file "handwritten"))))
+ :depends-on (:cffi :okra-common))
View
22 bindings-generator/templates/cl-enums.t
@@ -0,0 +1,22 @@
+;;;; [TMPL_VAR "file-name"]
+;;;;
+;;;; This file has been generated by the Okra Bindings Generator.
+;;;; You should not edit this file unless you know what you're doing.
+;;;; Any changes you've made directly to this file will not be retained
+;;;; when a new instance of this file is generated.
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+;;;;
+;;;; This file was generated on: [TMPL_VAR "date"].
+
+(in-package :okra-bindings)
+
+
+;;; Enums
+
+[TMPL_LOOP "enum-types"](defcenum [TMPL_VAR "type-name"][TMPL_LOOP "enums"]
+ (:[TMPL_VAR "name"] [TMPL_VAR "type"])[/TMPL_LOOP])
+
+[/TMPL_LOOP]
View
41 bindings-generator/templates/cl-file.t
@@ -0,0 +1,41 @@
+;;;; [TMPL_VAR "file-name"]
+;;;;
+;;;; This file has been generated by the Okra Bindings Generator.
+;;;; You should not edit this file unless you know what you're doing.
+;;;; Any changes you've made directly to this file will not be retained
+;;;; when a new instance of this file is generated.
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+;;;;
+;;;; This file was generated on: [TMPL_VAR "date"].
+
+(in-package :okra-bindings)
+
+
+;;; Class
+
+(defclass [TMPL_VAR "class-name"] ([TMPL_VAR "base-class-name"])
+ ())
+
+
+;;; Foreign Functions & Methods
+
+[TMPL_LOOP "f-and-m"];; name: [TMPL_VAR "ogre-name"]
+;; type: [TMPL_VAR "ogre-type"]
+;; args: [TMPL_VAR "ogre-args"]
+;;
+(defcfun "[TMPL_VAR "c-name"]"
+ [TMPL_VAR "return-type"]
+ (ogre-[TMPL_VAR "class-name"] :pointer)[TMPL_IF "return-type-arg"]
+ [TMPL_VAR "return-type-arg"][/TMPL_IF][TMPL_LOOP "args"]
+ ([TMPL_VAR "arg-name"] [TMPL_VAR "arg-type"])[/TMPL_LOOP])
+
+(defmethod [TMPL_VAR "name"] ((this [TMPL_VAR "class-name"])[TMPL_LOOP "args"] [TMPL_VAR "arg-name"][/TMPL_LOOP])[TMPL_IF "before"]
+ [TMPL_VAR "before"][/TMPL_IF]
+ [TMPL_IF "before"] [/TMPL_IF]([TMPL_VAR "lispefied-c-name"] (pointer-to this)[TMPL_IF "return-arg"] [TMPL_VAR "return-arg"][/TMPL_IF][TMPL_LOOP "args"] [TMPL_VAR "arg-name"][/TMPL_LOOP])[TMPL_IF "after"]
+ [TMPL_VAR "after"])[/TMPL_IF])
+
+
+[/TMPL_LOOP]
View
19 bindings-generator/templates/cl-package.t
@@ -0,0 +1,19 @@
+;;;; [TMPL_VAR "file-name"]
+;;;;
+;;;; This file has been generated by the Okra Bindings Generator.
+;;;; You should not edit this file unless you know what you're doing.
+;;;; Any changes you've made directly to this file will not be retained
+;;;; when a new instance of this file is generated.
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+;;;;
+;;;; This file was generated on: [TMPL_VAR "date"].
+
+(in-package :cl-user)
+
+(defpackage :okra-bindings
+ (:use :cl :cffi :okra-common)
+ (:shadow :position)
+ (:export *ogre-root* :ogre-object :name-of :pointer-to :conan :root-constructor :get-overlay-manager-singleton-ptr :get-resource-group-manager-singleton-ptr :get-window-handler :message-pump :simple-add-viewport :get-available-renderers-test[TMPL_LOOP "symbols"] :[TMPL_VAR "symbol"][/TMPL_LOOP]))
View
20 bindings-generator/templates/cl-typedefs.t
@@ -0,0 +1,20 @@
+;;;; [TMPL_VAR "file-name"]
+;;;;
+;;;; This file has been generated by the Okra Bindings Generator.
+;;;; You should not edit this file unless you know what you're doing.
+;;;; Any changes you've made directly to this file will not be retained
+;;;; when a new instance of this file is generated.
+;;;;
+;;;; author: Erik Winkels (aerique@xs4all.nl)
+;;;;
+;;;; See the LICENSE file in the Okra root directory for more info.
+;;;;
+;;;; This file was generated on: [TMPL_VAR "date"].
+
+(in-package :okra-bindings)
+
+
+;;; Typedefs
+
+[TMPL_LOOP "typedefs"](defctype [TMPL_VAR "name"] [TMPL_VAR "type"])
+[/TMPL_LOOP]
View
18 bindings-generator/templates/cpp-cmakelists.t
@@ -0,0 +1,18 @@
+# [TMPL_VAR "file-name"]
+#
+# This file has been generated by the Okra Bindings Generator.
+# You should not edit this file unless you know what you're doing.
+# Any changes you've made directly to this file will not be retained
+# when a new instance of this file is generated.
+#
+# author: Erik Winkels (aerique@xs4all.nl)
+#
+# See the LICENSE file in the Okra root directory for more info.
+#
+# This file was generated on: [TMPL_VAR "date"].
+
+set(LIBOKRA_SOURCE_FILES "../src/handwritten.cpp"[TMPL_LOOP "files"] "../src/[TMPL_VAR "file"]"[/TMPL_LOOP])
+
+add_library(okra ${LIBOKRA_SOURCE_FILES})
+
+target_link_libraries(okra ${OGRE_LIBRARY})
View
41 bindings-generator/templates/cpp-file.t
@@ -0,0 +1,41 @@
+// [TMPL_VAR "file-name"]
+//
+// This file has been generated by the Okra Bindings Generator.
+// You should not edit this file unless you know what you're doing.
+// Any changes you've made directly to this file will not be retained
+// when a new instance of this file is generated.
+//
+// author: Erik Winkels (aerique@xs4all.nl)
+//
+// See the LICENSE file in the Okra root directory for more info.
+//
+// This file was generated on: [TMPL_VAR "date"].
+
+#include "Ogre.h"
+#include "okra.h"
+
+using namespace Ogre;
+
+
+// Prototypes
+
+extern "C"
+{
+[TMPL_LOOP "prototypes"] [TMPL_VAR "return-type"] [TMPL_VAR "name"] ([TMPL_IF "class"][TMPL_VAR "class"]*[TMPL_IF "return-type-arg"], [/TMPL_IF][/TMPL_IF][TMPL_VAR "return-type-arg"][TMPL_VAR "args"]);
+[/TMPL_LOOP]}
+
+
+// Functions
+
+[TMPL_LOOP "functions"]// name: "[TMPL_VAR "name"]"
+// type: [TMPL_VAR "type"]
+// args: [TMPL_VAR "args"]
+//
+[TMPL_VAR "return-type"] [TMPL_VAR "c-name"] ([TMPL_IF "class"][TMPL_VAR "class"]* ogre_[TMPL_VAR "class-name"][TMPL_IF "return-type-arg"], [/TMPL_IF][/TMPL_IF][TMPL_IF "return-type-arg"][TMPL_VAR "return-type-arg"][TMPL_VAR "return-type-arg-name"][/TMPL_IF][TMPL_VAR "c-args"])
+{
+[TMPL_IF "arg-code"] [TMPL_VAR "arg-code"]
+[/TMPL_IF] [TMPL_VAR "return"][TMPL_VAR "before-call"]ogre_[TMPL_VAR "class-name"]->[TMPL_VAR "name"]([TMPL_VAR "call-args"])[TMPL_VAR "after-call"];[TMPL_IF "post-code"]
+ [TMPL_VAR "post-code"][/TMPL_IF]
+}
+
+[/TMPL_LOOP]
View
0 bindings-generator/xml/.gitignore
No changes.
View
462 cmake-modules/FindOGRE.cmake
@@ -0,0 +1,462 @@
+#-------------------------------------------------------------------
+# This file is part of the CMake build system for OGRE
+# (Object-oriented Graphics Rendering Engine)
+# For the latest info, see http://www.ogre3d.org/
+#
+# The contents of this file are placed in the public domain. Feel
+# free to make use of it in any way you like.
+#-------------------------------------------------------------------
+
+# - Try to find OGRE
+# If you have multiple versions of Ogre installed, use the CMake or
+# the environment variable OGRE_HOME to point to the path where the
+# desired Ogre version can be found.
+# By default this script will look for a dynamic Ogre build. If you
+# need to link against static Ogre libraries, set the CMake variable
+# OGRE_STATIC to TRUE.
+#
+# Once done, this will define
+#
+# OGRE_FOUND - system has OGRE
+# OGRE_INCLUDE_DIRS - the OGRE include directories
+# OGRE_LIBRARIES - link these to use the OGRE core
+#
+# Additionally this script searches for the following optional
+# parts of the Ogre package:
+# Plugin_BSPSceneManager, Plugin_CgProgramManager,
+# Plugin_OctreeSceneManager, Plugin_OctreeZone,
+# Plugin_ParticleFX, Plugin_PCZSceneManager,
+# RenderSystem_GL, RenderSystem_Direct3D9, RenderSystem_Direct3D10,
+# CEGUIRenderer, Paging, Terrain
+#
+# For each of these components, the following variables are defined:
+#
+# OGRE_${COMPONENT}_FOUND - ${COMPONENT} is available
+# OGRE_${COMPONENT}_INCLUDE_DIRS - additional include directories for ${COMPONENT}
+# OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT}
+#
+# Finally, the following variables are defined:
+#
+# OGRE_PLUGIN_DIR_REL - The directory where the release versions of
+# the OGRE plugins are located
+# OGRE_PLUGIN_DIR_DBG - The directory where the debug versions of
+# the OGRE plugins are located
+# OGRE_MEDIA_DIR - The directory where the OGRE sample media is
+# located, if available
+
+include(FindPkgMacros)
+include(PreprocessorUtils)
+findpkg_begin(OGRE)
+
+
+# Get path, convert backslashes as ${ENV_${var}}
+getenv_path(OGRE_HOME)
+getenv_path(OGRE_SDK)
+getenv_path(OGRE_SOURCE)
+getenv_path(OGRE_BUILD)
+getenv_path(PROGRAMFILES)
+
+
+# Determine whether to search for a dynamic or static build
+if (OGRE_STATIC)
+ set(OGRE_LIB_SUFFIX "Static")
+else ()
+ set(OGRE_LIB_SUFFIX "")
+endif ()
+
+
+set(OGRE_LIBRARY_NAMES "OgreMain${OGRE_LIB_SUFFIX}")
+get_debug_names(OGRE_LIBRARY_NAMES)
+
+# construct search paths from environmental hints and
+# OS specific guesses
+if (WIN32)
+ set(OGRE_PREFIX_GUESSES
+ ${ENV_PROGRAMFILES}/OGRE
+ C:/OgreSDK
+ )
+elseif (UNIX)
+ set(OGRE_PREFIX_GUESSES
+ /opt/ogre
+ /opt/OGRE
+ /usr/lib/ogre
+ /usr/lib/OGRE
+ /usr/local/lib/ogre
+ /usr/local/lib/OGRE
+ $ENV{HOME}/ogre
+ $ENV{HOME}/OGRE
+ )
+endif ()
+set(OGRE_PREFIX_PATH
+ ${OGRE_HOME} ${ENV_OGRE_HOME} ${ENV_OGRE_SDK}
+ ${OGRE_PREFIX_GUESSES}
+)
+create_search_paths(OGRE)
+# If both OGRE_BUILD and OGRE_SOURCE are set, prepare to find Ogre in a build dir
+set(OGRE_PREFIX_SOURCE ${OGRE_SOURCE} ${ENV_OGRE_SOURCE})
+set(OGRE_PREFIX_BUILD ${OGRE_BUILD} ${ENV_OGRE_BUILD})
+if (OGRE_PREFIX_SOURCE AND OGRE_PREFIX_BUILD)
+ foreach(dir ${OGRE_PREFIX_SOURCE})
+ set(OGRE_INC_SEARCH_PATH ${dir}/OgreMain/include ${dir}/Dependencies/include ${OGRE_INC_SEARCH_PATH})
+ set(OGRE_LIB_SEARCH_PATH ${dir}/lib ${dir}/Dependencies/lib ${OGRE_LIB_SEARCH_PATH})
+ endforeach(dir)
+ foreach(dir ${OGRE_PREFIX_BUILD})
+ set(OGRE_INC_SEARCH_PATH ${dir}/include ${OGRE_INC_SEARCH_PATH})
+ set(OGRE_LIB_SEARCH_PATH ${dir}/lib ${OGRE_LIB_SEARCH_PATH})
+ endforeach(dir)
+else()
+ set(OGRE_PREFIX_SOURCE "NOTFOUND")
+ set(OGRE_PREFIX_BUILD "NOTFOUND")
+endif ()
+
+# redo search if any of the environmental hints changed
+set(OGRE_COMPONENTS Paging Terrain CEGUIRenderer
+ Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager
+ Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX
+ RenderSystem_Direct3D10 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES)
+set(OGRE_RESET_VARS
+ OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR
+ OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG
+ OGRE_PLUGIN_DIR_DBG OGRE_PLUGIN_DIR_REL OGRE_MEDIA_DIR)
+foreach (comp ${OGRE_COMPONENTS})
+ set(OGRE_RESET_VARS ${OGRE_RESET_VARS}
+ OGRE_${comp}_INCLUDE_DIR OGRE_${comp}_LIBRARY_FWK