1. JoltC HelloWorld Example Help [UPDATED 7/3/24]

Hi all,

I have finished writing my JoltC wrapper, well almost. I just need a little help getting the hello world example done. I've used Greg's FFI Euphoria library to help with wrapping structs and such. I'm a bit confused on how I'd wrap the functions that are declared as static in the C Hello world example. I've shared what I've done so far. If you need more wrapper code, let me know. Wrapper is base off of this JoltC port, https://github.com/SecondHalfGames/JoltC

EDIT: Updated code. Nothing shows up on screen, but appears to run without any errors.

// C Hello World Example 
#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 
 
#include "JoltC/JoltC.h" 
 
#ifdef _MSC_VER 
	#define unreachable() __assume(0) 
#else 
	#define unreachable() __builtin_unreachable() 
#endif 
 
typedef enum Hello_ObjectLayers { 
	HELLO_OL_NON_MOVING, 
	HELLO_OL_MOVING, 
	HELLO_OL_COUNT, 
} Hello_ObjectLayers; 
 
typedef enum Hello_BroadPhaseLayers { 
	HELLO_BPL_NON_MOVING, 
	HELLO_BPL_MOVING, 
	HELLO_BPL_COUNT, 
} Hello_BroadPhaseLayers; 
 
unsigned int Hello_BPL_GetNumBroadPhaseLayers(const void *self) { 
	return HELLO_BPL_COUNT; 
} 
 
JPC_BroadPhaseLayer Hello_BPL_GetBroadPhaseLayer(const void *self, JPC_ObjectLayer inLayer) { 
	switch (inLayer) { 
	case HELLO_OL_NON_MOVING: 
		return HELLO_BPL_NON_MOVING; 
 
	case HELLO_OL_MOVING: 
		return HELLO_BPL_MOVING; 
 
	default: 
		unreachable(); 
	} 
} 
 
static JPC_BroadPhaseLayerInterfaceFns Hello_BPL = { //Having trouble figuring out to wrap this into Eu code 
	.GetNumBroadPhaseLayers = Hello_BPL_GetNumBroadPhaseLayers, 
	.GetBroadPhaseLayer = Hello_BPL_GetBroadPhaseLayer, 
}; 
 
bool Hello_OVB_ShouldCollide(const void *self, JPC_ObjectLayer inLayer1, JPC_BroadPhaseLayer inLayer2) { 
	switch (inLayer1) { 
	case HELLO_OL_NON_MOVING: 
		return inLayer2 == HELLO_BPL_MOVING; 
 
	case HELLO_OL_MOVING: 
		return true; 
 
	default: 
		unreachable(); 
	} 
} 
 
static JPC_ObjectVsBroadPhaseLayerFilterFns Hello_OVB = { 
	.ShouldCollide = Hello_OVB_ShouldCollide, 
}; 
 
bool Hello_OVO_ShouldCollide(const void *self, JPC_ObjectLayer inLayer1, JPC_ObjectLayer inLayer2) { 
	switch (inLayer1) 
	{ 
	case HELLO_OL_NON_MOVING: 
		return inLayer2 == HELLO_OL_MOVING; // Non moving only collides with moving 
 
	case HELLO_OL_MOVING: 
		return true; // Moving collides with everything 
 
	default: 
		unreachable(); 
	} 
} 
 
static JPC_ObjectLayerPairFilterFns Hello_OVO = { 
	.ShouldCollide = Hello_OVO_ShouldCollide, 
}; 
 
void Hello_Debug_DrawLine(const void *self, JPC_RVec3 inFrom, JPC_RVec3 inTo, JPC_Color inColor) { 
	// printf("Draw line from (%f, %f, %f) to (%f, %f, %f) with color (%d, %d, %d)\n", 
	// 	inFrom.x, inFrom.y, inFrom.z, inTo.x, inTo.y, inTo.z, inColor.r, inColor.g, inColor.b); 
} 
 
static JPC_DebugRendererSimpleFns Hello_DebugRenderer = { 
	.DrawLine = Hello_Debug_DrawLine, 
}; 
 
int main() { 
	JPC_RegisterDefaultAllocator(); 
	JPC_FactoryInit(); 
	JPC_RegisterTypes(); 
 
	JPC_TempAllocatorImpl* temp_allocator = JPC_TempAllocatorImpl_new(10 * 1024 * 1024); 
 
	JPC_JobSystemThreadPool* job_system = JPC_JobSystemThreadPool_new2(JPC_MAX_PHYSICS_JOBS, JPC_MAX_PHYSICS_BARRIERS); 
 
	JPC_BroadPhaseLayerInterface* broad_phase_layer_interface = JPC_BroadPhaseLayerInterface_new(nullptr, Hello_BPL); 
	JPC_ObjectVsBroadPhaseLayerFilter* object_vs_broad_phase_layer_filter = JPC_ObjectVsBroadPhaseLayerFilter_new(nullptr, Hello_OVB); 
	JPC_ObjectLayerPairFilter* object_vs_object_layer_filter = JPC_ObjectLayerPairFilter_new(nullptr, Hello_OVO); 
 
	const unsigned int cMaxBodies = 1024; 
	const unsigned int cNumBodyMutexes = 0; 
	const unsigned int cMaxBodyPairs = 1024; 
	const unsigned int cMaxContactConstraints = 1024; 
 
	JPC_PhysicsSystem* physics_system = JPC_PhysicsSystem_new(); 
	JPC_PhysicsSystem_Init( 
		physics_system, 
		cMaxBodies, 
		cNumBodyMutexes, 
		cMaxBodyPairs, 
		cMaxContactConstraints, 
		broad_phase_layer_interface, 
		object_vs_broad_phase_layer_filter, 
		object_vs_object_layer_filter); 
 
	// TODO: register body activation listener 
	// TODO: register contact listener 
 
	JPC_BodyInterface* body_interface = JPC_PhysicsSystem_GetBodyInterface(physics_system); 
 
	JPC_BoxShapeSettings floor_shape_settings; 
	JPC_BoxShapeSettings_default(&floor_shape_settings); 
	floor_shape_settings.HalfExtent = JPC_Vec3{100.0f, 1.0f, 100.0f}; 
	floor_shape_settings.Density = 500.0; 
 
	JPC_Shape* floor_shape; 
	JPC_String* err; 
	if (!JPC_BoxShapeSettings_Create(&floor_shape_settings, &floor_shape, &err)) { 
		printf("fatal error: %s\n", JPC_String_c_str(err)); 
 
		// the world is ending, but I guess we can still free memory 
		JPC_String_delete(err); 
 
		exit(1); 
	} 
 
	JPC_BodyCreationSettings floor_settings; 
	JPC_BodyCreationSettings_default(&floor_settings); 
	floor_settings.Position = JPC_RVec3{0.0, -1.0, 0.0}; 
	floor_settings.MotionType = JPC_MOTION_TYPE_STATIC; 
	floor_settings.ObjectLayer = HELLO_OL_NON_MOVING; 
	floor_settings.Shape = floor_shape; 
 
	JPC_Body* floor = JPC_BodyInterface_CreateBody(body_interface, &floor_settings); 
	JPC_BodyInterface_AddBody(body_interface, JPC_Body_GetID(floor), JPC_ACTIVATION_DONT_ACTIVATE); 
 
	JPC_SphereShapeSettings sphere_shape_settings; 
	JPC_SphereShapeSettings_default(&sphere_shape_settings); 
	sphere_shape_settings.Radius = 0.5; 
 
	JPC_Shape* sphere_shape; 
	if (!JPC_SphereShapeSettings_Create(&sphere_shape_settings, &sphere_shape, &err)) { 
		printf("fatal error: %s\n", JPC_String_c_str(err)); 
 
		// the world is ending, but I guess we can still free memory 
		JPC_String_delete(err); 
 
		exit(1); 
	} 
 
	JPC_BodyCreationSettings sphere_settings; 
	JPC_BodyCreationSettings_default(&sphere_settings); 
	sphere_settings.Position = JPC_RVec3{0.0, 2.0, 0.0}; 
	sphere_settings.MotionType = JPC_MOTION_TYPE_DYNAMIC; 
	sphere_settings.ObjectLayer = HELLO_OL_MOVING; 
	sphere_settings.Shape = sphere_shape; 
 
	JPC_Body* sphere = JPC_BodyInterface_CreateBody(body_interface, &sphere_settings); 
	JPC_BodyID sphere_id = JPC_Body_GetID(sphere); 
	JPC_BodyInterface_AddBody(body_interface, sphere_id, JPC_ACTIVATION_ACTIVATE); 
 
	JPC_BodyInterface_SetLinearVelocity(body_interface, sphere_id, JPC_Vec3{0.0, -5.0, 0.0}); 
 
	JPC_DebugRendererSimple* debug_renderer = JPC_DebugRendererSimple_new(nullptr, Hello_DebugRenderer); 
	JPC_BodyManager_DrawSettings draw_settings; 
	JPC_BodyManager_DrawSettings_default(&draw_settings); 
	JPC_PhysicsSystem_DrawBodies(physics_system, &draw_settings, debug_renderer, nullptr); 
 
	JPC_PhysicsSystem_OptimizeBroadPhase(physics_system); 
 
	const float cDeltaTime = 1.0f / 60.0f; 
	const int cCollisionSteps = 1; 
 
	int step = 0; 
	while (JPC_BodyInterface_IsActive(body_interface, sphere_id)) { 
		++step; 
 
		JPC_RVec3 position = JPC_BodyInterface_GetCenterOfMassPosition(body_interface, sphere_id); 
		JPC_Vec3 velocity = JPC_BodyInterface_GetLinearVelocity(body_interface, sphere_id); 
 
		printf("Step %d: Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", step, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z); 
 
		JPC_PhysicsSystem_Update(physics_system, cDeltaTime, cCollisionSteps, temp_allocator, job_system); 
	} 
 
	JPC_BodyInterface_RemoveBody(body_interface, sphere_id); 
	JPC_BodyInterface_DestroyBody(body_interface, sphere_id); 
 
	JPC_BodyInterface_RemoveBody(body_interface, JPC_Body_GetID(floor)); 
	JPC_BodyInterface_DestroyBody(body_interface, JPC_Body_GetID(floor)); 
 
	JPC_PhysicsSystem_delete(physics_system); 
	JPC_BroadPhaseLayerInterface_delete(broad_phase_layer_interface); 
	JPC_ObjectVsBroadPhaseLayerFilter_delete(object_vs_broad_phase_layer_filter); 
	JPC_ObjectLayerPairFilter_delete(object_vs_object_layer_filter); 
 
	JPC_JobSystemThreadPool_delete(job_system); 
	JPC_TempAllocatorImpl_delete(temp_allocator); 
 
	JPC_UnregisterTypes(); 
	JPC_FactoryDelete(); 
 
	printf("Hello, world!\n"); 
} 

--Parts JoltC Wrapper Eu Code 
include std/ffi.e 
include std/machine.e 
include std/os.e 
 
public atom jolt 
 
ifdef WINDOWS then 
	jolt = open_dll("joltc.dll") 
	elsifdef LINUX or FREEBSD then 
	jolt = open_dll("libjoltc.so") 
	elsifdef OSX then 
	jolt = open_dll("libjoltc.dylib") 
end ifdef 
 
if jolt = 0 then 
	puts(1,"Failed to load JoltC DLL!\n") 
	abort(0) 
end if 
 
public constant JPC_BroadPhaseLayerInterfaceFns = define_c_struct({ 
	C_POINTER, --GetNumBroadPhaseLayers 
	C_POINTER, --self (*GetNumBroadPhaseLayers)(const void *self); 
	C_POINTER, --GetBroadphaseLayer 
	C_POINTER, --self (*GetBroadPhaseLayer)(const void *self, JPC_ObjectLayer inLayer); 
	C_UINT32 --inLayer JPC_ObjectLayer 
}) 
 
public constant xJPC_BroadPhaseLayerInterface_new = define_c_func(jolt,"+JPC_BroadPhaseLayerInterface_new",{C_POINTER,JPC_BroadPhaseLayerInterfaceFns},C_POINTER), 
				xJPC_BroadPhaseLayerInterface_delete = define_c_proc(jolt,"+JPC_BroadPhaseLayerInterface_delete",{C_POINTER}) 
				 
public function JPC_BroadPhaseLayerInterface_new(atom self,sequence fns) 
	return c_func(xJPC_BroadPhaseLayerInterface_new,{self,fns}) 
end function 
 
public procedure JPC_BroadPhaseLayerInterface_delete(atom obj) 
	c_proc(xJPC_BroadPhaseLayerInterface_delete,{obj}) 
end procedure 
 
--ObjectLayerFilter 
 
public constant JPC_ObjectLayerFilterFns = define_c_struct({ 
	C_POINTER, --shouldCollide 
	C_POINTER, --self 
	JPC_ObjectLayer --inLayer 
}) 
 
public constant xJPC_ObjectLayerFilter_new = define_c_func(jolt,"+JPC_ObjectLayerFilter_new",{C_POINTER,JPC_ObjectLayerFilterFns},C_POINTER), 
				xJPC_ObjectLayerFilter_delete = define_c_proc(jolt,"+JPC_ObjectLayerFilter_delete",{C_POINTER}) 
				 
public function JPC_ObjectLayerFilter_new(atom self,sequence fns) 
	return c_func(xJPC_ObjectLayerFilter_new,{self,fns}) 
end function 
 
public procedure JPC_ObjectLayerFilter_delete(atom obj) 
	c_proc(xJPC_ObjectLayerFilter_delete,{obj}) 
end procedure 
--Hello World Example Eu code 
include std/ffi.e 
include std/machine.e 
 
include joltc.e 
 
public constant TRUE = 1, FALSE = 0 
 
public enum type Hello_ObjectLayers 
	HELLO_OL_NON_MOVING = 0, 
	HELLO_OL_MOVING, 
	HELLO_OL_COUNT 
end type 
 
public enum type Hello_BroadPhaseLayers 
	HELLO_BPL_NON_MOVING = 0, 
	HELLO_BPL_MOVING, 
	HELLO_BPL_COUNT 
end type 
 
public function Hello_BPL_GetNumBroadPhaseLayers() 
	return HELLO_BPL_COUNT 
end function 
 
public function Hello_BPL_GetBroadPhaseLayer(atom inLayer) 
	switch inLayer do 
	case HELLO_OL_NON_MOVING then 
		return HELLO_BPL_NON_MOVING 
	case HELLO_OL_MOVING then 
		return HELLO_BPL_MOVING 
	end switch 
end function 
 
atom Hello_BPL = allocate_struct(JPC_BroadPhaseLayerInterfaceFns) 
atom Hello_BPL_id = routine_id("Hello_BPL_GetNumBroadPhaseLayers") 
atom Hello_BPL_id2 = routine_id("Hello_BPL_GetBroadPhaseLayer") 
 
peek_struct(call_back(Hello_BPL_id),Hello_BPL) 
peek_struct(call_back(Hello_BPL_id2),Hello_BPL) 
 
public function Hello_OVB_ShouldCollide(atom inLayer1,atom inLayer2) 
	switch(inLayer1) do 
	case HELLO_OL_NON_MOVING then 
		return inLayer2 = HELLO_BPL_MOVING 
		 
	case HELLO_OL_MOVING then 
		return TRUE 
	end switch 
end function 
 
atom Hello_OVB = allocate_struct(JPC_ObjectVsBroadPhaseLayerFilterFns) 
atom Hello_OVB_id = routine_id("Hello_OVB_ShouldCollide") 
peek_struct(call_back(Hello_OVB_id),Hello_OVB) 
 
public function Hello_OVO_ShouldCollide(atom inLayer1,atom inLayer2) 
	switch inLayer1 do 
	case HELLO_OL_NON_MOVING then 
		return inLayer2 = HELLO_OL_MOVING 
	case HELLO_OL_MOVING then 
		return TRUE 
	end switch 
end function 
 
public atom Hello_OVO = allocate_struct(JPC_ObjectLayerPairFilterFns) 
atom Hello_OVO_id = routine_id("Hello_OVO_ShouldCollide") 
peek_struct(call_back(Hello_OVO_id),JPC_ObjectLayerPairFilterFns) 
 
public procedure main() 
	JPC_RegisterDefaultAllocator() 
	JPC_FactoryInit() 
	JPC_RegisterTypes() 
	 
	atom temp_allocator = JPC_TempAllocatorImpl_new(10 * 1024 * 1024) 
	 
	atom job_system = JPC_JobSystemThreadPool_new2(JPC_MAX_PHYSICS_JOBS,JPC_MAX_PHYSICS_BARRIERS) 
	 
	atom broad_phase_layer_interface = JPC_BroadPhaseLayerInterface_new(NULL,peek_struct(C_POINTER,JPC_BroadPhaseLayerInterfaceFns)) 
	atom object_vs_broad_phase_layer_filter = JPC_ObjectVsBroadPhaseLayerFilter_new(NULL,peek_struct(C_POINTER,JPC_ObjectVsBroadPhaseLayerFilterFns)) 
	atom object_vs_object_layer_filter = JPC_ObjectLayerPairFilter_new(NULL,peek_struct(C_POINTER,JPC_ObjectLayerPairFilterFns)) 
	 
	atom cMaxBodies = 1024 
	atom cNumBodyMutexes = 0 
	atom cMaxBodyPairs = 1024 
	atom cMaxContactConstraints = 1024 
	 
	atom physics_system = JPC_PhysicsSystem_new() 
	 
	JPC_PhysicsSystem_Init(physics_system,cMaxBodies,cNumBodyMutexes,cMaxBodyPairs,cMaxContactConstraints,broad_phase_layer_interface,object_vs_broad_phase_layer_filter,object_vs_object_layer_filter) 
	 
	atom body_interface = JPC_PhysicsSystem_GetBodyInterface(physics_system) 
	 
	object floor_shape_settings = JPC_BoxShapeSettings 
	JPC_BoxShapeSettings_default(floor_shape_settings) 
	floor_shape_settings[3] = {100.0,1.0,100.0} 
	floor_shape_settings[2] = 500.0 
	 
	atom floor_shape 
	if JPC_BoxShapeSettings_Create(floor_shape_settings,floor_shape,NULL) = -1 then 
		puts(1,"Failed to create shape!\n") 
	end if 
	 
	atom floor_settings = JPC_BodyCreationSettings 
	JPC_BodyCreationSettings_default(floor_settings) 
	floor_settings[1] = {0.0,-1.0,0.0} --floor_settings.position 
	floor_settings[7] = JPC_MOTION_TYPE_STATIC --floor_settings.MotionType 
	floor_settings[6] = HELLO_OL_NON_MOVING --floor_settings.ObjectLayer 
	floor_settings[28] = floor_shape --floor_settings.Shape 
	 
	atom static_floor = JPC_BodyInterface_CreateBody(body_interface,floor_settings) 
	JPC_BodyInterface_AddBody(body_interface,JPC_Body_GetID(static_floor),JPC_ACTIVATION_DONT_ACTIVATE) 
	 
	atom sphere_shape_settings = JPC_SphereShapeSettings 
	JPC_SphereShapeSettings_default(sphere_shape_settings) 
	sphere_shape_settings[3] = 0.5 --sphere_shape_settings.radius 
	 
	atom sphere_shape 
	if JPC_SphereShapeSettings_Create(sphere_shape_settings,sphere_shape,NULL) = -1 then 
		puts(1,"Failed to create sphere!\n") 
	end if 
	 
	atom sphere_settings = JPC_BodyCreationSettings 
	JPC_BodyCreationSettings_default(sphere_settings) 
	sphere_settings[1] = {0.0,2.0,0.0} 
	sphere_settings[7] = JPC_MOTION_TYPE_DYNAMIC 
	sphere_settings[6] = HELLO_OL_MOVING 
	sphere_settings[28] = sphere_shape 
	 
	atom sphere = JPC_BodyInterface_CreateBody(body_interface,sphere_settings) 
	atom sphere_id = JPC_Body_GetID(sphere) 
	JPC_BodyInterface_AddBody(body_interface,sphere_id,JPC_ACTIVATION_ACTIVATE) 
	 
	JPC_BodyInterface_SetLinearVelocity(body_interface,sphere_id,{0,0,-5.0,0.0}) 
	 
	JPC_PhysicsSystem_OptimizeBroadPhase(physics_system) 
	 
	atom cDeltaTime = 1.0 / 60.0 
	atom cCollisionSteps = 1 
	 
	atom step = 0 
	while JPC_BodyInterface_IsActive(body_interface,sphere_id) do 
		step += 1 
		 
		sequence pos = JPC_BodyInterface_GetCenterOfMassPosition(body_interface,sphere_id) 
		sequence vel = JPC_BodyInterface_GetLinearVelocity(body_interface,sphere_id) 
		 
			printf(1,"Steps: %d, Pos: %f, %f, %f, Vel = %f, %f, %f\n",{step,pos[1],pos[2],pos[3],vel[1],vel[2],vel[3]}) 
		 
		JPC_PhysicsSystem_Update(physics_system,cDeltaTime,cCollisionSteps,temp_allocator,job_system) 
	end while 
	 
	JPC_BodyInterface_RemoveBody(body_interface,sphere_id) 
	JPC_BodyInterface_DestroyBody(body_interface,sphere_id) 
	 
	JPC_BodyInterface_RemoveBody(body_interface,JPC_Body_GetID(static_floor)) 
	JPC_BodyInterface_DestroyBody(body_interface,JPC_Body_GetID(static_floor)) 
	 
	JPC_PhysicsSystem_delete(physics_system) 
	JPC_BroadPhaseLayerInterface_delete(broad_phase_layer_interface) 
	JPC_ObjectVsBroadPhaseLayerFilter_delete(object_vs_broad_phase_layer_filter) 
	JPC_ObjectLayerPairFilter_delete(object_vs_object_layer_filter) 
	 
	JPC_JobSystemThreadPool_delete(job_system) 
	JPC_TempAllocatorImpl_delete(temp_allocator) 
	 
	JPC_UnregisterTypes() 
	JPC_FactoryDelete() 
	 
end procedure 
	 
main() 
new topic     » topic index » view message » categorize

2. Re: JoltC HelloWorld Example Help [UPDATED 7/3/24]

I've released the wrapper code for now. Repo is private for now. DLLs are 32-bit.

https://github.com/gAndy50/EuJolt

Made repo public, thought giving the link would allow others to see if I shared it, even with the repo being private.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu