1. Phix: cffi.e
- Posted by andreasWagner 1 week ago
- 418 views
I looked at raylib for openeuphoria. Now I'm thinking about how and whether I can use this library with phix.
Can someone tell me how to use this code with phix with cffi.e for example:
In the functioncall Vector2 is not a pointer to a structure but the structure itself.
with ffi.e for openeuphoria this seems to work but i have no idea how to implement this with phix.
/* from raylib.h */ // Vector2, 2 components typedef struct Vector2 { float x; // Vector x component float y; // Vector y component } Vector2; RLAPI void DrawCircleV(Vector2 center, float radius, Color color);maybe i just haven't found it in the documentation yet.
Thank you
Andreas
2. Re: Phix: cffi.e
- Posted by Icy_Viking 1 week ago
- 413 views
I looked at raylib for openeuphoria. Now I'm thinking about how and whether I can use this library with phix.
Can someone tell me how to use this code with phix with cffi.e for example:
In the functioncall Vector2 is not a pointer to a structure but the structure itself.
with ffi.e for openeuphoria this seems to work but i have no idea how to implement this with phix.
/* from raylib.h */ // Vector2, 2 components typedef struct Vector2 { float x; // Vector x component float y; // Vector y component } Vector2; RLAPI void DrawCircleV(Vector2 center, float radius, Color color);maybe i just haven't found it in the documentation yet.
Thank you
Andreas
Well I'm not sure how you'd wrap it in Phix, but I assume it'd be similar to how it is wrapped in OE.
include std/ffi.e --the FFI library --defines a struct we can use Vector2, we declare the x and y members as floats, as they are in the C library. public constant VECTOR2 = define_c_struct({ C_FLOAT, --x C_FLOAT }) --defines a struct of color, where members r,g,b,a are unsigned chars in the C library public constant COLOR = define_c_struct({ C_UCHAR, --r C_UCHAR, --g C_UCHAR, --b C_UCHAR --a }) public constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{VECTOR2,C_FLOAT,COLOR}) public procedure DrawCircleV(sequence vector2,atom radius,sequence color) c_proc(xDrawCircleV,{vector2,radius,color}) end procedure --Then you can access the members like a sequence in an array DrawCircle({10,10},20,{255,255,255,255}) --Draws a circle at x: 10 and y: 10, radius: 20 and color values set 255,255,255,255
I hope that helps.
3. Re: Phix: cffi.e
- Posted by petelomax 6 days ago
- 327 views
In Phix I'd start with something like this (NB completely untested)
include cffi.e constant t_Vector2 = """ typedef struct Vector2 { float x; // Vector x component float y; // Vector y component } Vector2; """ constant idVector2 = define_struct(t_Vector2), pVector2 = allocate_struct(idVector2) -- (you might get away with passing/need to pass #RRGGBBAA values directly, -- and/or allocate(4) and poke4(said) might be much neater...) constant t_Color = """ typedef struct Color { unsigned char r; // Color red value unsigned char g; // Color green value unsigned char b; // Color blue value unsigned char a; // Color alpha value } Color;""" constant idColor = define_struct(t_Color), pColor = allocate_struct(idColor) -- I can tell you this kind of thing simply won't work: --constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{VECTOR2,C_FLOAT,COLOR}) -- instead: local constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{C_PTR,C_FLOAT,C_PTR}) global procedure DrawCircleV(sequence vector2, atom radius, sequence color) atom {x,y} = vector2 set_struct_field(idVector2,pVector2,"x",x) set_struct_field(idVector2,pVector2,"y",y) integer {r,g,b,a} = color set_struct_field(idColor,pColor,"r",r) set_struct_field(idColor,pColor,"g",g) set_struct_field(idColor,pColor,"b",b) set_struct_field(idColor,pColor,"a",a) c_proc(xDrawCircleV,{pVector2,radius,pColor}) end procedure -- if an alpha of 255 means fully transparent, this won't show anything: DrawCircleV({10,10},20,{255,255,255,255})
4. Re: Phix: cffi.e
- Posted by andreasWagner 6 days ago
- 311 views
Well I'm not sure how you'd wrap it in Phix, but I assume it'd be similar to how it is wrapped in OE.
include std/ffi.e --the FFI library [...]
Thanks for your effort, but I think it takes a lot of work to port ffi.e to phix.
Thanks a lot
5. Re: Phix: cffi.e
- Posted by andreasWagner 6 days ago
- 310 views
In Phix I'd start with something like this (NB completely untested)
include cffi.e [...] -- I can tell you this kind of thing simply won't work: --constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{VECTOR2,C_FLOAT,COLOR}) -- instead: local constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{C_PTR,C_FLOAT,C_PTR}) [...]
Thank you very much for the effort. My knowledge of the C programming language is very modest, but this will probably not work.
RLAPI void DrawCircleV(Vector2 center, float radius, Color color);
As I understand it:
This Function Call needs the structur passed as Value, your code passes it as reference (C_PTR,Pointer)
many thanks
Andreas
6. Re: Phix: cffi.e
- Posted by petelomax 6 days ago
- 293 views
This Function Call needs the structur passed as Value, your code passes it as reference (C_PTR,Pointer)
Hmm, maybe something like this would work (where color is a single #RRGGBBAA value):
local constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{C_FLOAT,C_FLOAT,C_FLOAT,C_DWORD}) c_proc(xDrawCircleV,{x,y,radius,color})
If you can make a small working C program, or better yet FASM which I've done myself more than once, then disassemble it with OllyDbg, fdbg, or even Phix's own filedump.exw,
then even should c_proc be unable cope, you could (with my help as needed) always replicate things using a wee bit of inline assembly...
I suppose I should really download what you've already got so far and give it a quick spin.
7. Re: Phix: cffi.e
- Posted by andreasWagner 5 days ago
- 269 views
I suppose I should really download what you've already got so far and give it a quick spin.
Thank you for the quick reply,
I don't really have anything tangible at the moment. But there's no need to rush either. Programming is just a hobby for me.
unfortunately I'm more than busy enough with my real life at the moment.
But I think at the weekend I'll find the peace and time to put something together that someone can work with.
Thank you
Andreas
8. Re: Phix: cffi.e
- Posted by andreasWagner 5 days ago
- 258 views
Hallo,
i just had to try it works
I would never have thought of trying it this way. there has been a function in tinlib for over 10 years that has never worked because of this problem (WindowFromPoint).
of course i still have to test if there are any memory leaks.
thanks a lot
Andreas
Hmm, maybe something like this would work (where color is a single #RRGGBBAA value):
local constant xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{C_FLOAT,C_FLOAT,C_FLOAT,C_DWORD}) c_proc(xDrawCircleV,{x,y,radius,color})
only for windows 32bit but it works
-- file: ray.e -- practically everything is shamelessly copied from Icy Vikings raylib.e atom ray constant Color =C_ULONG public struct Vector2 atom x = 0 atom y = 0 end struct ray = open_dll("raylib.dll") if ray = 0 then puts(1,"Unable to load Raylib!\n") abort(0) end if --public function makeRGB(integer REDi,integer GREENi, integer BLUEi,integer ALPHAi) -- return(REDi+BLUEi*256+(GREENi*256*256)+(ALPHAi*256*256*256)) --end function public function makeRGB(sequence color) return(color[1]+color[2]*256+(color[3]*256*256)+(color[4]*256*256*256)) end function public constant WHITE = {255,255,255,255}, BLACK = {0,0,0,255}, MAGENTA = {255,0,255,255}, RAYWHITE = {245,245,245,255}, RED = {230,41,55,255}, MAROON = {190,33,55,255}, GREEN = {0,228,48,255}, LIME = {0,158,47,255}, DARKGREEN = {0,117,44,255}, SKYBLUE = {102,191,255,255}, BLUE = {0,121,241,255}, YELLOW = {253,249,9,255} constant xInitWindow = define_c_proc(ray,"+InitWindow",{C_INT,C_INT,C_PTR}), xCloseWindow = define_c_proc(ray,"+CloseWindow",{}), xWindowShouldClose = define_c_func(ray,"+WindowShouldClose",{},C_BOOL), xSetTargetFPS = define_c_proc(ray,"+SetTargetFPS",{C_INT}), xBeginDrawing = define_c_proc(ray,"+BeginDrawing",{}), xEndDrawing = define_c_proc(ray,"+EndDrawing",{}), xClearBackground = define_c_proc(ray,"+ClearBackground",{C_ULONG}), xDrawText = define_c_proc(ray,"+DrawText",{C_PTR,C_INT,C_INT,C_INT,Color}), xDrawCircleV = define_c_proc(ray,"+DrawCircleV",{C_FLOAT,C_FLOAT,C_FLOAT,Color}) public procedure InitWindow(atom width,atom height,sequence title) atom ptitle = allocate_string(title) c_proc(xInitWindow,{width,height,ptitle}) free(ptitle) end procedure public procedure CloseWindow() c_proc(xCloseWindow,{}) end procedure public function WindowShouldClose() return c_func(xWindowShouldClose,{}) end function public procedure SetTargetFPS(atom fps) c_proc(xSetTargetFPS,{fps}) end procedure public procedure ClearBackground(object color) c_proc(xClearBackground,{makeRGB(color)}) end procedure public procedure BeginDrawing() c_proc(xBeginDrawing,{}) end procedure public procedure EndDrawing() c_proc(xEndDrawing,{}) end procedure public procedure DrawText(sequence text,atom x,atom y,atom fontSize,sequence color) atom ptext =allocate_string(text) c_proc(xDrawText,{ptext,x,y,fontSize,makeRGB(color)}) free(ptext) end procedure public procedure DrawCircleV(Vector2 center,atom radius,sequence color) c_proc(xDrawCircleV,{center.x,center.y,radius,makeRGB(color)}) end procedure
--file BasicWin.ex include ray.e constant Width = 800 constant Height = 600 InitWindow(Width,Height,"Simple Window") SetTargetFPS(60) Vector2 pos =new() pos.x=Width/2.5 pos.y=Height/2.5 while not WindowShouldClose() do BeginDrawing() ClearBackground(BLUE) DrawCircleV(pos,100,RED) DrawText("Simple Window Program",Width /2.5, Height /2.5 ,20,YELLOW) EndDrawing() end while CloseWindow()
9. Re: Phix: cffi.e
- Posted by petelomax 4 days ago
- 220 views
only for windows 32bit but it works
They are rare, but I've seen a couple of places where this bites, for instance libcurl.e has this:
if xcurl_easy_setopt=NULL then xcurl_easy_setopt = define_c_func(libcurl, "curl_easy_setopt", {C_PTR, C_INT, C_PTR}, C_INT) if machine_bits()=32 then -- split a curl_off_t (64 bit int) into two 32-bit ints xcurl_easy_setopt2 = define_c_func(libcurl, "curl_easy_setopt", {C_PTR, C_INT, C_PTR, C_PTR}, C_INT) end if end if ... if machine_bits()=32 and option>30000 then atom paramhi = floor(param/#1_0000_0000) param = remainder(param,#1_0000_0000) res = c_func(xcurl_easy_setopt2, {curl, option, param, paramhi}) else res = c_func(xcurl_easy_setopt, {curl, option, param}) end if
It may be that you need to ram two floats into a 64-bit value the hard way, ie faff about with poke(atom_to_float32()) and peek8(), on 64-bit.
10. Re: Phix: cffi.e
- Posted by andreasWagner 1 day ago
- 76 views
only for windows 32bit but it works
They are rare, but I've seen a couple of places where this bites, for instance libcurl.e has this:
if xcurl_easy_setopt=NULL then xcurl_easy_setopt = define_c_func(libcurl, "curl_easy_setopt", {C_PTR, C_INT, C_PTR}, C_INT) if machine_bits()=32 then -- split a curl_off_t (64 bit int) into two 32-bit ints xcurl_easy_setopt2 = define_c_func(libcurl, "curl_easy_setopt", {C_PTR, C_INT, C_PTR, C_PTR}, C_INT) end if end if ... if machine_bits()=32 and option>30000 then atom paramhi = floor(param/#1_0000_0000) param = remainder(param,#1_0000_0000) res = c_func(xcurl_easy_setopt2, {curl, option, param, paramhi}) else res = c_func(xcurl_easy_setopt, {curl, option, param}) end if
It may be that you need to ram two floats into a 64-bit value the hard way, ie faff about with poke(atom_to_float32()) and peek8(), on 64-bit.
What I have found so far in raylib, these stumbling blocks are not rare. For 64bit I just gave up for the moment.
The following sentences are from the Phix documentation (define_c_func).
Currently, there is no way to pass a C structure by value or get a C structure as a return result. You can only pass a pointer to a structure and get a pointer to a structure as a result.I think I'll just wait until these features are possibly included in a Phix 2.0 version.
Until then I'll play around with raylib(phix) here:
https://github.com/andizk4kx/raylib-playground/tree/main
Thanks for your support and especially for Phix.
Andreas