Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » HOW TO LOAD DATA FILE OBJECT...!!!!!!!!

Credits go to BAF, Corelian, Thomas Fjellstrom, Tobias Dammers, and umperio for helping out!
This thread is locked; no one can reply to it. rss feed Print
HOW TO LOAD DATA FILE OBJECT...!!!!!!!!
tibgamer
Member #6,859
February 2006
avatar

HI fellaws..

I am new to the data file concept...so..I wrote the below code in C to load a datafile containing only one object called "image0.bmp". It get compiled fine without error but during the runtime..it shows window error and couldn't able to load the dat file..help me out please...

I have three files namely: main.c, grab_exp.h, and input.h

===================================================================================
This is my main.c file:

#include <stdio.h>
#include <stdlib.h>
#include <allegro.h>
#include "grab_exp.h"
#include "input.h"

int main(int argc, char *argv[])
{
allegro_init();

DATAFILE *data_object;
BITMAP *bmp;

data_object = load_datafile_object ("grab_exp.dat", "image0");

if (!data_object) {
/* report an error! */
return;
}
bmp = create_bitmap(SCREEN_W, SCREEN_H);
bmp = (BITMAP *)data_object[image0].dat;
blit(bmp, screen, 0, 0, 0, 0, bmp->w, bmp->h);

destroy_bitmap(bmp);
unload_datafile_object(data_object);

allegro_exit();
return 0;
}
END_OF_MAIN()

===================================================================================
This is my grab_exp.h

/* Allegro datafile object indexes, produced by grabber v4.0.3, MinGW32 */
/* Do not hand edit! */

#define image0 0 /* BMP */
//#define image1 1 /* BMP */
//#define image2 2 /* BMP */

===================================================================================
This is my input.h

extern DATAFILE *data_object;
extern BITMAP *bmp;

===================================================================================

So...actually what I want to do is to...load one object of datafile...I had thoroughly went through both vivace examples and allegro examples..still i couldn't able to load dat file...help needed in any form and in any way... PEACE

software is not written, it is rewritten

Thomas Fjellstrom
Member #476
June 2000
avatar

You have a small error, the datafile code, in this case, the load_datafile_object creates the bitmap for you. There is no need to create_bitmap the bmp variable before hand, and leads to your actuall error, the destroy_bitmap (Freeing the bmp pointer twice), just use unload_datafile_object and you'll be fine.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Corelian
Member #3,376
March 2003
avatar

What Tomasu said, plus there are some errors and unnecessary lines.

These includes are useless:
#include <stdio.h> #include <stdlib.h> #include "input.h"

You don't need the input.h file.

You need to set gfx mode to display graphics!

Quote:

if (!data_object) {
/* report an error! */
return;
}

The return here should return a numeric value, because it terminates the program's main function. E.g. return 1;

It would be a good idea to e.g. wait for a key press before ending the program. Otherwise it'll execute in a fraction of a second.

Calling allegro_exit() is unnecessary.

BAF
Member #2,981
December 2002
avatar

And please put [code] and [/code] tags around your code.

tibgamer
Member #6,859
February 2006
avatar

hi guys...as you had pointed out the errors..i had made the required changes...but still its not showing the dat object...whats wrong this time..help...

<CODE>

#include <allegro.h>
#include "grab_exp.h"

int main(int argc, char *argv[])
{
allegro_init();
install_keyboard();

set_gfx_mode(GFX_AUTODETECT,640,480,0,0);

DATAFILE *data_object;

data_object = load_datafile_object ("grab_exp.dat", "image0");

blit(data_object, screen, 0, 0, 0, 0, 30, 30);
readkey();
unload_datafile_object(data_object);

return 0;
}
END_OF_MAIN()

</CODE>
???

software is not written, it is rewritten

Corelian
Member #3,376
March 2003
avatar

Quote:

blit(data_object, screen, 0, 0, 0, 0, 30, 30);

Completely off the top of my head, but shouldn't it be data_object->dat there? Read the Allegro manual pages about datafiles. They contain plenty of examples.

Use [ and ] for those code tags. To see the available tags, click the "[url http://www.allegro.cc/mockup.html]
HTML Mockup Code[/url] is enabled."-link above the text field when writing posts.

tibgamer
Member #6,859
February 2006
avatar

[quote ]shouldn't it be data_object->dat
</quote>

well..i am new to allegro..so thats why am making lots of mistake..anway..i read the manual..and it says that struct DATAFILE consist:

void *dat; - pointer to the actual data
int type; - type of the data
long size; - size of the data in bytes
void *prop; - list of object properties

and since in my code...i had declared "data_object" as a pointer variable of struct DATAFILE...so..i guess..it is same as *dat..anyhow..i tried putting data_object->dat in blit..still its not working...!! Help..

software is not written, it is rewritten

Tobias Dammers
Member #2,604
August 2002
avatar

Here's how it works.

A DATAFILE object holds information about a single datafile record. Not only the actual object data, but also its size, what kind of object it is, its name, original filename, and a few more properties.
When you do a load_datafile_object(), it does the following things for you:
1. Allocate memory for the datafile object
2. Load data from disk
3. Allocate memory for the actual object data
4. Load object data from disk
5. Return pointer to allocated data
So what you get in return is a pointer to a DATAFILE object, which in turn contains a pointer to the object it describes (in the dat field).
Since Allegro is a C library (not a C++ one), and the dat field can point to anything really (BITMAP, FONT, PALETTE, raw binary data, etc.), it is implemented as a void pointer. In plain C, this is no problem, but in C++, you need to explicitly cast the pointer to a BITMAP*:

blit((BITMAP*)data_object->dat, screen, 0, 0, 0, 0, 30, 30);

Also, make sure that:
- data_object's type is actually DAT_BITMAP
- data_object is not NULL (indicating an error while loading)
- data_object->dat is not NULL (indicating that something else is wrong)
Either of these will give you unpleasant results.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

umperio
Member #3,474
April 2003
avatar

1#include <allegro.h>
2#include "grab_exp.h"
3 
4 
5int main(int argc, char *argv[])
6{
7allegro_init();
8install_keyboard();
9 
10set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
11 
12DATAFILE *data_object;
13 
14data_object = load_datafile_object ("grab_exp.dat", "image0");
15 
16blit((BITMAP *)data_object->dat, screen, 0, 0, 0, 0, 30, 30);
17readkey();
18unload_datafile_object(data_object);
19 
20return 0;
21}
22END_OF_MAIN()

This works perfectly here, if you don't want to look at the manual or at the examples please at least listen to others suggestions.

If it's not working, please describe exactly in which way is not working, assuming you didn't create a corrupted datafile.

tibgamer
Member #6,859
February 2006
avatar

hi all the guys above...

now..i am getting really cleared up..about the datafile concept..thanx a lot..now i could able to load one object of datafile on to the screen..,,now..i am trying to load more than one object onto the screen, i.e i had added one more object called "image1" in my dat file..and could successfully able to load it...though i have doubt like..there could be better way to load more than one object by using kinda arrays or stuff like that..so could you suggest any better way than the below codes....thanks a lot again...:-) PEACEEEE

1 
2#include <allegro.h>
3#include "grab_exp.h"
4 
5 
6int main(int argc, char *argv[])
7{
8 allegro_init();
9 install_keyboard();
10 
11 set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
12 
13 DATAFILE *data_object, *data_object1;
14 BITMAP *bmp;
15 
16 bmp = create_bitmap(SCREEN_W, SCREEN_H);
17 clear(bmp);
18 data_object = load_datafile_object ("grab_exp.dat", "image0");
19 data_object1 = load_datafile_object ("grab_exp.dat", "image1");
20 draw_sprite(bmp, (BITMAP *)data_object->dat, 10, 10);
21 draw_sprite(bmp, (BITMAP *)data_object1->dat, 100, 100);
22 blit(bmp, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
23 
24
25 readkey();
26 unload_datafile_object(data_object);
27 unload_datafile_object(data_object1);
28 destroy_bitmap(bmp);
29 
30return 0;
31}
32END_OF_MAIN()

software is not written, it is rewritten

CursedTyrant
Member #7,080
April 2006
avatar

Why don't you use a for loop for loading the objects? It should work fine. I remember doing this a very different way, but unfortunately I don't have the time now to check and post my code here. I might be able to do that later when I'm back home.

---------
Signature.
----
[My Website] | [My YouTube Channel]

Tobias Dammers
Member #2,604
August 2002
avatar

That's exactly what load_datafile() is for. Instead of painstakingly loading individual objects and managing memory for them, you can load an entire datafile into memory. RTFM to see what I mean. The basic idea is this:
1. Create your datafile using grabber or dat. I'll assume it's called "data.dat".
2. Export datafile object names to a header file (the -h switch in dat.exe); I'll assume "data.h".
3. In your main program, #include "data.h"
4. Use load_datafile() (after allegro_init() of course) to load the entire datafile into memory at once, like so:

DATAFILE* data;
allegro_init() // etc.; set up allegro nicely
data = load_datafile("data.dat");

5. data now contains an array of DATAFILE objects, and the header you included gives you handy defines to access them directly and with virtually no performance overhead, like this:

// assuming you have loaded the datafile, and there is an image called "image1.bmp" in it:
draw_sprite(screen, (BITMAP*)data[IMAGE1_BMP]->dat, 100, 100);

And at the end of your program, you should free the memory allocated by the datafile array by calling:

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

That's exactly what load_datafile() is for. Instead of painstakingly loading individual objects and managing memory for them, you can load an entire datafile into memory.

Which is a horrible idea if you're only going to need a small portion of the datafile loaded into memory at any given time. Not wasting memory is A Good Thing(tm) :)

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Tobias Dammers
Member #2,604
August 2002
avatar

Not over-complicating code is also a Good Thing. A typical newbie game is small, so small that the amount of data in memory is a non-issue. Loading datafile objects one by one requires you to keep track of each one individually, and every time you add an object to the datafile, you need to change the loading code. This creates a lot of opportunities for nasty bugs and memory leaks - not exactly what a beginning programmer is waiting for.
Also, one would typically use all the objects in the datafile anyway, so loading them all at once won't consume that much more memory (might even be less by avoiding loading objects twice).

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

Loading datafile objects one by one requires you to keep track of each one individually, and every time you add an object to the datafile, you need to change the loading code.

No you don't.
data_object = load_datafile_object ("grab_exp.dat", "image0");
will always load the object named "image0" into data_object. You can add or remove things in the datafile as you want, and as long as image0 is the same, it'll work. Now, if you were loading the whole datafile at once, you'd have to recompile the parts of the program that made use of it, since the indices would change and the header would have to be remade since the values changed.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Tobias Dammers
Member #2,604
August 2002
avatar

Of course this is absolutely true. On the other hand, one typically loads the objects in one part of the program (initialization), while using them in another part (main loop, or even entity member func). If these parts are in different files, things get hackish. If they aren't, you just use indices into the global sprite list; if you try to use something that's not there, the compiler will throw it in your face. To be safe, you can set up your compile process to create the header every time, or use find_datafile_object().

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

tibgamer
Member #6,859
February 2006
avatar

hi guys...

now..i am trying to add SAMPLE file in my dat file..but i couldn't able to play it through dat file..though i could play it separately like below...tell me how to load the SAMPLE file called "frog" from dat file and play it from dat file....

1 
2#include <allegro.h>
3#include "grab_exp.h"
4 
5 
6int main(int argc, char *argv[])
7{
8 allegro_init();
9 install_keyboard();
10 
11 set_color_depth(32);
12 set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
13 
14 DATAFILE *data_object, *data_object1;
15 BITMAP *bmp;
16 SAMPLE *music_object;
17 
18 bmp = create_bitmap(SCREEN_W, SCREEN_H);
19 clear(bmp);
20
21 data_object = load_datafile_object ("grab_exp.dat", "image0");
22 data_object1 = load_datafile_object ("grab_exp.dat", "image1");
23
24
25 install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL);
26 music_object = load_sample("Frog.wav");
27
28 draw_sprite (bmp, (BITMAP *)data_object->dat, 10, 10);
29 draw_sprite (bmp, (BITMAP *)data_object1->dat, 100, 100);
30 blit (bmp, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
31
32
33 play_sample(music_object, 300, 128, 1000, TRUE);
34
35 readkey();
36 unload_datafile_object(data_object);
37 unload_datafile_object(data_object1);
38 destroy_bitmap(bmp);
39 destroy_sample(music_object);
40 
41return 0;
42}
43END_OF_MAIN()

software is not written, it is rewritten

HoHo
Member #4,534
April 2004
avatar

You should use it just the same as bitmap objects:

   DATAFILE *music_object;   
   music_object = load_sample("Frog.wav");
   play_sample((SAMPLE*)music_object->dat, 300, 128, 1000, TRUE);

Of course you could wrap some stuff around loading datafile to get the pointers to the dat fields when loading files.

I once did a very cleaver datafile loading class for my Xcom engine. All it needed was the datafile name and a text file describing the tile layers. When I loaded the file everything else worked automagically :)

[edit]

oops, I think I made a mistake. I have never used sounds in Allegro and I didn't notice that load_sample returs sample directly. That code should work if you replace the load_sample with load_datafile_object.

Also, it seems like load_sample loads stuff frome external files, not from datafiles. If you would check the return values I'm sure you would have an error in the load_sample function.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

umperio
Member #3,474
April 2003
avatar

Quote:

tell me how to load the SAMPLE file called "frog" from dat file and play it from dat file....

...please

Since it seems to me you're still learning, I'd go for a complete datafile instead of loading all the objects separately.

1#include <allegro.h>
2#include "running.h"
3 
4 
5void main() {
6 allegro_init();
7 install_keyboard();
8
9 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
10 install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL);
11
12 DATAFILE *data;
13
14 data = load_datafile("running.dat");
15 
16 if (!data) {
17 allegro_message("Error loading data");
18 exit(1);
19 }
20
21 draw_sprite(screen, (BITMAP *)data[FRAME_01].dat, 0, 0);
22 play_sample((SAMPLE *)data[SOUND_01].dat, 255, 128, 1000, 0);
23
24 readkey();
25
26 unload_datafile(data);
27}
28END_OF_MAIN()

Here I used the file running.dat from the allegro examples. Did you ever take a look at them?

BAF
Member #2,981
December 2002
avatar

You can always do load_bitmap("datafile.dat#bitmapname") too.

tibgamer
Member #6,859
February 2006
avatar

Quote:

it seems to me you're still learning

yes..i have just started out with allegro..and i have been going through the vivace tutorial..for a week or so....thats why am making lots of errors..anway..thanx for helping me out...i have been learning a lot from this forum....

oh..yes..now i could able to play SAMPLE file from dat file..Could any one tell me how to create header file index of objects from grabber..i tried going to Object menu and click export...but couldn't able to make header file...help me...!

software is not written, it is rewritten

umperio
Member #3,474
April 2003
avatar

Why don't you read how to do it?
There's a file called "grabber.txt" which can help you:

Quote:

===========================================
============ Using the grabber ============
===========================================

Various options can be set using the buttons and text fields at the top of
the screen. You can edit the name of the datafile, the name of the header
file for exporting object indexes (leave this blank if you don't want to
output a header), and the prefix string for the header file definitions.

Regards

Tobias Dammers
Member #2,604
August 2002
avatar

My, umperio, that's a mighty friendly RTFM, I say.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

tibgamer
Member #6,859
February 2006
avatar

thanks..i will check out...!

software is not written, it is rewritten

Go to: