Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Using An Array of DATAFILES

Credits go to ReyBrujo for helping out!
This thread is locked; no one can reply to it. rss feed Print
Using An Array of DATAFILES
cd wheat
Member #6,578
November 2005

I am trying to make it so that my level editor will read a directory, get all the file names of datafiles, and then count the number of bitmaps inside of the file. I am trying to make it this way so I can add and remove datafiles without hardcoding it into the editor. I can do all but the last. I read how do do it with a single declared datafile here: http://www.allegro.cc/forums/thread/311301 . My question is how do this with an array of datafiles or What other method should I use?

std::string filelist[50];//array of the data file names
int filecount //number of datafiles int he directory
DATAFILE* TileFiles[50]; //array of data files
int NumberOfBitmaps[50]; //number of bitmaps in the datafile

1void CSelectTileWindow::LoadDataFiles()
2{
3
4 for (int i = 0; i < filecount; i++)
5 {
6 TileFiles<i> = load_datafile(filelist<i>.c_str());
7 NumberOfBitmaps<i> = 0;
8
9 //This part crashes. I do not know what to do here
10 while (TileFiles<i>[NumberOfBitmaps<i>].type != DAT_END)
11 {
12 NumberOfBitmaps<i>++;
13 }
14 }
15}

Thank you for your time.

ReyBrujo
Moderator
January 2001
avatar

I would do it something like...

1std::string filelist[50];//array of the data file names
2int filecount; //number of datafiles int he directory
3DATAFILE* TileFiles[50]; //array of data files
4DATAFILE *index;
5int NumberOfBitmaps[50]; //number of bitmaps in the datafile
6 
7void CSelectTileWindow::LoadDataFiles()
8{
9 for (int i = 0; i < filecount; i++)
10 {
11 TileFiles<i> = load_datafile(filelist<i>.c_str());
12 if (TileFiles<i> != NULL) {
13 NumberOfBitmaps<i> = 0;
14 
15 index = TileFiles<i>;
16 while (index->type != DAT_END) {
17 if (index->type == DAT_BITMAP)
18 NumberOfBitmaps<i>++;
19 index++;
20 }
21 
22 unload_datafile(TileFiles<i>);
23 }
24 }
25}

Note that I don't remember if it is DAT_BITMAP or DAT_BMP, though. And I haven't checked it.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Rampage
Member #3,035
December 2002
avatar

Why don't you use nested datafiles?

-R

cd wheat
Member #6,578
November 2005

Thankyou ReyBrujo. That works perfectly.

Quote:

Why don't you use nested datafiles?

I didn't think of doing that. It sounds like a good idea though.

Dustin Dettmer
Member #3,935
October 2003
avatar

Why aren't you using a class or a struct?

cd wheat
Member #6,578
November 2005

Quote:

Why aren't you using a class or a struct?

I am using one; it is called CSelectTileWindow. LoadDataFiles() is a function of it that I had trouble getting to work, the rest of those variables were other variables in the class that were used in that function. I am trying to make a box in my tile/map/enemy placement editor that one can select stuff from and then draw it onto the map. Since I am doing my graphics last I needed a way to load datafiles and graphics in them without knowing what they are yet or how many. For right now most of the bitmaps are just randomly colored so that I know the editor is working how it is supposed to.

Dustin Dettmer
Member #3,935
October 2003
avatar

No. Thats not what I meant.
This:

std::string filelist[50];//array of the data file names
int filecount //number of datafiles int he directory
DATAFILE* TileFiles[50]; //array of data files
int NumberOfBitmaps[50]; //number of bitmaps in the datafile

should be:

class SomeName {
  std::string file;
  DATAFILE *TileFile;
  int NumberOfBitmaps;
};

std::vector<SomeName> someVariableName

If you can't understand this concept halt all your projects until you do. Your code will suck if you can't make the distinction I'm describing here.

cd wheat
Member #6,578
November 2005

I am using a class but not making a vector of them; I am using a class just to keep it organized somewhat. I just haven't had much experience with pointers or allegro but I am working on it. I just copied and pasted the code that needed to be worked on, not the whole project. This is what I have so far for this class though; I think I can do the rest.

1#ifndef SELECTTILEBOX_H
2#define SELECTTILEBOX_H
3 
4#include <iostream>
5#include <dirent.h>
6#include "Globals.h"
7 
8class CSelectTileBox
9{
10public:
11 CSelectTileBox();
12 ~CSelectTileBox();
13
14 void LoadDataFiles();
15 void UnloadDataFiles();
16
17 void Draw(int x, int y);
18 void UpdateState();
19
20private:
21
22 DATAFILE* TileFiles[50];
23 DATAFILE *index;
24 int NumberOfBitmaps[50];
25 int CurrentFile;
26
27 void ReadDir();
28 std::string filelist[50];
29 int FileCount;
30 
31};
32 
33#endif

1#include "SelectTileBox.h"
2 
3CSelectTileBox::CSelectTileBox()
4{
5 FileCount = 0;
6 CurrentFile = 0;
7 ReadDir();
8}
9 
10CSelectTileBox::~CSelectTileBox() {}
11 
12void CSelectTileBox::ReadDir()
13{
14 DIR *d = opendir("GFX");
15 struct dirent *dir;
16
17 int loc;
18 std::string filename;
19
20 if(d)
21 {
22 while ((dir = readdir(d)) != NULL)
23 {
24 filename = dir->d_name;
25 loc = filename.find(".dat", 0);
26 
27 if (loc != std::string::npos)
28 {
29 filelist[FileCount] = "GFX\\" + filename;
30 FileCount++;
31 }
32 }
33 closedir(d);
34 }
35}
36 
37void CSelectTileBox::LoadDataFiles()
38{
39 for (int i = 0; i < FileCount; i++)
40 {
41 TileFiles<i> = load_datafile(filelist<i>.c_str());
42
43 if (TileFiles<i> != NULL)
44 {
45 NumberOfBitmaps<i> = 0;
46 index = TileFiles<i>;
47 while (index->type != DAT_END)
48 {
49 if (index->type == DAT_BITMAP)
50 {
51 NumberOfBitmaps<i>++;
52 }
53 index++;
54 }
55 }
56 }
57 index = TileFiles[CurrentFile];
58}
59 
60 
61void CSelectTileBox::UnloadDataFiles()
62{
63 for (int i = 0; i < FileCount; i++)
64 {
65 unload_datafile(TileFiles<i>);
66 }
67}
68 
69void CSelectTileBox::Draw(int x, int y)
70{
71 textprintf_ex(buffer, font, x, y-16, COLOR_WHITE, -1, "%s",filelist[CurrentFile].c_str());
72
73 rectfill(buffer,x,y,x+640,y+160,COLOR_MAGNETA);
74
75 for (int i = 0; i < NumberOfBitmaps[CurrentFile]; i++)
76 {
77 draw_sprite(buffer,(BITMAP*)index<i>.dat , x+i*TILE_SIZE, y);
78 }
79
80 for (int i = x; i < x + 640; i += TILE_SIZE)
81 {
82 for (int j = y; j < y+ 160; j += TILE_SIZE)
83 {
84 line(buffer,i,j,i+TILE_SIZE,j,COLOR_YELLOW);
85 line(buffer,i,j,i,j+TILE_SIZE,COLOR_YELLOW);
86 }
87 }
88}
89 
90void CSelectTileBox::UpdateState()
91{
92
93}

Dustin Dettmer
Member #3,935
October 2003
avatar

My point is you should be using another class. You don't seem able to recognize this need.

It is completely legal and possible to have 'child' classes. Heres an example of this:

class Parent {
  class Child {
    ...
  };
  
  .. stuff ..

  Child child;
};

I refuse to help you until you can make this distinction

cd wheat
Member #6,578
November 2005

I know one can have classes declared and used inside classes because I use it for my tile map class. The class above is just to handle the selection area of the window where one chooses tiles that they want to draw on the map area of the window handled by the class below.

1#ifndef MAP_H
2#define MAP_H
3 
4#include "Globals.h"
5 
6class CMap
7{
8private:
9 class CLayer
10 {
11 private:
12 class CTile
13 {
14 public:
15 short Index;
16 short Zcoord;
17 short Transparency;
18 };
19 public:
20 CTile TileMap[256][256];
21 bool IsEmpty();
22 };
23
24 BITMAP* Image[512];
25 int x, y;
26
27 CLayer TileLayer[7];
28
29public:
30 CMap();
31 ~CMap();
32
33 void MoveMap(int xscroll, int yscroll);
34 void DrawMap(int startx, int starty);
35
36 void SaveMap(std::string filename);
37 void LoadMap(std::string filename);
38
39 void LoadBitmaps();
40 void UnloadBitmaps();
41
42};
43 
44#endif

The window looks something like this so far.

whole window 
*********************
*               * BA*      
*  Map/Level     * UR*
*  640*480     * TE*
*       * TA*
*       * O *
*       * N *
*********************
*Tile Selection Area   *            
*           *
*********************

Go to: