So the way my one is working is like this C (inside my lisp):
const Uint8 state; state = SDL_GetKeyboardState(NULL); if ( state[SDL_SCANCODE_UP] ) printf("Up is currently held down");
I'm not sure what that looks like in your lisp binding though!
In Lisp I use with-event-loop from cl-sdl2, like this:
(with-event-loop (:method :poll) (:keydown (:keysym keysym) (let ((scancode (scancode-value keysym))) (cond ((scancode= scancode :scancode-space) (format t "Playing Song~%") (sdl2-mixer:play-music music 1)) ((scancode= scancode :scancode-up) (when (< (+ *current-volume* 20) 128) (incf *current-volume* 20) (format t "Current Volume: ~a~%" *current-volume*) (sdl2-mixer:volume-music *current-volume*))) ((scancode= scancode :scancode-down) (when (> (- *current-volume* 20) 0) (decf *current-volume* 20) (format t "Current Volume: ~a~%" *current-volume*) (sdl2-mixer:volume-music *current-volume*)))))) ......
I think the above code is just like some of your code here :
for (;;) {" " while(SDL_PollEvent(&e)) if (e.type == SDL_QUIT) quitted = 1; else if (e.type == SDL_KEYDOWN) switch (e.key.keysym.sym) { case SDLK_q: quitted = 1; break; }
I didn't handle the "holding down" action specifically, so I haven't used something like SDL_GetKeyboardState.
If I were going to do it, I could use the function `keyboard-state-p` as defined here:
(defun keyboard-state-p (scancode) "Whether the key corresponding to the given scancode is currently pressed." (let ((state (nth-value 1 (autowrap:inhibit-string-conversion (sdl2-ffi.functions:sdl-get-keyboard-state nil)))) (scancode-num (autowrap:enum-value 'sdl2-ffi:sdl-scancode scancode))) (c-let ((state :unsigned-char :ptr state)) (= (state scancode-num) 1))))I can see that you're using ECL SFFI in your code, which involves writing C in Lisp, why not using UFFI or CFFI, since it will give us a more Lispy programming experience? Just being curious, because I feel C is too intimidating to me.
In some of my deployment contexts I have found ECL (ie just a C lib) more often supported than cffi, and I am somewhat used to C (it's a domain specific language for working with C operating systems in lisp, right).
I guess the c2ffi autogenerated stuff is nice and complete, on the other hand I think a la carte is also nice (alright, maybe shouldn't call writing C nice...).
Edit: For example if I were to want to conditionally pledge my game on openbsd in ecl :
#+(and openbsd ecl) (progn (ffi:clines "#include <unistd.h>") (let ((ret 0)) (declare (:int ret)) (ffi:c-progn (ret) "#0 = pledge(\"stdio rpath\", NULL);" (unless (zerop ret) (error "pledge")))) (mapc 'print (directory #p"./*.*")) (uiop:quit)
it's not clear to me that I would have gained a lot by dragging in https://github.com/cffi-posix/cffi-pledge . Though this example shows how gnarly sffi is too I guess !
Ah, BSD pledge! This is so elegant, I never heard of it before. Once I used FreeBSD as the OS of my PC but uninstalled due to some lack of WiFi drivers reason, but I still remember the clean and tidy FreeBSD Handbook, quite nice.
"a la carte" is indeed nice, you could deliver your work in a thin and slim way, as for CFFI, I have to pack all those .so/.dylib/.dll with my game, which is kind of over "table d'hôte".