packages feed

Box2D-0.1.0.0: cbits/box2d_shim.h

// SPDX-License-Identifier: BSD-3-Clause
//
// Thin C shim for the Box2D Haskell bindings.
//
// The Box2D public API passes and returns several small structs *by value*,
// which GHC's FFI cannot express in general. Ids are exempt: they are
// integer-only structs of at most 8 bytes, and on the supported 64-bit ABIs
// (x86-64 SysV and Win64, AArch64) they travel in a general-purpose register
// exactly like a uint32_t/uint64_t, so the Haskell side imports id-only
// functions directly with word-sized newtypes (see the _Static_asserts in
// box2d_shim.c). Everything else — float structs, which travel in vector
// registers or by hidden reference, and the config defs — is wrapped here
// into a pointer-based form. The naming convention is hs_<original b2 name>;
// a value that was returned by value is written through a trailing
// out-pointer, and a non-id value that was passed by value is taken through
// a const in-pointer.

#pragma once

#include "box2d/box2d.h"

// base.h -----------------------------------------------------------------

// b2Version b2GetVersion(void)
void hs_b2GetVersion(b2Version* out);

// math_functions.h -------------------------------------------------------

bool hs_b2IsValidVec2(const b2Vec2* a);
bool hs_b2IsValidRot(const b2Rot* q);
bool hs_b2IsValidTransform(const b2Transform* t);
bool hs_b2IsValidAABB(const b2AABB* a);
bool hs_b2IsValidPlane(const b2Plane* a);

// b2CosSin b2ComputeCosSin(float radians)
void hs_b2ComputeCosSin(float radians, b2CosSin* out);

// b2Rot b2MakeRot(float radians)
void hs_b2MakeRot(float radians, b2Rot* out);

// types.h: default definition constructors --------------------------------

void hs_b2DefaultWorldDef(b2WorldDef* out);
void hs_b2DefaultBodyDef(b2BodyDef* out);
void hs_b2DefaultShapeDef(b2ShapeDef* out);
void hs_b2DefaultFilter(b2Filter* out);
void hs_b2DefaultSurfaceMaterial(b2SurfaceMaterial* out);
void hs_b2DefaultQueryFilter(b2QueryFilter* out);
void hs_b2DefaultChainDef(b2ChainDef* out);
void hs_b2DefaultExplosionDef(b2ExplosionDef* out);
void hs_b2DefaultDebugDraw(b2DebugDraw* out);

// The world / body by-value accessors now live in the generated
// box2d_gen_shim.{h,c} (hsg_ prefix). This file keeps only the shims backing
// the hand-written scaffolding (base.h, math_functions.h, the *Def defaults).

// types.h: joint definition defaults ---------------------------------------

void hs_b2DefaultDistanceJointDef(b2DistanceJointDef* out);
void hs_b2DefaultMotorJointDef(b2MotorJointDef* out);
void hs_b2DefaultPrismaticJointDef(b2PrismaticJointDef* out);
void hs_b2DefaultRevoluteJointDef(b2RevoluteJointDef* out);
void hs_b2DefaultWeldJointDef(b2WeldJointDef* out);
void hs_b2DefaultWheelJointDef(b2WheelJointDef* out);
void hs_b2DefaultFilterJointDef(b2FilterJointDef* out);

// chains ---------------------------------------------------------------------

// b2CreateChain leaves contact/hit events disabled on its segment shapes;
// these toggle every segment of a chain in one call instead of one FFI
// round-trip per segment.
void hs_b2Chain_EnableContactEvents(b2ChainId chainId, bool flag);
void hs_b2Chain_EnableHitEvents(b2ChainId chainId, bool flag);

// Callback trampolines: fixed C functions with the engine's callback
// signatures. The context must point at an hs_b2Closure whose fn is a
// Haskell-wrapped function of the pointer-argument variant of the signature
// and whose context is the user context it receives.

typedef struct hs_b2Closure
{
	void* fn;
	void* context;
} hs_b2Closure;

float hs_b2CastResultTrampoline(b2ShapeId shapeId, b2Pos point, b2Vec2 normal, float fraction, void* context);
bool hs_b2PreContinuousTrampoline(b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Pos point, b2Vec2 normal, void* context);

// b2DebugDraw trampolines. The struct's ten callback slots share one context
// field, so they take a wider closure than hs_b2Closure: one Haskell-wrapped
// function per slot, in the declaration order of b2DebugDraw, followed by the
// user context. A NULL slot draws nothing.

typedef struct hs_b2DrawClosure
{
	void* polygon;
	void* solidPolygon;
	void* circle;
	void* solidCircle;
	void* solidCapsule;
	void* line;
	void* transform;
	void* point;
	void* string;
	void* bounds;
	void* context;
} hs_b2DrawClosure;

void hs_b2DrawPolygonTrampoline(b2WorldTransform transform, const b2Vec2* vertices, int vertexCount, b2HexColor color,
								void* context);
void hs_b2DrawSolidPolygonTrampoline(b2WorldTransform transform, const b2Vec2* vertices, int vertexCount, float radius,
									 b2HexColor color, void* context);
void hs_b2DrawCircleTrampoline(b2Pos center, float radius, b2HexColor color, void* context);
void hs_b2DrawSolidCircleTrampoline(b2WorldTransform transform, b2Vec2 center, float radius, b2HexColor color,
									void* context);
void hs_b2DrawSolidCapsuleTrampoline(b2Pos p1, b2Pos p2, float radius, b2HexColor color, void* context);
void hs_b2DrawLineTrampoline(b2Pos p1, b2Pos p2, b2HexColor color, void* context);
void hs_b2DrawTransformTrampoline(b2WorldTransform transform, void* context);
void hs_b2DrawPointTrampoline(b2Pos p, float size, b2HexColor color, void* context);
void hs_b2DrawStringTrampoline(b2Pos p, const char* s, b2HexColor color, void* context);
void hs_b2DrawBoundsTrampoline(b2AABB aabb, b2HexColor color, void* context);