Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Bitmap vector problem

This thread is locked; no one can reply to it. rss feed Print
Bitmap vector problem
Jimage
Member #4,205
January 2004

I'm having some trouble with a vector<BITMAP *>. It's purpose is to hold an array of tiles, hacked up from a larger tile bitmap. As the loop progresses, it blits the correct tile to the screen, but as soon as that's over, any reference to specific entries returns only the last tile read.

A test loop using an iterator, couting each address, returned only one address, so either only one BITMAP * entry is being created, or this program doesn't access the vector properly.

level.cpp (partial):

1#include "level.h"
2 
3// defined in main.cpp
4extern vector<BITMAP *> tileset;
5extern LEVELSTRUCT level;
6 
7int load_tileset(int episode)
8{
9 BITMAP *tilebitmap;
10 BITMAP *tmptile = create_bitmap(16, 16);
11 
12 string filename = int_str(episode) + "til0000.bmp";
13
14 if (!(tilebitmap = load_bitmap(filename.c_str(), NULL)))
15 {
16 cout << "Couldn't load " << filename << endl;
17 return 1;
18 }
19 
20 int tw = tilebitmap->w / 16;
21 int th = tilebitmap->h / 16;
22 
23 tileset.clear();
24 
25 int x = 0, y = 0;
26 
27 for (y = 0; y < th; ++y)
28 for (x = 0; x < tw; ++x)
29 {
30 blit(tilebitmap, tmptile, x * 16, y * 16, 0, 0, 16, 16);
31 tileset.push_back(tmptile);
32 draw_sprite(screen, tileset[x + y * tw], x * 16, y * 16);
33 }
34 
35 destroy_bitmap(tilebitmap);
36 
37 int i;
38 
39 for (i = 0; i < tileset.size(); ++i)
40 {
41 draw_sprite(screen, tileset<i>, (i % 13) * 16, (i / 13) * 16);
42 }
43 
44 return 0;
45}

Kibiz0r
Member #6,203
September 2005
avatar

tileset.push_back() is adding a pointer to the vector. Since you never change the value of tmptile, it's always the same pointer. You just overwrite what it points to a ton of times.

Jimage
Member #4,205
January 2004

Thanks. That makes sense. So how do I copy the content of tmptile instead of just a pointer?

Kitty Cat
Member #2,815
October 2002
avatar

Create a tmptile each time just before you blit to it and push_back to the vector. It might be better to use create_sub_bitmap though, so you don't have to deal with having the image spread out all over memory.

Just don't forget to call destroy_bitmap on the pointers in the vector before clearing it!

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Kibiz0r
Member #6,203
September 2005
avatar

If you wanted to have them destroyed automagically, you could wrap them in another class whose destructor calls destroy_bitmap() and use std::auto_ptr instead of a regular pointer.

It's a bit of extra work, but at least you can be sure you're not leaking memory. An ounce of prevention...

Jimage
Member #4,205
January 2004

Ah, marvelous. It works great again.

Kitty Cat said:

It might be better to use

create_sub_bitmap

though, so you don't have to deal with having the image spread out all over memory.

Sounds useful. I'll read into it.

Kibiz0r said:

you could wrap them in another class whose destructor calls destroy_bitmap() and use std::auto_ptr

Good thing you mentioned that or I'd have overlooked freeing the pointers. However, I'm not dealing with classes yet. Though I'm using certain C++ features, everything's still coded procedurally. Is there a tutorial or example around that might shed some more light on the subject anyway?

A WIP screenshot is attached if anyone's interested.

Kibiz0r
Member #6,203
September 2005
avatar

Get a C++ primer book, then get used to C++ for a while, then get Effective C++.

Classes are the win. ;)

I would recommend a specific C++ primer book, but I really don't know. I read one C++ book and it was terrible. I mostly learned by absorbing code from these forums, documentation... anywhere there was semi-reliable C++ code. Looking back it was a dumb way to go about it, but it worked. :P

Also, screenshot looks nice!

Oh, and you will also need a C++ design patterns book.

Go to: