PDA

View Full Version : Delphi 2009 - SDL_OPENBMP noob problem



GordonShumway
27-09-2009, 07:27 PM
Hello fellow Pascalians, (I couldn't resist the temptation. :))

I have kind of a stupid newbie type question, as I'm sure you've gathered from the post title I'm using Delphi 2k9, and am having some rather perturbing problems. (A lot of which were solved elsewhere after some quick perusing on previous posts.)

So after downloading and installing Jedi-SDL (most recent version from source forge, including most recent DLLs from libsdl) I've been able to compile several basic examples. However whenever I call SDL_OPENBMP (or for that matter TTF_OPENFONT) I always get a nil return value. So when I check the error code I get 'Cannot open ?', the '?' is the first letter of the file name that I try to send to it. I have included my code here in hopes that maybe someone could explain to me what I'm doing wrong. I'm sure it's something simple. However (at least for SDL_TTF) it does compile in Lazarus (the tutorials that I've been following have been for fpc and Lazarus.)

Also note that this is in a separate class from the main program with the actual screen surface being referenced by (of course) self.mainScreen

Any help would be very appreciative!



procedure Ttesting.DisplayPic;
var
picture : PSDL_Surface;
srcRect, dstRect: PSDL_RECT;
I: Integer;
fname: PChar;
begin
picture := SDL_LOADBMP('fpsdl.bmp');
if picture = nil then
begin
ShowMessage('Couldn''t load the bmp. ' + PAnsiChar(SDL_GETERROR));
exit;
end;
new(srcRect);
new(dstRect);
srcRect.x := 0;
srcRect.y := 0;
srcRect.w := 200;
srcRect.h := 200;
dstRect.x := 0;
dstRect.y := 0;
dstRect.w := 200;
dstRect.h := 200;
for I := 0 to 200 do
begin
SDL_BLITSURFACE(picture, srcRect, self.mainScreen, dstRect);
SDL_FLIP(self.mainScreen);
dec(srcRect.w);
dec(srcRect.h);
inc(dstRect.x);
inc(dstRect.y);
SDL_DELAY(30);
if srcRect.w = 1 then
begin
srcRect.x := 0;
srcRect.y := 0;
srcRect.w := 200;
srcRect.h := 200;
dstRect.x := 0;
dstRect.y := 0;
dstRect.w := 200;
dstRect.h := 200;
end;
end;
SDL_FREESURFACE(picture);
end;

pjpdev
27-09-2009, 08:43 PM
Where is 'fpsdl.bmp' located in the directory structure? According to your code the bitmap must be located in the same directory as the executable itself (or the root directory). So if it is located in a subdirectory then you should include that as well:


picture := SDL_LoadBMP('subdir/fpsdl.bmp');


SDL_LoadBMP shouldn't return nil if the bitmap is found where told. It's worth taking a look at your directory structure and make sure where the bitmap is located.

GordonShumway
27-09-2009, 09:01 PM
Where is 'fpsdl.bmp' located in the directory structure? According to your code the bitmap must be located in the same directory as the executable itself (or the root directory). So if it is located in a subdirectory then you should include that as well:


picture := SDL_LoadBMP('subdir/fpsdl.bmp');


SDL_LoadBMP shouldn't return nil if the bitmap is found where told. It's worth taking a look at your directory structure and make sure where the bitmap is located.


Thanks for the quick reply PJP Dev,
The bitmap in question is actually located in the same directory as the executable being compiled. This one has really got me stumped, I've not had a problem quite like this.

GordonShumway
27-09-2009, 09:27 PM
Woohoo! :D
I got it to work! A person by the name of StormyOrdos on this post had the same problem that I did and posted the solution. (I didn't know this as I had found this site and the updated inc via google, so I didn't see these posts pertaining to an updated include for D2k9)

http://www.pascalgamedevelopment.com/forum/index.php?topic=5495.0

procedure Dummy;
var
name : AnsiString;
begin
name := 'Projet SDL';
SDL_WM_SetCaption(PAnsiChar(name), nil);
end;


So for anyone who want's to know why D2k9 cuts off your string data when passing params to SDL, just create an AnsiString variable, initialize it, and then cast it as a PWideChar/PChar (PAnsiChar throws a flag) to whatever you're calling. Too cool. So my code now looks like.

procedure Ttesting.DisplayPic;
var
picture : PSDL_Surface;
srcRect, dstRect: PSDL_RECT;
I: Integer;
fname : AnsiString;
begin
fname := 'fpsdl.bmp';
picture := SDL_LOADBMP(PChar(fname));
if picture = nil then
begin
ShowMessage('Couldn''t load the bmp. ' + PAnsiChar(SDL_GETERROR));
exit;
end;

Thanks for the help PJP Dev!

Andreaz
28-09-2009, 06:56 AM
The "problem", AFAIK is that D2k9 uses wide strings as the default string type:

String = type WideString;

while in previous versions

string = type AnsiString;

Thus you are sending the filename as a UTF-16 string, which SDL doesnt like to much.

GordonShumway
28-09-2009, 10:41 AM
The "problem", AFAIK is that D2k9 uses wide strings as the default string type:

String = type WideString;

while in previous versions

string = type AnsiString;

Thus you are sending the filename as a UTF-16 string, which SDL doesnt like to much.


LOL You can say that again! Unicode is nice (sort of), but man sometimes it's a REAL pain. Everyone (at least it seems like it's everyone) is still using D6, D7 or D2k7, it's as though no one cares about D2k9. So when I type in code from a tutorial I'm always wondering in the back of my mind, 'Is this code really compatible?'

GordonShumway
28-09-2009, 11:15 AM
I would like to know though why I had to create an AnsiString only to cast it back to PChar, shouldn't I just have been able to type in the name? Which by default would have been a wide char anyway. Maybe I just don't understand the differences between the Unicode and Ansi encoding. (It sucks being a noob :baby: )

pjpdev
28-09-2009, 05:05 PM
I would like to know though why I had to create an AnsiString only to cast it back to PChar, shouldn't I just have been able to type in the name? Which by default would have been a wide char anyway. Maybe I just don't understand the differences between the Unicode and Ansi encoding. (It sucks being a noob :baby: )


I previously used Delphi 6 and now I'm using Lazarus. With both I could directly pass a string argument to SDL_LoadBMP


surface := SDL_LoadBMP('bitmap.bmp');


But doing it with a string variable requires you to make it a pointer:


var
sFilename: String;
...

surface := SDL_LoadBMP(PChar(sFilename));


Thats where I made most of my mistakes... lol :baby:.

GordonShumway
28-09-2009, 08:45 PM
But doing it with a string variable requires you to make it a pointer:
Thats where I made most of my mistakes... lol :baby:.
You just put a way-ward ship(me) back on course! That makes perfect sense, thanks for clearing that up.


I previously used Delphi 6 and now I'm using Lazarus. With both I could directly pass a string argument to SDL_LoadBMP

Yes, this example worked perfectly with Lazarus. (It's funny that a 'free' IDE can do some pretty incredible things that an overpriced IDE has problems with or just doesn't even bother to support.)