racket-sdl
racket-sdl copied to clipboard
How use event ?
I don't understand how use SDL_Event and SDL_PollEvent, could you make a third example file with this C program converted in racket ? How define an event variable with SDL_Event type ? And how use SDL_PollEvent with ?
int done = 0;
SDL_Event event;
while(done == 0)
{
while ( SDL_PollEvent(&event) )
{
switch(event.type)
{
case SDL_QUIT :
done = 1;
break;
default :
print("Event not available\n");
}
/* something */
// ...
}
}
This fork has more examples available https://github.com/stonecauldron/racket-sdl/blob/master/lazyfoo/lazyfoo03.rkt
@adamlwgriffiths That fork does not exist anymore.
Update: See my second comment, below.
After reading http://planet.racket-lang.org/package-source/pb82/sdl4racket.plt/1/0/src/sdl4racket.rkt
(define event (malloc 128)) ; I don't know why this is `128`
(cpointer-push-tag! event 'SDL_Event*)
(let loop ()
(SDL_PollEvent event)
; Do stuff with event...
)
NOTE: SDL2 on OS X Mojave has a known issue where you will need to call:
(SDL_PumpEvents)
(SDL_SetWindowSize window 640 400) ; Change to your liking
before your event loop, otherwise the title bar may be screwed up and graphics may not render.
UPDATE: It turns out that libffi, which Racket (and other languages) use for C dynamic library integration doesn't support unions per se, and instead the size passed to malloc
should be the size of the greatest struct or other type that is a member of the union. In this case 128
is significantly larger than the number of bytes needed for any event type, which is why it works. FWIW, 64
works as well. Hard-coding a "safe" number here seems best when unions are involved, until libffi supports unions natively. See https://github.com/libffi/libffi/issues/33
It turns out, after a ton of digging, I was wrong. You can malloc
the struct to the correct size, and you can access fields inside. Here's an example of getting the keycode of the pressed key:
#lang racket/base
(require ffi/unsafe
ffi/unsafe/define
; Replace with your `racket-sdl` `require` line
"racket-sdl/sdl/definitions.rkt"
"racket-sdl/sdl/constants.rkt"
"racket-sdl/sdl/structs.rkt")
(define _SDL_KEYDOWN_TYPE (cast 'SDL_KEYDOWN _SDL_EventType _int))
(define _SDL_EVENT_TYPE_OFFSET 0)
(define _SDL_KEYBOARDEVENT_OFFSET 3)
(module* main #f
(SDL_Init SDL_INIT_EVERYTHING)
(let* ([window (SDL_CreateWindow "Foo"
SDL_WINDOWPOS_CENTERED
SDL_WINDOWPOS_CENTERED
640
480
'SDL_WINDOW_SHOWN)]
[surface (SDL_GetWindowSurface window)]
[event-ptr (malloc (ctype-sizeof _SDL_Event))]
[event (cast event-ptr _pointer _SDL_Event*)])
(let loop ()
(let check-events ()
(when (> (SDL_PollEvent event) 0)
(let* ([event-ref (ptr-ref event _SDL_Event 0)]
[type (union-ref event-ref _SDL_EVENT_TYPE_OFFSET)])
(when (equal? type _SDL_KEYDOWN_TYPE)
(let* ([keyboard-event (union-ref event-ref _SDL_KEYBOARDEVENT_OFFSET)]
[sym (SDL_Keysym-sym (SDL_KeyboardEvent-keysym keyboard-event))])
(printf "pressed ~s\n" sym)))
(check-events))))
(SDL_Delay 20)
(loop))))
Requires some changes that are currently in this PR (https://github.com/cosmez/racket-sdl/pull/8). So use that branch to run this example for now.
Update: As per @lockie's comment, I changed (ctype-sizeof _SDL_Event*)
to (ctype-sizeof _SDL_Event)
above.
@rjungemann Sorry to interrupt, but this particular line looks fishy:
[event-ptr (malloc (ctype-sizeof _SDL_Event*))]
You're allocating 8 bytes of memory (on 64-bit machine, that is) when SDL_Event
actually occupies 56 bytes of memory space (as the simple printf("%d\n", sizeof(SDL_Event))
C program indicates).
From the looks of it, the line should read
[event-ptr (malloc (ctype-sizeof _SDL_Event))]
(correct me if I'm wrong!)
Hey @lockie I believe you are correct! Amending my comments
@rjungemann All right, thanks. You might also want to do the same change in your PR #8