Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Loading stuff from datafile question

This thread is locked; no one can reply to it. rss feed Print
Loading stuff from datafile question
The_Wind
Member #9,128
October 2007

Hi. I would like to load something from a datafile. I can get it work with the codes below:

BITMAP *bmp;
DATAFILE *dat;

dat = load_datafile("myfile.dat");
bmp = (BITMAP *)dat[COOL_PICTURE].dat;

However, is it possible to make the 'COOL_PICTURE portion to be dynamic?
Such as:

string pictureName = "COOL_PICTURE";
BITMAP *bmp;
DATAFILE *dat;

dat = load_datafile("myfile.dat");
bmp = (BITMAP *)dat[pictureName].dat;

Which of course did not work. I'm just asking is there a way so I can get input and load the stuff I call for?

Edward Sheets
Member #4,734
June 2004
avatar

pictureName needs to be an int, not a string. Basically, when you refer to an item in a datafile you are just pointing to a member of an array. You could do this:

#define COOL_PICTURE 1
//be careful not to access beyond the limits of the datafile array!
int myPictureName = COOL_PICTURE;

Provided that the picture you are referring is in the given place in your datafile. You can look at the header file produced by grabber to find out where the bitmap is in the datafile and use that integer to reference the items in the datafile.

---

Note: carving a pentagram on the top of a container of spoiled yogurt does not summon a yogurt demon. -Kikaru

kazzmir
Member #1,786
December 2001
avatar

For animations and stuff I used to put in dummy markers in the datafile and use an offset from that to get the current sprite.

int offset = 1;
int start = EXPLODE_MARKER;
while ( offset = 1; offset < 10; offset++ ){
   draw_sprite( buffer, datafile[ start + offset ], ... );
}

So you can loop over sprites easily.

ImLeftFooted
Member #3,935
October 2003
avatar

Quote:

However, is it possible to make the 'COOL_PICTURE portion to be dynamic?

Yes. I am with you, this is much nicer then all this 'locate by index' stuff from the 80s.

string pictureName = "COOL_PICTURE";
BITMAP *bmp;
DATAFILE *dat;

dat = load_datafile("myfile.dat");
bmp = (BITMAP *)find_datafile_object(dat, pictureName.c_str()).dat;

The_Wind
Member #9,128
October 2007

Dustin Dettmer got the one I was looking for, yet the code provided still did not work :(

I was trying to get input for the name of the image and load it from a datafile. So I guess I have to get input as interger instead?

Audric
Member #907
January 2001

It should work, what message do you get?
(check the manual page for find_datafile_object(), it's exactly what you asked for. )

Edward Sheets
Member #4,734
June 2004
avatar

I think this should do the trick:

DATAFILE *tmp;
const char *pictureName;

pictureName = "COOL_PICTURE";

tmp = load_datafile_object("DatafileName.dat", pictureName);

[edit] Fixed.

---

Note: carving a pentagram on the top of a container of spoiled yogurt does not summon a yogurt demon. -Kikaru

The_Wind
Member #9,128
October 2007

It was a compile error. I think it is because that extra ".dat" at the end. I took it out and it could compile.

string pictureName = "COOL_PICTURE";
BITMAP *bmp;
DATAFILE *dat;

dat = load_datafile("myfile.dat");
bmp = (BITMAP *)find_datafile_object(dat, pictureName.c_str());

However, it does not load the image I want :(
I tried to save the bitmap it loaded, but it just saved a empty bitmap.
When I use

bmp = (BITMAP *)dat[COOL_PICTURE].dat;

it could actually save the bitmap correctly...

This is getting me headache now...

amber
Member #6,783
January 2006
avatar

Quote:

load_datafile_object("DatafileName.dat", pictureName);

This sort of thing works too (well, it would work if you stored the return value somewhere), but the problem with this one is that then you're stuck with a datafile, not a bitmap.

So, you'll get memory leaks if you try something like:

BITMAP *dont_do_this(const char *df, const char *bmp) {
   DATAFILE *tmp;
   tmp = load_datafile_object(df, bmp);
   return ((BITMAP*)tmp->dat);
}

As a completely different approach, you could try storing the images in the datafile not as Allegro BITMAP types, but as PCX/BMP/whatever images. (You can just import them as binary files in the grabber)

Then, do something like:

BITMAP *bmp;
bmp = load_pcx("datafile.dat#PICTURENAME", NULL);

The # means "yank this image file out of the datafile," and it's handy. ;D

The_Wind
Member #9,128
October 2007

amber
My image was "Test.bmp" and it is grabbed and stored in the datafile as COOL_PICTURE.
I tried your stuff but the image cannot be load.

BITMAP *bmp;
bmp = load_pcx("datafile.dat#COOL_PICTURE", NULL);

amber
Member #6,783
January 2006
avatar

Are you using that exact code?
That is, are you using load_pcx to try to load a .bmp?

ImLeftFooted
Member #3,935
October 2003
avatar

Quote:

the code provided ***** did not work

I can now see a typo in my code. This code uses the -> operator insted of the . operator. Here is the revised code.

string pictureName = "COOL_PICTURE";
BITMAP *bmp;
DATAFILE *dat;

dat = load_datafile("myfile.dat");
bmp = (BITMAP *)find_datafile_object(dat, pictureName.c_str())->dat;

As a second chance to learn something, try to associate the error message the compiler gave you with a mistake of . in place of ->. Next time you see it you may more easily find the error yourself.

***** the word 'still' omitted because my response ignores it and in this context it is grammatically incorrect.

Edward Sheets
Member #4,734
June 2004
avatar

The above post may be the most arrogant thing I've ever seen on this forum. ;D

The_Wind, the Allegro manual is your friend. Also look at the examples provided with allegro. Combine that with a good book on C/C++ and you'll find the right solution to your problem. :)

---

Note: carving a pentagram on the top of a container of spoiled yogurt does not summon a yogurt demon. -Kikaru

The_Wind
Member #9,128
October 2007

Thank you all who replied. I got it to work now. (using Dustin Dettmer's code).

I am new to C++ (I used to code in Java), so I still can't really work with pointers that well. Sorry if my questions sounded amateur.

I now have a new question (don't want to start a new thread).
I have done a code to successfully load spritesheets from the datafile. And I have a code to cut the spritesheets to individual sprites.
I wish to store these sprites into arrays that's in another class.
Well, it did not work. I think it is because the BITMAP is a pointer or something... Can anyone help?

1BITMAP* temp_bmp;
2SomeClass sc;
3 
4for(int i = 0; i < 10; i++)
5{
6 temp_bmp = cut_sprite_sheet(i); //some method that successfully load a
7 //sprite (with load_bitmap)
8
9 draw_sprite(screen, temp_bmp, 0, 0); //test if bitmap was loaded.
10 //it worked.
11 
12 sc.saveSprite(i, temp_bmp); //method to store bitmap in array.
13}
14destroy_bitmap(temp_bmp);
15 
16draw_sprite(screen, sc.getSprite(0), 50, 50); //Crashed right here!!!
17 //seems like sprite was NULL
18 
19 
20 
21 
22 
23//***SomeClass....
24BITMAP* sprites[10];
25 
26void SomeClass::saveSprite(int i, BITMAP* bmp)
27{
28 sprites<i> = bmp;
29}
30 
31BITMAP* SomeClass::getSprite(int i)
32{
33 return sprites<i>;
34}
35//***End SomeClass

Audric
Member #907
January 2001

The line destroy_bitmap(tmp_bmp); is wrong, because it unloads from memory the latest bitmap (sprite[9] now points to a freed BITMAP)

But that doesn't explain why sprite[0] is not ok :-/

Jonatan Hedborg
Member #4,886
July 2004
avatar

First of all, use the stl vector. Google it. It will make you happy.

Secondly, that destroy_bitmap() is probably the problem, depending on how your cut_sprite_sheet(int) is implemented. And either way it should not be there (see previous post).

Audric
Member #907
January 2001

Wait, you have temp_bmp and tmp_bmp.
There's something fishy there.

The_Wind
Member #9,128
October 2007

Audric said:

Wait, you have temp_bmp and tmp_bmp.
There's something fishy there.

Ah, that was a typo when I posted the simplified code. Fixed now.

Taking out the destroy_bitmap(temp_bmp) still did not work. But I was trying to make a 'copy' of the temp_bmp and store it inside an array. If the array is simply just pointing to the temp_bmp then it does not work the way I want...

Trying to implement vector now, might take some time.

//EDIT

Aghh, what I thought so. It is a pointer to the temp_bmp that is stored into the array (now, the vector). So after destroy_bitmap(temp_bmp), the bitmap in the array aslo is gone.

I loaded the sprite directly to the array in SomeClass now, and it finally worked. Thank you to all who replied. I might need to learn more about these pointer sruff...

Jonatan Hedborg
Member #4,886
July 2004
avatar

void SomeClass::saveSprite(int i, BITMAP* bmp)
{
     sprites<i> = bmp;
}

That does not copy the bitmap. That copies the pointer to a bitmap. It will still "point" at the same memory adress (and therefore the same BITMAP).
You copy a bitmap by making a new bitmap of the correct size (create_bitmap(old->w, old->h)) and then blitting the old bitmap to the new one.

Post your cut_sprite_sheet() function.

Also, please read up on basic C/C++ :)

The_Wind
Member #9,128
October 2007

Jonatan Hedborg, thanks for reply. But I got it worked already :D

Yes I will go ahead and read some C++ stuff. Right now my computer class is just teaching logic... Something like P -> Q = F, P = T, Q = F... stuff.

I have NO idea how does that going to help me programming, but that is required and what I'm learning now.

Edward Sheets
Member #4,734
June 2004
avatar

Logic is the heart and soul of programming.

---

Note: carving a pentagram on the top of a container of spoiled yogurt does not summon a yogurt demon. -Kikaru

Go to: