1. JoltC HelloWorld Example Help [UPDATED 7/3/24]
- Posted by Icy_Viking Jun 30, 2024
- 1124 views
- Last edited Jul 03, 2024
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()
2. Re: JoltC HelloWorld Example Help [UPDATED 7/3/24]
- Posted by Icy_Viking Jul 02, 2024
- 969 views
- Last edited Jul 03, 2024
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.

