1. SDL, keyboard and event handling
- Posted by ChrisB (moderator) Nov 01, 2022
- 1174 views
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
2. Re: SDL, keyboard and event handling
- Posted by ChrisB (moderator) Nov 01, 2022
- 1167 views
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.
3. Re: SDL, keyboard and event handling
- Posted by petelomax Nov 01, 2022
- 1152 views
return scancode
I'd expect that to die with "variable scancode has not been assigned a value"
atom ev = 0
Neither of these work
I'd expect that to stay 0 forever
4. Re: SDL, keyboard and event handling
- Posted by ghaberek (admin) Nov 01, 2022
- 1142 views
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
5. Re: SDL, keyboard and event handling
- Posted by Icy_Viking Nov 01, 2022
- 1135 views
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.
6. Re: SDL, keyboard and event handling
- Posted by ChrisB (moderator) Nov 01, 2022
- 1126 views
return scancode
I'd expect that to die with "variable scancode has not been assigned a value"
No, scancode = i
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
7. Re: SDL, keyboard and event handling
- Posted by ChrisB (moderator) Nov 01, 2022
- 1132 views
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
8. Re: SDL, keyboard and event handling
- Posted by ghaberek (admin) Nov 01, 2022
- 1133 views
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.
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
9. Re: SDL, keyboard and event handling
- Posted by ChrisB (moderator) Nov 01, 2022
- 1118 views
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
10. Re: SDL, keyboard and event handling
- Posted by Icy_Viking Nov 02, 2022
- 1116 views
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