copy_sub_bitmap() or create_sub_bitmap_copy()
ADmiral

I recently encountered this problem: that you practically can't copy a sub-bitmap or create another sub-bitmap with the same properties of an existing one. For further information read this thread.
This might be an overlooked feature; Thus my suggestion to add one of those functions to get a sub-bitmap duplicate in case you can't just copy the pointer.

Evert

Do you mean

BITMAP *copy_bitmap(BITMAP *bmp)
{
   BITMAP *bmpc = NULL;
   ASSERT(bmp);
   bmpc = create_bitmap_ex(bitmap_color_depth(bmp), bmp->w, bmp->h);
   if (bmpc)
      blit(bmp, bmpc, 0, 0, 0, 0, bmp->w, bmp->h);
   return bmpc;
}

or

BITMAP *duplicate_bitmap(BITMAP *bmp)
{
   BITMAP *bmpc = NULL;
   ASSERT(bmp);
   bmpc = create_sub_bitmap(bmp, 0, 0, bmp->w, bmp->h);
   return bmpc;
}

?

Either way, this is fairly trivial to write yourself and I don't think it has to be in Allegro.

Neil Walker

Just remember not to use system or video bitmaps with the duplicate function otherwise it won't work ;)

btw, why isn't there a load_bmp set of functions to go directly to system or video bitmaps? I find I have to load up the bitmap into a temporary variable, create a new video/system bitmap, copy over the bitmap then destroy the original loaded one.

CGamesPlay

No, he means creating a sub bitmap which shares the same parent bitmap as another sub bitmap and has the same clipping area, without knowledge of the parent.

Evert
Quote:

No, he means creating a sub bitmap which shares the same parent bitmap as another sub bitmap and has the same clipping area, without knowledge of the parent.

I know, but my second example has the same effect as that, except that the parent is technically not the parent of the original subbitmap but another subbitmap. The behavior is the same though for practical purposes.

What I might consider missing from the API is a way to get the parent BITMAP * of a child, but I'm not sure that it's something you would generally need to know or should care about.

CGamesPlay

Wait, your secon example will work even after bmp has been deleted?

Elias
The current documentation said:

Returns a pointer to the created sub bitmap, or NULL if the sub bitmap could not be created. Remember to free the sub bitmap before freeing the parent bitmap to avoid memory leaks and potential crashes accessing memory which has been freed.

So, with the current docs, I'd say it is a mistake deleting the parent of a sub-bitmap (even if the parent is a sub-bitmap). Of course, a simple addition to the docs might be enough to allow it :)

Evert

Actually, I'm confused now...

Quote:

Thus my suggestion to add one of those functions to get a sub-bitmap duplicate in case you can't just copy the pointer.

When would that be the case?

Peter Wang
Quote:

When would that be the case?

The sub-bitmap could theoretically (I think in practice never) be created by the gfx or system drivers, and who knows what they could get up to.

But why do you need to duplicate sub-bitmaps?

Neil Walker

Sorry to digress, but talking of sub-bitmaps, have you had time to digest my results from recoding the sub-bitmap clipping: http://www.allegro.cc/forums/thread/558528

ADmiral
Evert said:

I know, but my second example has the same effect as that, except that the parent is technically not the parent of the original subbitmap but another subbitmap. The behavior is the same though for practical purposes.

I didn't know that it would cause the same behaviour, else I wouldn't have spent several days searching for a way to copy my sub-bitmaps. I could not simply copy the pointer because I was using wrapper classes for the bitmap types. In the copy-constructor of my sub-bitmap class, I used to just copy the pointer until the first sub-bitmap got destroyed before I used the second one. And there was no mention in the documentation of any way to obtain a sub-bitmap except the create_sub_bitmap() function.

Meanwhile, the problem is gone. I fixed the copy-constructor to do what you did in your second example.

Also, in my opinion it is not right to assume this to work because obviously create_sub_bitmap() wasn't necessarily intended to produce such behaviour. Should the implementation of the function ever change, it might stop working. Thus, it is a hack. If there was a function dedicated to copying sub-bitmaps, I would know that it was always guaranteed to work; and anyone else who might one day encounter this problem wouldn't need to ask for the hack or use even uglier workarounds.

Elias

You could simply save the offsets in your wrapper, and then create a new sub bitmap with the same offsets, instead of copying.

CGamesPlay

Is the following code be guaranteed to work?

BITMAP *duplicate_bitmap(BITMAP *bmp)
{
   BITMAP *bmpc = NULL;
   ASSERT(bmp);
   bmpc = create_sub_bitmap(bmp, 0, 0, bmp->w, bmp->h);
   return bmpc;
}

BITMAP* parent, *child1, *child2;
parent = create_bitmap(100, 100);
child1 = create_sub_bitmap(parent, 0, 0, 100, 100);
child2 = create_sub_bitmap(child1, 0, 0, child1->w, child1->h);
destroy_bitmap(child1);
blit(child2, screen, 0, 0, 0, 0, child2->w, child2->h);
destroy_bitmap(child2);
destroy_bitmap(parent);

If it isn't, his problem still stands.

Elias

This is not guaranteed to work, but in practice, works with the current implementation (but the docs currently also allow the view of "chained" sub bitmaps). The solution I meant above would be if you replace that line:

child2 = create_sub_bitmap(child1, 0, 0, child1->w, child1->h);

in your code with

child2 = create_sub_bitmap(parent, 0, 0, 100, 100);

It means, you need to store the parameters, but it's non-hackish.

CGamesPlay

Yes, but the original problem was that parent was not available, so he had to actually duplicate a sub-bitmap.

ADmiral

I would have to rewrite most of the wrapper class. Also, I think it was more of a psychological problem than a design-related one, because it didn't feel right to me to write a wrapper class for a sub-bitmap and then don't use a sub-bitmap for the representation :D Also, since every Tile has a SubBitmap and uses it to draw to the screen (or whatever back buffer is passed for a parameter), it has to be kind of fast and small. Would it be faster and smaller to store a sub-bitmap, or to store a BITMAP* and four ints? Maybe smaller, but certainly not faster if I have to recreate the sub-bitmap every time I need to use it.
Furthermore, this is only one situation where a function for copying sub-bitmaps would be useful. I don't have another example at the moment, but I'm sure there are more. What if one day I update my huge project to use Allegro 4.3 and suddenly it doesn't work anymore?! It could take months to find out about create_sub_bitmap() being the reason.

Evert
Quote:

I didn't know that it would cause the same behaviour, else I wouldn't have spent several days searching for a way to copy my sub-bitmaps.

Well, think about it: the original subbitmap refers to an area of the parent bitmap (they share the same drawing surface). So any bitmap that shares a drawing surface with the subbitmap shares a drawing surface with the parent bitmap.
Hence, the behavior is the same.

Quote:

Furthermore, this is only one situation where a function for copying sub-bitmaps would be useful.

Maube I'm dense, but I still don't understand what it is exactly that you're trying to do and why you cannot keep the old subbitmap around.
Could you explain again why this is so useful?
Personally, I think the ability to copy bitmaps in general is more useful and would make more sense to have than the ability to duplicate subbitmaps per se, and that is something which is easily done through blit (and not really a missing feature).

Quote:

Maybe smaller, but certainly not faster if I have to recreate the sub-bitmap every time I need to use it.

What are you doing that makes it nescessary to recreate a sub-bitmap regularly?
Note that you can duplicate much of the functionality of sub-bitmaps by using the source offset parameters of blit() and clipping rectangles. Doesn't mean that subbitmaps aren't useful (they certainly are), just that maybe what you're doing could be better done in another way.

Thread #559065. Printed from Allegro.cc