How to pass a 2d tiles image to a function in C++

I’ll try to team up for the next big WIP I’m planning. Will post an announce when ready.

This is the best I did (just rotoscoped something)


@HomineLudens, let me know when you decide to make a “teaser/WIP of game I am working on” thread so I can migrate all this.

Also, very nice graphics.

If you only did the rotoscoping and didn’t make the background graphics, who did?

1 Like

Here the game where I need that function.
[Game]Pok15 [WIP]
Thanks again for the help:

A good friend of mine. Maybe I’ll will be able to involve in some development.

1 Like
template< std::size_t numberOfFrames, std::size_t imageSize >
void DrawTiles(const uint16_t * palette, const uint8_t (&images)[numberOfFrames][imageSize], int8_t textColor)

Now I’m a happy user of this pattern, but I’m encountering some problems using this with Embitz. The code works perfectly with Code::Blocks but compiling in EmBitz rise some strange erros.

The strange thing is that the it seems to happens only when using a function with this template, calling another function that use similar template.

I’m invoking @Pharap super powers!

Attached the project folder, forgive me for using header only class, I’m a bad person I know. (10.9 KB)

1 Like

Ok, this is going to be my official last post for the day :P

I think it’s possible that the error is actually nothing to do with the template.

I took the code and tried to compile it and I think I’ve found the problem.
I think it’s possible that that the compiler doesn’t like that you’ve got an unused variable.
For some reason there are certain ‘warning’ situations that EmBitz flags as errors.
I suspect it’s something in the project settings that can be changed though.

I never actually got it fully compiling because FixMath kept giving me various errors.

1 Like

It would be kindly if it tell me in a better way.
Anyway that was the point, just removed the “unused/debugging” variable and everything compile correctly.

Kudos @Pharap

1 Like

It sort of does tell you.
The warning saying ‘unused variable’ is underneath the red error message.
I admit that it probably should be highlighted in red as well though.

There should be a way to make it not flag up unused variables as errors.
I’m not sure if it’s a bug in the system, an ill-conceived ‘feature’ or if something somewhere is using a pragma to force that particular warning into an error.


Let’s suppose now I need to incapsulate a couple or more of 2d const array in a object.
The plan is to have a Layer.h class that have a “reference” to immutable 2d array that describe the tiles with another 2d array that keep track of rendering modification or functionality of the tiles.

Should the Layer.h class keep a pointer to the 2d array? If so how should I build the contstructor ?

 Layer(const uint8_t (&mapData),
          const std::bitset<4> (&mapRenders),
          const std::bitset<8> (&mapProp),
          const uint8_t (&mapAnim),
          uint8_t (&mapDmg))

And the call it like:

Layer layer1=Layer(map_1_data,map_1_renders,map_1_properties,map_1_animations,map_1_destructible);

I’m not sure exactly what you’re trying to do.
Can you break it down a bit more?

E.g maybe what the inputs will look like (in terms of how they’re declared/defined).

Also, just so you know, creating an array of std::bitset<4> won’t pack the bitsets together, each bitset will still occupy a whole byte.

Sure, that was quite smoky also for me.
You can reference the code posted before for the basic structure of this small project I’m working on.
Basically it’s a 2d platform game where the map is stored as 2d array of tiles index.

const uint8_t map_0_data[14][64] ={...}

Toghether with this there is also another 2d array of the same dimension that store various bit that contains rendering info

const std::bitset<4> map_0_renders[14][64] ={...}

This is used to flip the tiles or rotate them.

There’s also another 2d array that store tiles properties (solid, animated, destructible etc etc)

const std::bitset<8> map_0_properties[14][64] ={...}

Note all this arrays are const to avoid use precious ram. There should be some other data that will not be const to keep track of map modifications.
Now I’d like to pack all this data together, maybe storing as reference in a Layer class, keeping a reference (pointer?) to original data. In this way I can build some common methods to manipulate and render the map all together.

Now I’ve a ugly but workink method that looks like

    template<std::size_t col, std::size_t row, std::size_t lenA,std::size_t lenD>
    void drawMap(Camera *cam,
                 const uint8_t (&mapData)[col][row],
                 const std::bitset<4> (&mapRenders)[col][row],
                 const std::bitset<8> (&mapProp)[col][row],
                 const uint8_t (&mapAnim)[lenA],
                 uint8_t (&mapDmg)[lenD])

Where I’d like to call something like

Layer l1=new Layer(mapdata,render,prop);

//inside main loop

Maybe packing using a structure?


is there a way to optimize more?

Firstly, is there a reason you want 3 separate arrays instead of one large one?

Secondly, if you’re giving each bit a special meaning then I’d suggest either wrapping the bitsets in another class, e.g.

class TileRenderProperties
	static constexpr std::size_t FlipBitIndex = 0;

	std::bitset<4> bits;
	bool hasFlipBit(void) const
		return this->bits[FlipBitIndex];
	void setFlipBit(bool value)
		this->bits.set(FlipBitIndex, value);

Or perhaps even doing the bit shifting yourself in this case.

std::bitset is a good match for when you just need arbitrary bits or you don’t feel confident enough to write your own bit handling, but if you’re giving bits special meanings and you think you’re up to it then doing your own bit manipulation might be worthwhile.

Assuming that you can’t split your arrays up into separate values then you’re going to end up with large templates, there’s little choice in the matter.

Yes, but you’d have to write something to manually handle the bit packing.

I could probably write something suitable, but I’d need to know as much detail about the use case as possible and I’d rather leave it till tomorrow because I’ve been juggling a lot of things and it would require more focus.

new is for dynamic allocation only, and you probably don’t want to be dynamically allocating.

Well the idea behind is simply that when I need to render a tiles at cell X,Y I can simply extract the index from
map_data[x][y] and get rendering information at render_data[x][y], same 2d address.

//Pseudo code
for(int x=0:x<12;x++){
 for(int y=0:y<12;y++){

Bit data etc will be optimized later

Not really if I can just allocate some pointers to my data.

I’m still confused.

Why do you want to do:

tileId = tileData[y][x];
flip = renderData[y][x].getFlip();

Rather than:

tileId = mapData[y][x].getTileId();
flip = mapData[y][x].getRenderData().getFlip();

Or even:

mapDataObject = mapData[y][x];
tileId = mapDataObject.getTileId();
flip = mapDataObject.getRenderData().getFlip();


If you don’t need the 3 arrays to be separate then you could make matters easier by fusing the 3 into 1.
(Although you might miss out on an opportunity to save memory with the render flags.)

That’s good to me!
When you said only one array I didn’t understand what kind of array were you thought about. I get the idea of fuse all data in a huge array [width3][height3]. That sound soo ugly.

I have seen people attempt things like that before.
It’s a terrible idea.

If I knew what all your map properties, render flags etc were then I could write an example.

I believe simply need a proof of concept, then I’ll try to elaborate more.
Also for the 4 bit occupying 1 full byte, is not a big issue right now.

For now every Tile have:

  • Id uint8_t
  • bitset<4> renders: FlipH,FlipV,Rotate1,Rotate2
  • bitset<8> properties: Solid,Visible,Action,Destructible,Animated,Mass,Movable,Blocking

Destructible table is something like:
uint8_t map_1_destructible[]

So when I found a tile that is destructible I look in the table for a specific row and column. If found I decrease the life.
This should limit RAM usage.

For animations there’s something similar but I’ll change it, because it’s a waste of memory have different animation for every combination of row-cell. I’ll simply look for the specific tile id.

Ok, I’ve finished writing something.
It looks like a lot of boilerplate, but it’s not.

I haven’t tested it so let me know if it doesn’t compile.
I’ve assumed since you were asking about EmBitz that you have access to C++11, if you don’t it’ll need a big rewrite.

You can create an array like:

const Tile tileMap[2][2] =
	{ Tile(4, TileRenderFlags::FlipH | TileRenderFlags::FlipV, TilePropertyFlags::Solid), Tile(3, TileRenderFlags::FlipV, TilePropertyFlags::Visible) },
	{ Tile(4, TileRenderFlags::FlipH | TileRenderFlags::FlipV, TilePropertyFlags::Solid | TilePropertyFlags::Visible), Tile(3, TileRenderFlags::FlipV, TilePropertyFlags::Visible) },

And then to test stuff you can do things like:

const Tile tile = tileMap[0][0];

// Test if the tile is both visible and solid
bool isSolidAndVisible = tile.getPropertyOptions().hasAllFlags(TilePropertyFlags::Solid | TilePropertyFlags::Visible);

// Test if the tile is using FlipV or FlipH
bool usesFlipping = tile.getRenderOptions().hasAnyFlags(TileRenderFlags::FlipV | TileRenderFlags::FlipH);

I debated whether to allow stuff like tile.getPropertyOptions().isVisible() (which could still be enabled),
but I decided against it because even though it’s often easier to read, it could lead to larger and slower code.

For example, the following two things are logically equivalent:

// Option 1
if(tile.getPropertyOptions().isSolid() && tile.getPropertyOptions().isVisible())

// Option 2
if(tile.getPropertyOptions().hasAllFlags(TilePropertyFlags::Solid | TilePropertyFlags::Visible))

But ‘Option 2’ is done using bitshifting and ‘Option 1’ probably requires more jumps (depending on how good the compiler is), so it makes sense to use the second version, even if the syntax isn’t as nice.

I find it kind of odd that Visible isn’t part of RenderFlags instead of PropertyFlags.

1 Like

Wow! That’s a big help!
Going to study in depth. Precious reference for develop.

1 Like

If there’s anything you don’t understand about it, don’t be afraid to ask.

I’ve mixed a lot of different techniques to create that code,
and I didn’t learn all those techniques in one day.
Being able to craft solutions like this takes a lot of learning and discovery.

I’d like to investigate more on the subject and I’m still curious if there’s a way to keep a pointer to a 2d array of const inside a class instance.
After some research I’m a bit confused if there’s a way at all.