# Copyright (C) 2009  Peter De Wachter <pdewacht@gmail.com>
# Distributed under the same license as the game. See debian/copyright.

This is an attempt to make mu-cade compatible with libode 2:0.10.1-1

--- a/import/ode/common.d
+++ b/import/ode/common.d
@@ -69,8 +69,8 @@
 
 /* floating point data type, vector, matrix and quaternion types */
 
-//alias double dReal;
-alias float dReal;
+alias double dReal;
+//alias float dReal;
 
 /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
  * (used to compute matrix leading dimensions)
@@ -256,6 +256,7 @@
   dParamSuspensionCFM,
 
 #define D_ALL_PARAM_NAMES_X(start,x) \
+  dParamGroup ## x = start, \
   /* parameters for limits and motors */ \
   dParamLoStop ## x = start, \
   dParamHiStop ## x, \
@@ -272,6 +273,8 @@
 
 enum {
   D_ALL_PARAM_NAMES(0)
+  dParamsInGroup,
+  D_ALL_PARAM_NAMES_X(0x000,1)
   D_ALL_PARAM_NAMES_X(0x100,2)
   D_ALL_PARAM_NAMES_X(0x200,3)
 
--- a/import/ode/collision.d
+++ b/import/ode/collision.d
@@ -79,16 +79,19 @@
 enum {
   dSphereClass = 0,
   dBoxClass,
-  dCCylinderClass,
+  dCapsuleClass,
   dCylinderClass,
   dPlaneClass,
   dRayClass,
+  dConvexClass,
   dGeomTransformClass,
   dTriMeshClass,
+  dHeightfieldClass,
 
   dFirstSpaceClass,
   dSimpleSpaceClass = dFirstSpaceClass,
   dHashSpaceClass,
+  dSweepAndPruneSpaceClass,
   dQuadTreeSpaceClass,
   dLastSpaceClass = dQuadTreeSpaceClass,
 
@@ -155,6 +158,7 @@
 		    dMatrix3 R2, dVector3 side2);
 
 void dInfiniteAABB (dGeomID geom, dReal aabb[6]);
+void dInitODE();
 void dCloseODE();
 
 /* ************************************************************************ */
--- a/import/ode/mass.d
+++ b/import/ode/mass.d
@@ -62,6 +62,6 @@
 
 struct dMass {
   dReal mass;
-  dVector4 c;
+  dVector3 c;
   dMatrix3 I;
 };
--- a/import/ode/contact.d
+++ b/import/ode/contact.d
@@ -33,8 +33,9 @@
   dContactSoftCFM	= 0x010,
   dContactMotion1	= 0x020,
   dContactMotion2	= 0x040,
-  dContactSlip1		= 0x080,
-  dContactSlip2		= 0x100,
+  dContactMotionN       = 0x080,
+  dContactSlip1		= 0x100,
+  dContactSlip2		= 0x200,
 
   dContactApprox0	= 0x0000,
   dContactApprox1_1	= 0x1000,
@@ -42,37 +43,77 @@
   dContactApprox1	= 0x3000
 };
 
-
-struct dSurfaceParameters {
-  /* must always be defined */
-  int mode;
-  dReal mu;
-
-  /* only defined if the corresponding flag is set in mode */
-  dReal mu2;
-  dReal bounce;
-  dReal bounce_vel;
-  dReal soft_erp;
-  dReal soft_cfm;
-  dReal motion1,motion2;
-  dReal slip1,slip2;
-};
-
+version(X86) {
+  // gdc is supposed to use the same struct layout as gcc, but it
+  // doesn't do that for this struct on i386. (It seems to think
+  // doubles need an 8 byte alignment.) So we introduce this hack.
+  align(1)
+  struct dSurfaceParameters {
+    /* must always be defined */
+    int mode;
+    dReal mu;
+
+    /* only defined if the corresponding flag is set in mode */
+    dReal mu2;
+    dReal bounce;
+    dReal bounce_vel;
+    dReal soft_erp;
+    dReal soft_cfm;
+    dReal motion1,motion2,motionN;
+    dReal slip1,slip2;
+  };
+} else {
+  struct dSurfaceParameters {
+    /* must always be defined */
+    int mode;
+    dReal mu;
+
+    /* only defined if the corresponding flag is set in mode */
+    dReal mu2;
+    dReal bounce;
+    dReal bounce_vel;
+    dReal soft_erp;
+    dReal soft_cfm;
+    dReal motion1,motion2,motionN;
+    dReal slip1,slip2;
+  };
+}
 
 /* contact info set by collision functions */
 
-struct dContactGeom {
-  dVector3 pos;
-  dVector3 normal;
-  dReal depth;
-  dGeomID g1,g2;
-};
+version(X86) {
+  align(1)
+  struct dContactGeom {
+    dVector3 pos;
+    dVector3 normal;
+    dReal depth;
+    dGeomID g1,g2;
+    int side1,side2;
+  };
+} else {
+  struct dContactGeom {
+    dVector3 pos;
+    dVector3 normal;
+    dReal depth;
+    dGeomID g1,g2;
+    int side1,side2;
+  };
+}
 
 
 /* contact info used by contact joint */
 
-struct dContact {
-  dSurfaceParameters surface;
-  dContactGeom geom;
-  dVector3 fdir1;
-};
+version(X86) {
+  align(1)
+  struct dContact {
+    dSurfaceParameters surface;
+    dContactGeom geom;
+    dVector3 fdir1;
+  };
+} else {
+  struct dContact {
+    dSurfaceParameters surface;
+    dContactGeom geom;
+    dVector3 fdir1;
+  };
+}
--- a/src/abagames/util/ode/world.d
+++ b/src/abagames/util/ode/world.d
@@ -41,6 +41,7 @@
   bool initialized = false;
 
   public void init() {
+    dInitODE();
     world = dWorldCreate();
     dWorldSetContactMaxCorrectingVel(world, CONTACT_MAX_CORRECTING_VEL);
     dWorldSetContactSurfaceLayer (world, CONTACT_SURFACE_LAYER);
