iiuc gambit just lets you put c snippets in your code that can #include but the catch is that they need to be compiled before you can use them in the repl
Yeah, I'm doing something like that with my current Chicken project.
My SDL init stuff looks like this:
Code:
(foreign-declare "#include <SDL3/SDL.h>")
(define SDL_INIT_AUDIO (foreign-value "SDL_INIT_AUDIO" unsigned-integer32))
(define SDL_INIT_VIDEO (foreign-value "SDL_INIT_VIDEO" unsigned-integer32))
(define SDL_INIT_JOYSTICK (foreign-value "SDL_INIT_JOYSTICK" unsigned-integer32))
(define SDL_INIT_HAPTIC (foreign-value "SDL_INIT_HAPTIC" unsigned-integer32))
(define SDL_INIT_GAMEPAD (foreign-value "SDL_INIT_GAMEPAD" unsigned-integer32))
(define SDL_INIT_EVENTS (foreign-value "SDL_INIT_EVENTS" unsigned-integer32))
(define SDL_INIT_SENSOR (foreign-value "SDL_INIT_SENSOR" unsigned-integer32))
(define SDL_INIT_CAMERA (foreign-value "SDL_INIT_CAMERA" unsigned-integer32))
(define SDL_Init (foreign-lambda bool SDL_Init unsigned-integer32))
(define SDL_InitSubSystem (foreign-lambda bool SDL_InitSubSystem unsigned-integer32))
(define SDL_Quit (foreign-lambda void SDL_Quit))
(define SDL_QuitSubSystem (foreign-lambda void SDL_QuitSubSystem unsigned-integer32))
(define SDL_GetError (foreign-lambda c-string SDL_GetError))
This file needs to be compiled.
Also very conveniently, Chicken offers syntax called
foreign-lambda*
, which you can write a C function and supply the body as a string literal.
And actually, Chicken doesn't supply a syntax for defining accessors for C structures, so my
SDL_Event
accessors look like this:
Code:
(define SDL_Event-type
(foreign-lambda* unsigned-integer32 ((u8vector ev))
"C_return(((SDL_Event*)ev)->type);"))
(define SDL_Event-motion-xrel
(foreign-lambda* float ((u8vector ev))
"C_return(((SDL_Event*)ev)->motion.xrel);"))
(define SDL_Event-motion-yrel
(foreign-lambda* float ((u8vector ev))
"C_return(((SDL_Event*)ev)->motion.yrel);"))
In this case, I'm storing
SDL_Event
s as byte buffers (
u8vector
s) on the Chicken side. Other SDL data types (like if I was using
SDL_Surface
s), I'd let SDL itself allocate them and just handle them as pointers, but
SDL_Event
s are entirely self contained so they're a good candidate for garbage collection.
Any time a structure is simple enough that it can be allocated on the Scheme side, often that's preferable, less bookkeeping to fuck up. (Although maybe Chicken has some kind of finalizer API somewhere? idk)
Also the
C_return
is just a C macro for
return
, but Chicken's compiler implementation does some clever/funky stuff, so you need to use the special macro for stack cleanup before turning to Scheme code. But as far as I need to be concerned, it's just return.
The
SDL_Event
struct is a huge union with a bajillion members for all the different event types. I only have those three accessors defined right now. At some point I might throw together some shell scripts and see if I can generate all the accessors. But for now, I'm just defining the ones I need by hand as I find a need for them.
Right now I'm just testing click and drag of the tiles.