1. SDL, keyboard and event handling

Hi

Using Andy's SDL2 lib

Pointers drive me insane!

to check the keyboard to see if ESC is pressed

atom key = 0 
integer scanning = 1, scancode 
 
while scanning = 1 do 
	SDL_PumpEvents() 
	key = SDL_GetKeyboardState(key) 
	 
	if peek(key+SDL_SCANCODE_ESCAPE) > 0 then 
		scanning = 0 
	end if 
end while 
 
return scancode 
 

to check the keyboard for any key pressed

atom key = 0, ev_type = 0 
integer scanning = 1, scancode 
 
while scanning = 1 do 
	 
	SDL_PumpEvents() 
	 
	key = SDL_GetKeyboardState(key) 
	 
	--if peek(key+SDL_SCANCODE_ESCAPE) > 0 then 
	--	scanning = 0 
	--end if 
 
    for i = 4 to 99 do 
        if peek(key + i) > 0 then 
            scanning = 0   
            scancode = i 
        end if 
    end for 
 
end while 
 
return scancode 
 

These work, and do the job.

But, to check the keyboard for an event, like keydown, or indeed other event types

atom ev = 0, ev_type = 0 
 
printf(1, "M_wait_key\n", {}) 
 
while SDL_WaitEvent(ev) do 
        if ev > 0 then 
            ev_type = peek(ev) 
            printf(1, "%d, %d\n", {ev, ev_type}) 
            if wait_key() then end if 
            if ev_type = SDL_KEYDOWN then return 1 end if 
         end if 
end while     
 
return 0 
 
while 1 do 
    if SDL_PollEvent(ev) then 
        if ev > 0 then 
            ev_type = peek(ev) 
            printf(1, "%d, %d\n", {ev, ev_type}) 
            if ev_type = SDL_KEYDOWN then return 1 end if 
         end if 
    end if 
end while 
 
return 0 
 

Neither of these work

My thinking went like this

--Uses pointers and members addressing 
--SDL_PollEvent to get the next event from the event queue  
--to put in a test_event structure, 
--the first member of which will be the event type  
--all events have different structures (with members specific to the structure) 
--but for this function only need the first member. 
--see SDL_KEYBOARD event 
--Uint32 type the event type; SDL_KEYDOWN or SDL_KEYUP 
 

Any pointers (sorry) in the right direction would be greatly appreciated.

Cheers Chris

Update : just remembering this has kind of already been addressed, but reading the docs, pollevent places the next event structure from the event queue into an event structure (which doesn't look like a union), so we should be able to get the event type, the first member, from that structure.

Cheers

Chris

new topic     » topic index » view message » categorize

2. Re: SDL, keyboard and event handling

Added another couple of little helper routines

--------------------------------------------------------------------------- 
global function M_get_key() 
--like M_wait_key(), but doesn't wait 
--------------------------------------------------------------------------- 
atom key = 0, ev_type = 0 
integer scanning = 1, scancode = 0 
 
	SDL_PumpEvents() 
	key = SDL_GetKeyboardState(key) 
	 
	--if peek(key+SDL_SCANCODE_ESCAPE) > 0 then 
	--	scanning = 0 
	--end if 
 
    for i = 4 to 99 do 
        if peek(key + i) > 0 then 
            scanning = 0   
            scancode = i 
        end if 
    end for 
 
return scancode 
end function 
 
--------------------------------------------------------------------------- 
global procedure M_flush_key_buffer() 
--------------------------------------------------------------------------- 
 
while M_get_key() do end while 
 
end procedure 
 
 

Is there a better SDL way to do these - SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LAST_EVENT) doesn't seem to work as expected.

new topic     » goto parent     » topic index » view message » categorize

3. Re: SDL, keyboard and event handling

ChrisB said...
return scancode 

I'd expect that to die with "variable scancode has not been assigned a value"

ChrisB said...
atom ev = 0 

Neither of these work

I'd expect that to stay 0 forever

new topic     » goto parent     » topic index » view message » categorize

4. Re: SDL, keyboard and event handling

SDL_PollEvent() (and SDL_WaitEvent()) expect a pointer to an SDL_Event union. You're passing a value of ev = 0 which it reads as NULL, and that is technically fine except that SDL_PollEvent() has nowhere to put the event it found, so it just returns 1 or 0.

Like I said in this thread, I simply do not have anything for dealing with unions added to my FFI library yet. But you should be able to get along without it as shown below. And keep in mind I'm looking for feedback on this. Does this design work? does it make sense?

include std/ffi.e 
include std/math.e 
 
constant SDL_CommonEvent = define_c_type({ 
    C_UINT32, -- type 
    C_UINT32  -- timestamp 
}) 
 
constant SDL_DisplayEvent = define_c_type({ 
    C_UINT32, -- type 
    C_UINT32, -- timestamp 
    C_UINT32, -- display 
    C_UINT8,  -- event 
    C_UINT8,  -- padding1 
    C_UINT8,  -- padding2 
    C_UINT8,  -- padding3 
    C_INT32   -- data1 
}) 
 
constant SDL_WindowEvent = define_c_type({ 
    C_UINT32, -- type 
    C_UINT32, -- timestamp 
    C_UINT32, -- windowID 
    C_UINT8,  -- event 
    C_UINT8,  -- padding1 
    C_UINT8,  -- padding2 
    C_UINT8,  -- padding3 
    C_INT32,  -- data1 
    C_INT32   -- data2 
}) 
 
constant SDL_Keysym = define_c_type({ 
    C_INT,    -- scancode 
    C_INT,    -- sym 
    C_UINT16, -- mod 
    C_UINT32  -- unused 
}) 
 
constant SDL_KeyboardEvent = define_c_type({ 
    C_UINT32,  -- type 
    C_UINT32,  -- timestamp 
    C_UINT32,  -- windowID 
    C_UINT8,   -- state 
    C_UINT8,   -- repeat 
    C_UINT8,   -- padding2 
    C_UINT8,   -- padding3 
    SDL_Keysym -- keysym 
}) 
 
 
-- allocate enough memory to hold the largest member of SDL_Event union 
 
constant SIZEOF_SDL_EVENT = math:max({ 
    sizeof(C_UINT32),          -- type 
    sizeof(SDL_CommonEvent),   -- common 
    sizeof(SDL_DisplayEvent),  -- display 
    sizeof(SDL_WindowEvent),   -- window 
    sizeof(SDL_KeyboardEvent), -- key 
    -- etc. 
}) 
 
atom event = allocate_data( SIZEOF_SDL_EVENT ) 
 
while SDL_WaitEvent( event ) do -- SDL_WaitEvent() fills our memory with the event it found and returns 1 (or 0 on error) 
 
    atom etype = peek_type( event, C_UINT32 ) 
 
    switch etype do 
 
        case SDL_DISPLAYEVENT then 
            sequence display_event = peek_struct( event, SDL_DisplayEvent ) 
 
        case SDL_WINDOWEVENT then 
            sequence window_event = peek_struct( event, SDL_WindowEvent ) 
 
        case SDL_KEYDOWN, SDL_KEYUP then 
            sequence key_event = peek_struct( event, SDL_KeyboardEvent ) 
 
        -- etc. 
 
    end switch 
 
end while 
 
free( event ) 

-Greg

new topic     » goto parent     » topic index » view message » categorize

5. Re: SDL, keyboard and event handling

I actually have re-written my SDL 2 wrapper with Greg's FFI library. It does need some tweaking here and there and some fine-tuning, but it works for the most part. I'll try to get it on github later today. The code-base is more organized and its easier to read through the code.

new topic     » goto parent     » topic index » view message » categorize

6. Re: SDL, keyboard and event handling

petelomax said...
ChrisB said...
return scancode 

I'd expect that to die with "variable scancode has not been assigned a value"

No, scancode = i

petelomax said...
ChrisB said...
atom ev = 0 

Neither of these work

I'd expect that to stay 0 forever

and it does, except SDL_WaitEvent(ev) and SDL_PollEvent(ev) should make ev a pointer to the event structure.

Chris

new topic     » goto parent     » topic index » view message » categorize

7. Re: SDL, keyboard and event handling

ghaberek said...

SDL_PollEvent() (and SDL_WaitEvent()) expect a pointer to an SDL_Event union. You're passing a value of ev = 0 which it reads as NULL, and that is technically fine except that SDL_PollEvent() has nowhere to put the event it found, so it just returns 1 or 0.

Like I said in this thread, I simply do not have anything for dealing with unions added to my FFI library yet. But you should be able to get along without it as shown below. And keep in mind I'm looking for feedback on this. Does this design work? does it make sense?

include std/ffi.e 
include std/math.e 
 
constant SDL_CommonEvent = define_c_type({ 
    C_UINT32, -- type 
    C_UINT32  -- timestamp 
}) 
 
constant SDL_DisplayEvent = define_c_type({ 
    C_UINT32, -- type 
    C_UINT32, -- timestamp 
    C_UINT32, -- display 
    C_UINT8,  -- event 
    C_UINT8,  -- padding1 
    C_UINT8,  -- padding2 
    C_UINT8,  -- padding3 
    C_INT32   -- data1 
}) 
 
constant SDL_WindowEvent = define_c_type({ 
    C_UINT32, -- type 
    C_UINT32, -- timestamp 
    C_UINT32, -- windowID 
    C_UINT8,  -- event 
    C_UINT8,  -- padding1 
    C_UINT8,  -- padding2 
    C_UINT8,  -- padding3 
    C_INT32,  -- data1 
    C_INT32   -- data2 
}) 
 
constant SDL_Keysym = define_c_type({ 
    C_INT,    -- scancode 
    C_INT,    -- sym 
    C_UINT16, -- mod 
    C_UINT32  -- unused 
}) 
 
constant SDL_KeyboardEvent = define_c_type({ 
    C_UINT32,  -- type 
    C_UINT32,  -- timestamp 
    C_UINT32,  -- windowID 
    C_UINT8,   -- state 
    C_UINT8,   -- repeat 
    C_UINT8,   -- padding2 
    C_UINT8,   -- padding3 
    SDL_Keysym -- keysym 
}) 
 
 
-- allocate enough memory to hold the largest member of SDL_Event union 
 
constant SIZEOF_SDL_EVENT = math:max({ 
    sizeof(C_UINT32),          -- type 
    sizeof(SDL_CommonEvent),   -- common 
    sizeof(SDL_DisplayEvent),  -- display 
    sizeof(SDL_WindowEvent),   -- window 
    sizeof(SDL_KeyboardEvent), -- key 
    -- etc. 
}) 
 
atom event = allocate_data( SIZEOF_SDL_EVENT ) 
 
while SDL_WaitEvent( event ) do -- SDL_WaitEvent() fills our memory with the event it found and returns 1 (or 0 on error) 
 
    atom etype = peek_type( event, C_UINT32 ) 
 
    switch etype do 
 
        case SDL_DISPLAYEVENT then 
            sequence display_event = peek_struct( event, SDL_DisplayEvent ) 
 
        case SDL_WINDOWEVENT then 
            sequence window_event = peek_struct( event, SDL_WindowEvent ) 
 
        case SDL_KEYDOWN, SDL_KEYUP then 
            sequence key_event = peek_struct( event, SDL_KeyboardEvent ) 
 
        -- etc. 
 
    end switch 
 
end while 
 
free( event ) 

-Greg

Hmm, I wonder if I'm doing the wrong sort of peek

atom event = allocate_data( SIZEOF_SDL_EVENT )  
  
while SDL_WaitEvent( event ) do -- SDL_WaitEvent() fills our memory with the event it found and returns 1 (or 0 on error)  
  
    atom etype = peek_type( event, C_UINT32 )  
  
    switch etype do  
  

After all, as far as I can tell, event is structure, not a union.

Cheers

Chris

new topic     » goto parent     » topic index » view message » categorize

8. Re: SDL, keyboard and event handling

ChrisB said...

Hmm, I wonder if I'm doing the wrong sort of peek

The peek/poke_type() and peek/poke_struct() routines are something I made for FFI to help take the guesswork out of peek/peek2s/peek4u/etc. In this case peek4u() would work the same.

ChrisB said...

After all, as far as I can tell, event is structure, not a union.

Unless we're referencing different things, SDL_events.h says SDL_Event is definitely a union. It's designed in a way that the value sitting at the "base" address in memory is always the event type value.

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: SDL, keyboard and event handling

Hi

Yes, but it's a union I can access now, thanks to you pointing me in the right direction with the peek type.

All I need is the event type for a 'press any key function' doing it this way

"The SDL_Event structure is the core of all event handling in SDL. SDL_Event is a union of all event structures used in SDL."

So make an event memory area big enough to hold the event union, and treat the bit I'm interested in like a structure - the last element of the SDL_Event structure is another structure, which is wher it becomes a union. (Probably teaching Granny to suck eggs at this point, but I've always had a conceptual difficulty grasping this)

atom ev_type = 0, ev 
 
ev = allocate(1024) 
while SDL_WaitEvent(ev) do 
    ev_type = peek4u(ev) 
        if ev > 0 then 
            ev_type = peek4u(ev)     4 byte unsigned int (C_UINT32) 
            printf(1, "%d, %d, %d\n", {ev, SDL_KEYDOWN, ev_type}) --lets see what it's spewing out 
            --if wait_key() then end if       --console 
            if ev_type = SDL_KEYDOWN then exit end if  -- comment this out to see all the spew 
        end if 
end while     
 
free(ev)  --should probably free it too 
return ev_type 
 

It was the allocate memory bit that I was missing. Now just need to trim and adapt the output for use. I appreciate that ffi, and cffi/c-struct should be easier to do this too.

Many thanks Chris

new topic     » goto parent     » topic index » view message » categorize

10. Re: SDL, keyboard and event handling

ChrisB said...

Hi

Yes, but it's a union I can access now, thanks to you pointing me in the right direction with the peek type.

All I need is the event type for a 'press any key function' doing it this way

"The SDL_Event structure is the core of all event handling in SDL. SDL_Event is a union of all event structures used in SDL."

So make an event memory area big enough to hold the event union, and treat the bit I'm interested in like a structure - the last element of the SDL_Event structure is another structure, which is wher it becomes a union. (Probably teaching Granny to suck eggs at this point, but I've always had a conceptual difficulty grasping this)

atom ev_type = 0, ev 
 
ev = allocate(1024) 
while SDL_WaitEvent(ev) do 
    ev_type = peek4u(ev) 
        if ev > 0 then 
            ev_type = peek4u(ev)     4 byte unsigned int (C_UINT32) 
            printf(1, "%d, %d, %d\n", {ev, SDL_KEYDOWN, ev_type}) --lets see what it's spewing out 
            --if wait_key() then end if       --console 
            if ev_type = SDL_KEYDOWN then exit end if  -- comment this out to see all the spew 
        end if 
end while     
 
free(ev)  --should probably free it too 
return ev_type 
 

It was the allocate memory bit that I was missing. Now just need to trim and adapt the output for use. I appreciate that ffi, and cffi/c-struct should be easier to do this too.

Many thanks Chris

Alright, I've got my current wrapper of SDL 2 using Greg's FFI library on Github. You can get/view it here: https://github.com/gAndy50/SDL2Wrapper

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu