Hi there, While adding support for handling keyboard events to the SDL bindings (see the attached patch; it's not for applying, as the documentation is lacking and the interface exposes too many details), I discovered that the alignment of members within a struct matters quite a bit.
That is, to make the keyed struct work correctly, I had to add extra bytes of padding in the appropriate places. This works, at least on my platform, but I'm not sure how portable it is. If you have the SDL headers installed on your system, I'm trying to make the Parrot equivalent of an SDL_Event, the mess that it is. In particular, I added one byte of padding before keysym and three bytes before keysym.sym. Is this indeed unportable? If so, is there a way to work around this without writing C code for every afflicted structure? Is it a case of making the struct PMCs smarter? Or have I fixed it with my nasty workaround? -- c
Index: library/sdl.pasm =================================================================== RCS file: /cvs/public/parrot/library/sdl.pasm,v retrieving revision 1.2 diff -u -u -r1.2 sdl.pasm --- library/sdl.pasm 3 Feb 2004 01:58:24 -0000 1.2 +++ library/sdl.pasm 3 Feb 2004 07:07:01 -0000 @@ -21,6 +21,13 @@ store_global 'SDL::DisplayFormat', P2 dlfunc P2, P1, 'SDL_UpperBlit', 'ipppp' store_global 'SDL::BlitSurface', P2 +dlfunc P2, P1, 'SDL_WaitEvent', 'ip' +store_global 'SDL::WaitEvent', P2 +dlfunc P2, P1, 'SDL_GetKeyName', 'ti' +store_global 'SDL::GetKeyName', P2 + +# now load the SDL_image library +# should be broken out into library/sdl/image.pasm or somesuch loadlib P1, 'libSDL_image' dlfunc P2, P1, 'IMG_Load', 'pt' store_global 'SDL::IMG_Load', P2 Index: library/sdl_types.imc =================================================================== RCS file: /cvs/public/parrot/library/sdl_types.imc,v retrieving revision 1.2 diff -u -u -r1.2 sdl_types.imc --- library/sdl_types.imc 3 Feb 2004 01:58:24 -0000 1.2 +++ library/sdl_types.imc 3 Feb 2004 07:07:01 -0000 @@ -257,6 +256,93 @@ .pcc_begin_return .return image + .pcc_end_return +.end + +.pcc_sub _new_SDL_Event prototyped + .local pmc layout + new layout, .OrderedHash + + .local int size + .local int element_size + + # this is the only element in common in the SDL_Event union + set layout['type'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + + # SDL_KeyboardEvent is the largest struct in the SDL_Event union + set layout['which'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['state'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['padding'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['scancode'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['padding_a'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['padding_b'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['padding_c'], .DATATYPE_UINT8 + push layout, 0 + push layout, 0 + set layout['sym'], .DATATYPE_INT + push layout, 0 + push layout, 0 + set layout['mod'], .DATATYPE_INT + push layout, 0 + push layout, 0 + set layout['unicode'], .DATATYPE_UINT16 + push layout, 0 + push layout, 0 + + # type, which, state, scancode, and four paddings + sizeof element_size, .DATATYPE_UINT8 + mul element_size, 8 + add size, element_size + + # sym and mod + sizeof element_size, .DATATYPE_INT + mul element_size, 2 + add size, element_size + + # unicode + sizeof element_size, .DATATYPE_UINT16 + add size, element_size + + .local pmc event + new event, .ManagedStruct, layout + set event, size + + .pcc_begin_return + .return event + .pcc_end_return +.end + +.pcc_sub _SDL_WaitEvent + .param pmc event + + .local pmc WaitEvent + WaitEvent = global "SDL::WaitEvent" + + .pcc_begin prototyped + .arg event + .nci_call WaitEvent + .result event + .pcc_end + + .local string type + typeof type, event + + .pcc_begin_return + .return event .pcc_end_return .end --- /dev/null 1969-12-31 16:00:00.000000000 -0800 +++ examples/sdl/show_events.imc 2004-02-02 23:06:11.000000000 -0800 @@ -0,0 +1,97 @@ +.sub _main + _init() + _MAIN() + end +.end + +.include "library/sdl_types.imc" + +.pcc_sub _init prototyped + .include "library/sdl.pasm" + .pcc_begin_return + .pcc_end_return +.end + +.sub _MAIN + .local pmc SDL_Init + .local pmc SDL_Quit + .local pmc SDL_GetKeyName + .local object screen + + SDL_Init = global "SDL::Init" + SDL_Quit = global "SDL::Quit" + SDL_GetKeyName = global "SDL::GetKeyName" + + .pcc_begin prototyped + .arg 65535 + .nci_call SDL_Init + .pcc_end + + .local pmc screen_settings + new screen_settings, .PerlHash + set screen_settings['width'], 640 + set screen_settings['height'], 480 + set screen_settings['bpp'], 0 + set screen_settings['flags'], 0 + + screen = _new_SDL_Screen( screen_settings ) + + .local pmc event + event = _new_SDL_Event() + + .local int key + .local int type + .local string key_name + .local string type_name +loop: + event = _SDL_WaitEvent( event ) + + set type, event['type'] + set key, event['sym'] + + # redo if no event + if type == 0 goto loop + + # SDL_Quit event + if type == 12 goto end_loop + + if type != 2 goto not_down + set type_name, "Key down" + goto set_key_name + +not_down: + if type != 3 goto not_up + set type_name, "Key up" + goto set_key_name + +not_up: + set type_name, "Unknown type" + set key_name, "Unknown key (not a key type)" + goto end_set_key_name + +set_key_name: + .pcc_begin prototyped + .arg key + .nci_call SDL_GetKeyName + .result key_name + .pcc_end + +end_set_key_name: + + print type_name + print ", " + print key_name + print "\n" + + # SDLK_ESCAPE + if key != 27 goto loop + +end_loop: + + .pcc_begin prototyped + .nci_call SDL_Quit + .pcc_end + + .pcc_begin_return + .pcc_end_return +.end