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

You have about 90-100k still to go (leaving space for loader)

1 Like

Sure! Code will come, I just wrote something yesterday after downloading new lib and discover mode15. Love it.
What about ask friends here post their preferite 16 color images 160x160 (not NSFW) and open a poll?
I’d like to have a persistence mode (EEPROM saving on power off?), high score and undo maybe.

I was trying to keep it C only for learning purpose… but template seems necessary.

The graphics looks super sharp on the display. Its just beautiful.

“Ask an Expert” or “Ask the Expert”? :P

Seriously though, we could just have a couple of tiers of question asking badges:
“Asked a question”, “Asked a notable question”, “Asked a famous question”

It started as a joke, now I’m not even sure if I’m joking anymore.
I think I’ll just leave that idea haning and come back to it if we need badge suggestions in the future.


Semi-related: earlier today I discovered a discourse plugin that allows threads in designated categories to be marked as ‘questions’ and then the owner of the thread can opt to select a specific post as an ‘answer’ (kind of like Stackoverflow).

It’s an interesting idea.


Strictly using C means no PokittoLib.

Using C++ that looks like C isn’t using C.
It doesn’t work like that.

1 Like

Not for sure. I’ve 0% capabilities on that field. Maybe some music attitude but graphics…

@adekto is good at graphics.

I’m sometimes good at graphics.
(I can do ‘art’ - in single quotes for legal reasons :P.)


Sidenote:
I feel like we’ve ended up going off on a tangent,
but migrating it would be awkard because the game is on the post accepting the answer.

1 Like

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)

2 Likes

@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.
HelloWorld.zip (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.

2 Likes

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

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

//inside main loop
l1.update();
l1.draw();

Maybe packing using a structure?

Also:

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
{
public:
	static constexpr std::size_t FlipBitIndex = 0;

private:
	std::bitset<4> bits;
	
public:
	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++){
  idTile=map_data[x][y];
  flip=map_data[x][y][FILP_H];
  g.DrawTile(x*8,y*8,idTile,flip);
 }
}

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.