Jump to content

  • Log In with Google      Sign In   
  • Create Account


Using char as byte problem


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
9 replies to this topic

#1 Riztro   Members   -  Reputation: 240

Like
0Likes
Like

Posted 23 December 2012 - 02:54 PM

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, 23 December 2012 - 03:05 PM.


Sponsor:

#2 Servant of the Lord   Crossbones+   -  Reputation: 17154

Like
3Likes
Like

Posted 23 December 2012 - 03:08 PM

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;

 
 
 
 
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, 23 December 2012 - 03:20 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.

[Fly with me on Twitter] [Google+] [My broken website]

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.                                                                                                                                                       [Need free cloud storage? I personally like DropBox]

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal


#3 Riztro   Members   -  Reputation: 240

Like
0Likes
Like

Posted 23 December 2012 - 04:42 PM

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;

 
 
 
 
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, 23 December 2012 - 04:46 PM.


#4 Paradigm Shifter   Crossbones+   -  Reputation: 5132

Like
2Likes
Like

Posted 23 December 2012 - 04:44 PM

4906 != 4096 ;)
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#5 Paradigm Shifter   Crossbones+   -  Reputation: 5132

Like
0Likes
Like

Posted 23 December 2012 - 04:53 PM

That's why you shouldn't use magic numbers.<br /><br />const int MAPSIZE = 4096;<br /><br />or something similar.
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#6 Servant of the Lord   Crossbones+   -  Reputation: 17154

Like
1Likes
Like

Posted 23 December 2012 - 05:17 PM

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.


It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.

[Fly with me on Twitter] [Google+] [My broken website]

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.                                                                                                                                                       [Need free cloud storage? I personally like DropBox]

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal


#7 Riztro   Members   -  Reputation: 240

Like
0Likes
Like

Posted 23 December 2012 - 05:48 PM

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, 23 December 2012 - 05:51 PM.


#8 superman3275   Crossbones+   -  Reputation: 1976

Like
1Likes
Like

Posted 23 December 2012 - 10:18 PM

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, 23 December 2012 - 10:19 PM.

I'm a game programmer and computer science ninja ph34r.png!

Here's Breakout:
Breakout!

Want to ask about Python and / or Pygame? What about HTML5 / CSS3 / JavaScript? What about C++ and / or SFML 2 (and 1.6)? Recruiting for a game development team and need a passionate programmer? Just want to talk about programming? Email me here:

Superman3275@Gmail.com

or Personal-Message me on here smile.png!


#9 EWClay   Members   -  Reputation: 655

Like
0Likes
Like

Posted 24 December 2012 - 05:30 PM

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.

#10 Waterlimon   Crossbones+   -  Reputation: 2362

Like
0Likes
Like

Posted 24 December 2012 - 05:44 PM

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

Waterlimon (imagine this is handwritten please)





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS