dynamic array sizes
in my game, the main play area is a map. the map is an array[w][h] of atile (my own struct), decalred like this:
atile map[MAX_WIDTH][MAX_HEIGHT];
my MAX_''s are around 1024 each, and my atile''s take up around 20 bytes, which is 20971520 bytes :] (thats 20megs of memory peeps).
this doesnt bother me at all, its fine, but the thing is, its still 20 megs, when im using a map 20x20 instead of 1024x1024. i have a map format etc, and have a variable storing my mapw (and maph) so, the unused tiles are still there, but never attempted to be read. i need to be able to specifiy the dimensions of this map to save some memory. i know its got something to do with memalloc and resalloc i think, but i dont know how to implement it.
can some one gimme some pointers (excuse the pun). im wokring in c, i dont mind branching out into c++, and im familar with memory usage, just not when declaring variables... (msvc++ btw)
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
__________________graham "red" reeves.[email=red@deadpenguin.org]red@deadpenguin.org[/email]www.deadpenguin.org
February 03, 2001 05:16 AM
c++ way :
atile *map[width];
for (int i = 0; i < width; i ++)
{
map = new atile[height];
}
You can now access the array like any other 2 dimensional array (map[x][y]).
for deletion :
for (int i = 0; i < width; i ++)
{
delete[] map;<br>}<br><br>So all you have to do is to store the number of tiles in width and height in your map file, read it and allocate memory for the array.<br><br>Or you could use a linked list, but that''s another topic. </i>
atile *map[width];
for (int i = 0; i < width; i ++)
{
map = new atile[height];
}
You can now access the array like any other 2 dimensional array (map[x][y]).
for deletion :
for (int i = 0; i < width; i ++)
{
delete[] map;<br>}<br><br>So all you have to do is to store the number of tiles in width and height in your map file, read it and allocate memory for the array.<br><br>Or you could use a linked list, but that''s another topic. </i>
ah, nice, i already read my map''s w/h from the file etc
so now i just need something like this:
memalloc(map,width*height*sizeof(atile)); ?
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
so now i just need something like this:
memalloc(map,width*height*sizeof(atile)); ?
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
__________________graham "red" reeves.[email=red@deadpenguin.org]red@deadpenguin.org[/email]www.deadpenguin.org
correct me if I''m wrong
That way takes rather a lot of memory too.
If you have a pointer (4 bytes) to sruct of 20 bytes
it takes 20 percent more memory.
Just my thoughts
That way takes rather a lot of memory too.
If you have a pointer (4 bytes) to sruct of 20 bytes
it takes 20 percent more memory.
Just my thoughts
God saw all that he had made. Shit happens sometimes. --the sixth day.
No, it''s an array of pointers, and each points to an array. In other words, for a map with a width of 32 and a height of 64, there are only 32 pointers, each to an array of 64 tiles. That makes 32 * 64 for the number of tiles. Understand?
If you want to make a variable map width, you can use a pointer to a pointer, dynamically create an array of pointers, and then dynamically create the rows of elements like usual.
If you want to make a variable map width, you can use a pointer to a pointer, dynamically create an array of pointers, and then dynamically create the rows of elements like usual.
this has side tracked a little i think, what i need to do, is allocate memory for my pointer/array etc
how?
whatever method i use, i need to dynamically allocate memory right? so the pointers have soemthing to point to. thats what i need to find out... i think.
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
how?
whatever method i use, i need to dynamically allocate memory right? so the pointers have soemthing to point to. thats what i need to find out... i think.
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
__________________graham "red" reeves.[email=red@deadpenguin.org]red@deadpenguin.org[/email]www.deadpenguin.org
heh, the way i first understood the topic of the post now seems to be the opposite of the desired answer...
well, just cuz it could help:
the way to find the number of elements in an array is:
so, to find the number of rows would be:
and the way to find the number of columns would be:
or is that columns then rows...
dog-gone it... c for 4 years and i forget...
oh well, it should werk.
Edited by - Succinct on February 5, 2001 11:48:49 AM
well, just cuz it could help:
the way to find the number of elements in an array is:
int nElements = sizeof( Array )/sizeof( Array[0] );
so, to find the number of rows would be:
int nRows = sizeof( Map )/sizeof( Map[0] );
and the way to find the number of columns would be:
int nColumns = sizeof( Map[0] )/sizeof( Map[0][0] );
or is that columns then rows...
dog-gone it... c for 4 years and i forget...
oh well, it should werk.
Edited by - Succinct on February 5, 2001 11:48:49 AM
-- Succinct(Don't listen to me)
Here is what C++ will do for you: Create a map class
class CMyMap{
public:
CMyMap();
virtual ~CMyMap();
virtual void CreateMap(int nRow, int nCol);
virtual void DestroyMap();
atile GetTile(int nRow, int nCol);
private:
int m_nRow; //number of rows
int m_nCol; //number of columns
atile* m_pTiles; //a 4 byte pointer
};
Here is the implementation:
void CMyMap::CreateMap(int nRow, int nCol)
{
m_pTiles = new atile[nRow*nCol]; //dynamiclly allocate memory
m_nRow = nRow;
m_nCol = nCol;
//initilize
.......
}
void CMyMap::DestroyMap()
{
delete [] m_pTiles;
m_nRow = 0;
m_nCol = 0;
}
Another problem is that your atile is 20BYTE. You may need to redo the architecture a bit, because 20Byte tile sounds awful.
In most case, a tile is just an integer, sometimes (the way you do matrix shows that you map is flat so that no level info is required) and a pointer for Entities. In this case, it is only 8 Bytes. Even if level is required, that''s 12 bytes. Animated Tile will need 16 bytes (or 12 bytes if external container is used).
It looks like you will need to use pointers more often.
Hope this helps.
Turtlenet
class CMyMap{
public:
CMyMap();
virtual ~CMyMap();
virtual void CreateMap(int nRow, int nCol);
virtual void DestroyMap();
atile GetTile(int nRow, int nCol);
private:
int m_nRow; //number of rows
int m_nCol; //number of columns
atile* m_pTiles; //a 4 byte pointer
};
Here is the implementation:
void CMyMap::CreateMap(int nRow, int nCol)
{
m_pTiles = new atile[nRow*nCol]; //dynamiclly allocate memory
m_nRow = nRow;
m_nCol = nCol;
//initilize
.......
}
void CMyMap::DestroyMap()
{
delete [] m_pTiles;
m_nRow = 0;
m_nCol = 0;
}
Another problem is that your atile is 20BYTE. You may need to redo the architecture a bit, because 20Byte tile sounds awful.
In most case, a tile is just an integer, sometimes (the way you do matrix shows that you map is flat so that no level info is required) and a pointer for Entities. In this case, it is only 8 Bytes. Even if level is required, that''s 12 bytes. Animated Tile will need 16 bytes (or 12 bytes if external container is used).
It looks like you will need to use pointers more often.
Hope this helps.
Turtlenet
Succinct: That only works with arrays created on the stack, not with arrays created on the heap with new.
redmonkey: There are two ways to create an array with two dimensions. First, you can create a single dimensioned array and access it with a bit of math:
Second, you can create a multiply dimensioned array. The creation and destruction is harder, but the access is cleaner:
Now, 20 bytes is indeed large. You do not need to store the x and y of the tile in the tile struct. You really only need a pointer to the image or simply an int that holds the image id. If it is animated or has special support for blending, then it will require more. Remember that the compiler will typically pad your struct for faster access.
What data do you store in your tile struct?
redmonkey: There are two ways to create an array with two dimensions. First, you can create a single dimensioned array and access it with a bit of math:
// create a singly dimensioned array of tiles
tile* p = new tile[width * height];
// access the tile at position 10, 33
p[10 + 33 * width];
// destroy it
delete[] p;
Second, you can create a multiply dimensioned array. The creation and destruction is harder, but the access is cleaner:
// create a multiply dimensioned array of tiles
tile** p = new tile*[width];
for( int x=0; x < height; x++ ) p[x] = new tile[height];
// access the tile at position 10, 33
p[10][33];
// destroy it - note the loop!
for( int x=0; x < height; x++ ) delete[] p;
delete[] p;
Now, 20 bytes is indeed large. You do not need to store the x and y of the tile in the tile struct. You really only need a pointer to the image or simply an int that holds the image id. If it is animated or has special support for blending, then it will require more. Remember that the compiler will typically pad your struct for faster access.
What data do you store in your tile struct?
its actaully been cut down to 6 bytes, which is a bit better
my map format is just basic at the moment, the whole world is tile based, so i recognize a building by its height (1 byte)
the main tile (the top of the building, or the floor has a texture id (i have a pointer array for the textyures, which are stored via a hash table) and each side of the building has a textureid too
thats:
byte z;
byte textureid;
byte side[4];
byte angle;
at the moment, my map[][] is global, and is always
tile map[MAX_W][MAX_H];
(the max''s are defines and are both 1024)
what i need to do (i think) is change that to a pointer, and have the actaul map stuff in my winmain() or gameloop()
but, the reason this whole thread was devised, was because i cant do this:
tile map[width_read_from_mapfile][height_read_from_mapfile];
i thought id need to use memalloc, but the way i see it (from everyones postings) is that i need to do a new() tile each time...
i think thats right, but havent actually done any of this yet (ive messing with dynamic lights)
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
my map format is just basic at the moment, the whole world is tile based, so i recognize a building by its height (1 byte)
the main tile (the top of the building, or the floor has a texture id (i have a pointer array for the textyures, which are stored via a hash table) and each side of the building has a textureid too
thats:
byte z;
byte textureid;
byte side[4];
byte angle;
at the moment, my map[][] is global, and is always
tile map[MAX_W][MAX_H];
(the max''s are defines and are both 1024)
what i need to do (i think) is change that to a pointer, and have the actaul map stuff in my winmain() or gameloop()
but, the reason this whole thread was devised, was because i cant do this:
tile map[width_read_from_mapfile][height_read_from_mapfile];
i thought id need to use memalloc, but the way i see it (from everyones postings) is that i need to do a new() tile each time...
i think thats right, but havent actually done any of this yet (ive messing with dynamic lights)
__________________
graham "red" reeves.
red@deadpenguin.org
www.deadpenguin.org
__________________graham "red" reeves.[email=red@deadpenguin.org]red@deadpenguin.org[/email]www.deadpenguin.org
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement