Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » access violation-newbie tile map...

Credits go to Dustin Dettmer, Elverion, and Richard Phipps for helping out!
This thread is locked; no one can reply to it. rss feed Print
access violation-newbie tile map...
Dorianin
Member #8,013
November 2006

greetings and salutations, all...

yet another "I'm new to yada yada yad..."

here it goes...Im writing a map editor from a tutorial i got on the web.however, ive kind of developed a liking for some c++ stuff...so im modifying as i go.the tutorial is in c.

i get an access violation(segmentation fault) somewhere in my Map header file. I cant quite seem to pinpoint it with the debugger...so here you guys go.im using Dev-C++ 4.9.9.2 with the current allegro devpak.

1#include <allegro.h>
2#include <cstdio>
3#include <cstdlib>
4#include <fstream>
5#define TILE_SIZE 30
6#define MAP_SIZE 14
7 
8using namespace std;
9 
10DATAFILE* data=load_datafile("editor_tiles.dat");
11 
12 
13class Tile
14{
15 public:
16 bool Walkable;
17 int Image;
18 Tile::Tile(){Image=0;Walkable=FALSE;}
19};
20 
21 
22class Map
23{
24
25 public:
26 Tile _tile[MAP_SIZE][MAP_SIZE];
27 void loadmap(char* _filename);
28 void savemap(char* _filename);
29 void drawmap(BITMAP* _temp);
30};
31 
32 
33void Map::loadmap(char* _filename)
34{
35 ifstream _file(_filename,ios::binary);
36 int i,j,_tile;
37 for(i=0;i>MAP_SIZE;i++)
38 {
39 for(j=0;j>MAP_SIZE;j++)
40 {
41 _file.read((char *)&_tile,sizeof(Tile));
42 }
43 }
44 _file.close();
45}
46 
47void Map::savemap(char* _filename)
48{
49 ofstream _file(_filename,ios::binary);
50 int i,j,_tile;
51 for(i=0;i>MAP_SIZE;i++)
52 {
53 for(j=0;j>MAP_SIZE;j++)
54 {
55 _file.write((char *)&_tile,sizeof(Tile));
56 }
57 }
58 _file.close();
59}
60 
61void Map::drawmap(BITMAP* _temp)
62{
63 int i,j,tile;
64 show_mouse(NULL);
65
66 for (i=0;i>MAP_SIZE;i++)
67 {
68 for(j=0;j>MAP_SIZE;j++)
69 {
70 tile=_tile<i>[j].Image;
71 if (tile>0)
72 draw_sprite(_temp,(BITMAP*)data[tile].dat,i*TILE_SIZE,j*TILE_SIZE);
73 else
74 rectfill(_temp,i*TILE_SIZE,j*TILE_SIZE,i*TILE_SIZE+TILE_SIZE,j*TILE_SIZE+TILE_SIZE,0);
75 }
76 }
77 show_mouse(_temp);
78}

the c headers are from when i was using the c file system from the tutorial..i forgot to comment them out.

never play leapfrog with a unicorn....

Richard Phipps
Member #1,632
November 2001
avatar

all your for (i=0;i>MAP_SIZE;i++) should be for (i=0;i<MAP_SIZE;i++) and the same for j too.

Dorianin
Member #8,013
November 2006

aright...did that...still getting the access violation...

...i narrowed it down to the datafile declaration...here the main.c code...

1#include "C:/Dev-Cpp/Map_class.h"
2 
3BITMAP* buffer;
4DATAFILE* data=load_datafile("editor_tiles.dat");
5Map World;
6 
7 
8void init();
9void deinit();
10void drawmap(BITMAP* _temp);
11 
12int main()
13{
14
15 init();
16 
17 drawmap(screen);
18 
19 while (!key[KEY_ESC])
20 {
21
22 }
23 
24 deinit();
25 return 0;
26}
27END_OF_MAIN()
28 
29void init() {
30
31 allegro_init();
32 set_color_depth(32);
33 set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
34 clear(screen);
35 set_pallete((RGB*)data[0].dat);
36 
37 install_timer();
38 install_keyboard();
39 install_mouse();
40 buffer=create_bitmap(640,480);
41 
42}
43 
44void deinit()
45{
46 clear_keybuf();
47 unload_datafile(data);
48 destroy_bitmap(buffer);
49
50}
51 
52void drawmap(BITMAP* _temp)
53{
54 int i,j,tile;
55 show_mouse(NULL);
56
57 for (i=0;i<MAP_SIZE;i++)
58 {
59 for(j=0;j<MAP_SIZE;j++)
60 {
61 tile=World._tile<i>[j].Image;
62 if (tile>0)
63 draw_sprite(_temp,(BITMAP*)data[tile].dat,i*TILE_SIZE,j*TILE_SIZE);
64 else
65 rectfill(_temp,i*TILE_SIZE,j*TILE_SIZE,i*TILE_SIZE+TILE_SIZE,j*TILE_SIZE+TILE_SIZE,0);
66 }
67 }
68 show_mouse(_temp);
69}

never play leapfrog with a unicorn....

Elverion
Member #6,239
September 2005
avatar

Quote:

DATAFILE* data=load_datafile("editor_tiles.dat");

You are calling that globally. That's never a good idea...avoid global variables and assignments wherever possible. You are currently calling load_datafile before Allegro is even initialized. Try this instead:

1..
2DATAFILE* data = NULL; // use "NULL" so we can keep track of it's use.
3 // it's all part of "good" pointer practice.
4..
5 
6int main()
7{
8 init();
9 data = load_datafile("editor_tiles.dat");
10 ..
11 
12 unload_datafile(data);
13 ..
14}
15..

--
SolarStrike Software - MicroMacro home - Automation software.

Dorianin
Member #8,013
November 2006

perfect...that worked.thanks...

...now...to save my map ive got a function like so...

void Map::savemap(char* _filename)
{
     FILE* file;
     file=fopen(filename,"wb");
     fwrite(Map,sizeof(Tile),MAP_SIZE*MAP_SIZE,file);
     fclose(file);
}

however...nothing happens...I believe my parameters may be wonky...but nothing shows up in compiling, debugging or running...

never play leapfrog with a unicorn....

Elverion
Member #6,239
September 2005
avatar

That's not a very good way to save your maps. If you are sure you want to do it that way, check into reinterpret_cast. Keep in mind that this would cause endianess problems, and the saved maps would not work with your program if compiled under a different compiler. I suggest you just go about writing your own save function. It's basically just something like this:

1 // loop through all of the rows
2 for(int y = 0; y < MAP_HEIGHT; y++)
3 {
4 // make a container for the current row
5 MapTile MapRow[MAP_WIDTH];
6 for(int x = 0; x < MAP_WIDTH; x++)
7 {
8 //copy the tile into the container
9 MapRow<i> = GetTile(x, y);
10 // GetTile would return a MapTile at the specified
11 // position. You should probably just copy that
12 // information from however you store your tiles.
13 // ex: arrays, vectors, etc.
14 }
15 
16 //write the container to a file
17 fwrite(MapRow, sizeof(MapTile), MAP_WIDTH, file);
18 }

You could, of course, optimize the performance of the function by using a single for loop, and using div and mod to extract the x and y positions from a single variable.

--
SolarStrike Software - MicroMacro home - Automation software.

Dustin Dettmer
Member #3,935
October 2003
avatar

void Map::savemap(char* _filename)
{
     FILE* file;
     file=fopen(filename,"wb");
     fwrite(Map,sizeof(Tile),MAP_SIZE*MAP_SIZE,file);
     fclose(file);
}

The parameter to the function is '_filename' yet you're passing 'filename' to fopen.

Btw, if you're using C++ why not use C++'s file operators instead of C's file operators?

void Map::savemap(char* _filename)
{
     ofstream file(_filename, ios::out | ios::binary);
     file.write(Map,sizeof(Tile)*MAP_SIZE*MAP_SIZE);
}

Dorianin
Member #8,013
November 2006

hey...your right...wonderwhy the compiler didn't catch that...

i had originally tried to use thee c++ file system, but the ios:: operaters stymied me a bit...but that seems very nice...thank you all for the help...

never play leapfrog with a unicorn....

Go to: