Sign in to follow this  
TTT_Dutch

Using char as byte problem

Recommended Posts

Hello all!

I am working on a 2D Tile Engine and I am trying to store the whole map in memory. The map is just ID's for tiles. Since my map is 4096*4096 tiles big, I am trying to store an array of 4096*4096 chars. When I try to compile the code that stores the chars, I get this error:

 error: cannot convert ‘uint8 (*)[4096] {aka unsigned char (*)[4096]}’ to ‘uint8* {aka unsigned char*}’ in assignment

And here is my code:

//Load all tiles into memory
   m_Tile = new uint8[MAP_WIDTH][MAP_HEIGHT];

//m_Tile is a protected variable in the map class( uint8 *m_Tile; )
//uint8 is type defined as an unsigned char.

Can someone please tell me what is going here? I can do this operation when I define uint8 as an int but not when its a char... :/

EDIT: 

Doesn't work with int either.

Edited by Riztro

Share this post


Link to post
Share on other sites

I think you are assigning a pointer (that is an array) of arrays to a pointer. Notice the different types it says you are converting between?

 

error: cannot convert ‘uint8 (*)[4096] {aka unsigned char (*)[4096]}’ to ‘uint8* {aka unsigned char*}’ in assignment
 
From uint8*[] to uint8*.
Or, in another sense*, from uint8[][] to uint8[].

 

*Not technically accurate, but for illustrative purposes. [] is not identical to *, even if [] can convert to *.


It'd be easiest to just have it as a one-dimensional array that you treat like a 2D array:
 

m_Tile = new uint8[MAP_WIDTH * MAP_HEIGHT];
 
m_Tile[(y * MAP_WIDTH) + x] = blah;

 
 
[hr]
 
But why not use a one-dimensional std::vector so the memory is managed for you?
 

std::vector<uint8> m_Tiles(MAP_WIDTH * MAP_HEIGHT);

 
 
 

uint8 myClass::GetTile(unsigned x, unsigned y)
{
    return this->m_Tiles[(y * MAP_WIDTH) + x];
}
Edited by Servant of the Lord

Share this post


Link to post
Share on other sites

I think you are assigning a pointer (that is an array) of arrays to a pointer. Notice the different types it says you are converting between?

 

error: cannot convert ‘uint8 (*)[4096] {aka unsigned char (*)[4096]}’ to ‘uint8* {aka unsigned char*}’ in assignment
 
From uint8*[] to uint8*.
Or, in another sense*, from uint8[][] to uint8[].

 

*Not technically accurate, but for illustrative purposes. [] is not identical to *, even if [] can convert to *.


It'd be easiest to just have it as a one-dimensional array that you treat like a 2D array:
 

m_Tile = new uint8[MAP_WIDTH * MAP_HEIGHT];
 
m_Tile[(y * MAP_WIDTH) + x] = blah;

 
 
[hr]
 
But why not use a one-dimensional std::vector so the memory is managed for you?
 

std::vector<uint8> m_Tiles(MAP_WIDTH * MAP_HEIGHT);

 
 
 

uint8 myClass::GetTile(unsigned x, unsigned y)
{
    return this->m_Tiles[(y * MAP_WIDTH) + x];
}

Ohhh okay thankyou!! It compiles! biggrin.png And I just want to use dynamic memory because it is a bit quicker when I access it every draw call.

But now I have run into another problem, I wrote a program that generates tile IDs in the range of 0 to 1, but it is generating way more than I want. Can anyone tell me why? Here is my function:

//Little program to generate test map with only 0 and 1 tile

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>

using namespace std;

int main()
{
   ofstream file;
   file.open("default.vmf", ios::trunc);
   for (int j = 0; j < 4096; j++) 
   {
      for (int i = 0; i < 4906; i++) 
      {
         file << rand()%2;
      }
      file << '\n';
   }
   file.close();
   return 0;
}

 

So the file size should be (4096*4096) + 4096 == 16781312 right? Because I am filling up all the tiles and adding \n at the end of every 4096 tiles. But then after my program runs, the file is 20099072 bytes large. I don't understand what is happening here :/

 

EDIT: Just saw the problem.. I made a typo, 4906 instead of 4096 :p

Edited by Riztro

Share this post


Link to post
Share on other sites
Ohhh okay thankyou!! It compiles! biggrin.png And I just want to use dynamic memory because it is a bit quicker when I access it every draw call.

A) Optimizing prematurely causes more pain then it saves. wink.png

B) Unless you are running in debug mode, the speed of std::vector::operator[] should be about identical to a raw pointer's [] subscript operator.

C) If it's not identical, you could get the pointer to vector[0] (.data() in C++11) and treat it as a normal array anyway, but the dynamic memory will still be managed for you safely.

D) The C++ standard library is heavily optimized by the people who wrote the compiler you're using, I think it's rather fast enough. smile.png

 

To correct myself: if you are using C++11 (the latest version of C++ standardized last year), the correct container would probably be std::array<> or std::vector<>, but you might not have that available yet.

Share this post


Link to post
Share on other sites

Alright guys now I feel as though I am going about this whole tile based game all wrong. Anyone have any suggestions on what I should do to make a top down tile based game? Any good engines out there that are cross OS (linux,win,mac)? I could make my own but I feel as though it would take too much time away from development of the actual game and I would just be reinventing the wheel. Or do you think that I should be trying to make my own TileEngine (never done it before)?

 

 

Thanks for all your suggestions so far guys!

-Brent

Edited by Riztro

Share this post


Link to post
Share on other sites

I just spent 12+ hours overhauling my Tile-System (Thus the new screenshot on my blog :)!).

 

I had a struct which held the Tiles's type (Which is an Enumeration) and it's position relative to other tiles. I then made a Two-Dimensional vector of the struct which was used for my map. All I have to do now if I am using the system for another project is change the Enumeration's definitions and the images it loads (Very easy!). If you would like to look at the source code you can PM me, however keep in note the system is written in C++ (The system is universally applicable however smile.png!).

Edited by superman3275

Share this post


Link to post
Share on other sites
I wouldn't say writing your own tile engine is going about it the wrong way. It's not so difficult and a good learning experience.

You could take a look at some tile editors though, and see how they store their data. Although I suspect that with that map size, you're planning on random generation.

Share this post


Link to post
Share on other sites
For my tile engine im going to have a list of tile definitions, so i can ask a tile definition what it looks like given the world and a position (so it can access the tile data and all surroundings etc.)

:3

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this