1. Allegro Wrapper Concerns
- Posted by Icy_Viking Oct 09, 2022
- 550 views
Hi all,
As I am starting on wrapping an allegro wrapper using the new ffi.e, I have come across a few issues that are sorta bothersome, but not a huge deal in the grand scheme of things. Though I was wondering if anyone had any thoughts on this. I want to keep the allegro as close to the C source as possible. For example color.h would be color.e and contain the functions found in color.h, but of course wrapped as Euphoria functions.
I'll show some code to show what I mean.
Main Allegro.e
--Allegro.e --Basically converted into Euphoria from C code (base.h) include std/ffi.e include std/math.e include std/machine.e public constant ALLEGRO_VERSION = 5, ALLEGRO_SUB_VERSION = 2, ALLEGRO_WIP_VERSION = 6 public constant ALLEGRO_RELEASE_NUMBER = 1 public constant ALLEGRO_UNSTABLE_BIT = -2147483648 public constant ALLEGRO_PI = 3.14159265358979323846 public constant ALLEGRO_VERSION_INT = or_all({ shift_bits(ALLEGRO_VERSION,-24), shift_bits(ALLEGRO_SUB_VERSION,-16), shift_bits(ALLEGRO_WIP_VERSION, -8), ALLEGRO_RELEASE_NUMBER,ALLEGRO_UNSTABLE_BIT}) include color.e export constant all = open_dll("allegro-5.2.dll"), xal_get_allegro_version = define_c_func(all,"+al_get_allegro_version",{},C_UINT), xal_run_main = define_c_func(all,"+al_run_main",{C_INT,C_POINTER,C_INT,C_INT,C_POINTER},C_INT), --color functions xal_map_rgb = define_c_func(all,"+al_map_rgb",{C_UCHAR,C_UCHAR,C_UCHAR},ALLEGRO_COLOR), xal_map_rgba = define_c_func(all,"+al_map_rgba",{C_UCHAR,C_UCHAR,C_UCHAR,C_UCHAR},ALLEGRO_COLOR), xal_map_rgb_f = define_c_func(all,"+al_map_rgb_f",{C_FLOAT,C_FLOAT,C_FLOAT},ALLEGRO_COLOR), xal_map_rgba_f = define_c_func(all,"+al_map_rgba_f",{C_FLOAT,C_FLOAT,C_FLOAT,C_FLOAT},ALLEGRO_COLOR), xal_premul_rgba = define_c_func(all,"+al_premul_rgba",{C_UCHAR,C_UCHAR,C_UCHAR,C_UCHAR},ALLEGRO_COLOR), xal_premul_rgba_f = define_c_func(all,"+al_premul_rgba_f",{C_FLOAT,C_FLOAT,C_FLOAT,C_FLOAT},ALLEGRO_COLOR), $ public function al_get_allegro_version() return c_func(xal_get_allegro_version,{}) end function public function al_run_main(atom argc,sequence argv,atom x,atom x2,sequence char) return c_func(xal_run_main,{argc,argv,x,x2,char}) end function --Color public function al_map_rgb(integer r,integer g,integer b) return c_func(xal_map_rgb,{r,g,b}) end function public function al_map_rgba(integer r,integer g,integer b,integer a) return c_func(xal_map_rgba,{r,g,b,a}) end function public function al_map_rgb_f(atom r,atom g,atom b) return c_func(xal_map_rgb_f,{r,g,b}) end function public function al_map_rgba_f(atom r,atom g,atom b,atom a) return c_func(xal_map_rgba_f,{r,g,b,a}) end function public function al_premul_rgba(integer r,integer g,integer b,integer a) return c_func(xal_premul_rgba,{r,g,b,a}) end function public function al_premul_rgba_f(atom r,atom g,atom b,atom a) return c_func(xal_premul_rgba_f,{r,g,b,a}) end function
Color.e
include std/ffi.e public constant ALLEGRO_COLOR = define_c_type({ C_FLOAT, --r C_FLOAT, --g C_FLOAT, --b C_FLOAT --a }) public enum type ALLEGRO_PIXEL_FORMAT ALLEGRO_PIXEL_FORMAT_ANY = 0, ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA = 1, ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA = 2, ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA = 3, ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA = 4, ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA = 5, ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA = 6, ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA = 7, ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA = 8, ALLEGRO_PIXEL_FORMAT_ARGB_8888 = 9, ALLEGRO_PIXEL_FORMAT_RGBA_8888 = 10, ALLEGRO_PIXEL_FORMAT_ARGB_4444 = 11, ALLEGRO_PIXEL_FORMAT_RGB_888 = 12, --/* 24 bit format */ ALLEGRO_PIXEL_FORMAT_RGB_565 = 13, ALLEGRO_PIXEL_FORMAT_RGB_555 = 14, ALLEGRO_PIXEL_FORMAT_RGBA_5551 = 15, ALLEGRO_PIXEL_FORMAT_ARGB_1555 = 16, ALLEGRO_PIXEL_FORMAT_ABGR_8888 = 17, ALLEGRO_PIXEL_FORMAT_XBGR_8888 = 18, ALLEGRO_PIXEL_FORMAT_BGR_888 = 19, --/* 24 bit format */ ALLEGRO_PIXEL_FORMAT_BGR_565 = 20, ALLEGRO_PIXEL_FORMAT_BGR_555 = 21, ALLEGRO_PIXEL_FORMAT_RGBX_8888 = 22, ALLEGRO_PIXEL_FORMAT_XRGB_8888 = 23, ALLEGRO_PIXEL_FORMAT_ABGR_F32 = 24, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE = 25, ALLEGRO_PIXEL_FORMAT_RGBA_4444 = 26, ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 = 27, ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 = 28, ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 = 29, ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 = 30, ALLEGRO_NUM_PIXEL_FORMATS end type
AS you can see, I can keep the flags in the color.e, but ideally I would like to have the functions in there too. When I tried to run it, I got an error saying the 'all' variable could not be found. So I put the color functions in the main allegro.e and it worked. If there's any tips or tricks I can use, I'd sure like to know them.
2. Re: Allegro Wrapper Concerns
- Posted by ChrisB (moderator) Oct 10, 2022
- 513 views
Hi
Try (just for the sake of elimination and experimentation) defining 'all' before including color.e
Cheers
Chris
3. Re: Allegro Wrapper Concerns
- Posted by ghaberek (admin) Oct 10, 2022
- 515 views
Hi all,
As I am starting on wrapping an allegro wrapper using the new ffi.e, I have come across a few issues that are sorta bothersome, but not a huge deal in the grand scheme of things. Though I was wondering if anyone had any thoughts on this. I want to keep the allegro as close to the C source as possible. For example color.h would be color.e and contain the functions found in color.h, but of course wrapped as Euphoria functions.
...snip...
AS you can see, I can keep the flags in the color.e, but ideally I would like to have the functions in there too. When I tried to run it, I got an error saying the 'all' variable could not be found. So I put the color functions in the main allegro.e and it worked. If there's any tips or tricks I can use, I'd sure like to know them.
Try (just for the sake of elimination and experimentation) defining 'all' before including color.e
This is a good example of how to the scoping rules work in Euphoria and why we have both export and public. There are technically twelve scopes inside the interpreter but we're only concerned with four:
Keyword | Description |
---|---|
none | local to the file |
global | global across all files |
export | visible to anyone that includes the file |
public | visible to any file that includes it, or via "public include" |
You can't see export constant all because you're not including base.e in color.e. The behavior you're expecting is produced by global which is technically deprecated.
The best practice here would be to use public for symbols required for using the API like al_get_allegro_version() and use export for symbols required for implementing the API like the constants created by define_c_func(), etc.
To put it another way, anything the end-programmer needs to see should be public and anything the library-wrapping programmer needs to see should be export. I hope that makes sense.
That being said, I recommend simply following the existing file hierarchy already established by Allegro using public include in allegro5/allegro.e:
include/allegro5/allegro.e
namespace allegro public include allegro5/base.e public include allegro5/color.e -- etc.
And then put your open_dll() in base.e and segment your define_c_func/proc constants into their respective files:
include/allegro5/base.e
namespace allegro_base include std/ffi.e include std/machine.e -- export scope is only available to files that directly include this file so this won't -- be available if you only include allegro5/allegro.e (which is what we want anyway) export constant liballeg = open_dll( "allegro-5.2.dll" ), _al_get_allegro_version = define_c_func( liballeg, "+al_get_allegro_version", {}, C_UINT ) -- "public" scope is available to files including this file or any file that "public includes" this file public function al_get_allegro_version() return c_func( _al_get_allegro_version, {} ) end function
include/allegro5/color.e
namespace allegro_color include std/ffi.e include std/machine.e include allegro5/base.e -- provides exported constant liballeg export constant AL_ALLEGRO_COLOR = define_c_type({ C_FLOAT, -- r C_FLOAT, -- g C_FLOAT, -- b C_FLOAT -- a }) export constant _al_map_rgb = define_c_func( liballeg, "+al_map_rgb", {C_UCHAR,C_UCHAR,C_UCHAR}, AL_ALLEGRO_COLOR ), _al_map_rgba = define_c_func( liballeg, "+al_map_rgba", {C_UCHAR,C_UCHAR,C_UCHAR,C_UCHAR}, AL_ALLEGRO_COLOR ) public function al_map_rgb( integer r, integer g, integer b ) return c_func( _al_map_rgb, {r,g,b} ) end function public function al_map_rgba( integer r, integer g, integer b, integer a ) return c_func( _al_map_rgba, {r,g,b,a} ) end function
-Greg
4. Re: Allegro Wrapper Concerns
- Posted by Icy_Viking Oct 10, 2022
- 481 views
Thanks Greg. It worked. After some copying and pasting and a little tweaks its working as expected.