racket-sdl icon indicating copy to clipboard operation
racket-sdl copied to clipboard

How use event ?

Open MrSiuol opened this issue 8 years ago • 7 comments

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 */
             // ...
      }
    }

MrSiuol avatar Dec 02 '16 21:12 MrSiuol

This fork has more examples available https://github.com/stonecauldron/racket-sdl/blob/master/lazyfoo/lazyfoo03.rkt

adamlwgriffiths avatar Apr 22 '18 10:04 adamlwgriffiths

@adamlwgriffiths That fork does not exist anymore.

rjungemann avatar Jan 31 '19 02:01 rjungemann

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

rjungemann avatar Jan 31 '19 02:01 rjungemann

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 avatar Apr 04 '19 02:04 rjungemann

@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!)

lockie avatar Apr 08 '19 16:04 lockie

Hey @lockie I believe you are correct! Amending my comments

rjungemann avatar Apr 10 '19 05:04 rjungemann

@rjungemann All right, thanks. You might also want to do the same change in your PR #8

lockie avatar Apr 10 '19 07:04 lockie