Hello sdl4fp-users,
As some of you might remember, I wanted to use the SDL also with GNU Pascal in my project AKFQuiz. I tried to fiddle with the source code of SDL4Freepascal. But there was too much code to change just to find out how it works...
So I decided to leave SDL4fp away and implement the few things I need from scratch.
My project now is fully functional with GPC and SDL. It is not yet in the released version, but you can check out the CVS as described on the homepage (see link at the end of this mail).
Now I want to share my findings with you, so probably you can use it for SDL4Freepascal...
First of all, the types for variables are very different. SDL4fp uses "LongInt" for what is "int" in C - because LongInt happens to be 32Bit wide in FPC. But in GPC a LongInt is "at least" :-) 64bit wide! So it doesn't fit.
Older versions of GPC intentionally kept the variable types compatible to their counterparts in C. Newer versions broke with that and introduced speacial types, like CInteger or CLongInt.
Another difference to FPC is, that in GPC you have a more fine grained access to determine attributes, so you have really control about the size of variables.
Here is the code snipplet for the types (from my "qsys.pas"):
----------------------------------------------------------------------- {$IfDef __GPC__}
type Uint8 = Cardinal attribute (Size = 8); Uint16 = Cardinal attribute (Size = 16); Sint16 = Integer attribute (Size = 16); Uint32 = Cardinal attribute (Size = 32); Sint32 = Integer attribute (Size = 32); pByte = ^Uint8;
{$if __GPC_RELEASE__ < 20041218} type CInteger = Integer; {$EndIf} { __GPC_RELEASE__ }
{$Else} { not __GPC__ }
type CInteger = LongInt; { @@@ for 32-Bit systems } CString = PChar; Uint8 = byte; Uint16 = word; Sint16 = SmallInt; Uint32 = cardinal; Sint32 = LongInt; pByte = ^Uint8;
{$EndIf} { not __GPC__ } -----------------------------------------------------------------------
Note that you have to change "LongInt" to "CInteger" and "PChar" to "CString" in SDL4fp.
SDL4fp links to the library by using the name 'SDL' after the "external" modifier. This doesn't work in GPC (yet). In GPC you have to use the compiler directive "{$L SDL}". In FPC there's also a possability to use it in a similar way with "{$LinkLib SDL}"... well it works, but not in every situation. So I decided to keep the name after the external clause, but with "IfDef"s around it. GPC compiles it without the IfDef, but there are lot of warning messages then.
In FPC you must use the modifier "cdecl". In GPC that is the default, so you don't need it there. You can however declare it with "attribute(cdecl)", so you can simply write a macro to modify the "cdecl": "{$Define cdecl attribute(cdecl)}".
C is case sensitive, while Pascal is not. So in GPC all Pascal identifiers are converted to lowercase at an early stage, this includes the procedure names. So you have a problem when your C identifiers need uppercase letters. This can only be solved by using an attribute which mentions the name again with its capitalisation: "name 'Example'". This name isn't converted to lower case, since it's a string-constant. FPC doesn't need that, but it doesn't harm there either.
putting everything together it looks like in this example:
procedure SDL_WM_SetCaption(title, icon: CString); cdecl; external {$IfDef FPC}'SDL'{$EndIf} name 'SDL_WM_SetCaption';
Well I still have a problem with CString parameters. FPC needs a type cast, while GPC doesn't accept a type cast here. I "solved" it again with "IfDef"s. Does anybody know a better solution?
Please have a look at my source code for more information: http://cvs.sv.nongnu.org/viewcvs/akfquiz/srcbin/?root=akfquiz The relevant units are "sdlgrph.pas" and "sdlsnd.pas". The type definitions are in "qsys.pas".
If you use my findings in SDL4fp, it would be nice, if you would mention me there as "AKFoerster".
Related Links:
GNU Pascal: http://www.gnu-pascal.de/ Free Pascal: http://www.freepascal.org/ SDL: http://www.libsdl.org/ SDL4Freepascal: http://sdl4fp.sourceforge.net/ AKFQuiz: http://akfquiz.nongnu.org/