Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Problems with BITMAP*s

This thread is locked; no one can reply to it. rss feed Print
Problems with BITMAP*s
Miles Lombardi
Member #5,876
May 2005

My code uses a class that I made called SPRITE. Now SPRITE contains an array of BITMAP*s, the problem is that the first time I come to try and blit one of those BITMAP*s the whole programme crashes.
Now it didn't used to do this, so I don't know why it is doing it now.

This is the header and constructor for the SPRITE class:

1class SPRITE {
2 public:
3 int offset_x; //Draw offset x
4 int offset_y; //Draw offset y
5 int max_frames; //Frames in sprite (array bounds 0 - max_frames)
6 int width; //Sprite width (all frames)
7 int height; //Sprite height (all frames)
8 int id; //Individual sprite ID
9 bool operator == (SPRITE &class1); //Comparison (checks IDs)
10 BITMAP * spr_sheet(); //Returns a BITMAP of the entire sprite sheet, horizontally.
11 BITMAP ** frames; //The pointer to the array of BITMAP*s, the main point of this
12 SPRITE(BITMAP * load_sprite, int load_width, int load_height, int frame_num, int load_offset_x = 0, int load_offset_y = 0, int offset_x = 0, int offset_y = 0, bool debug_me = 0); //The constructor, self explanitory
13 SPRITE(); //Empty Constructor
14 ~SPRITE(); //Destructor
15 void draw(int x, int y, int frame, int alpha = 255, bool debug_me = 0); //Normal draw function
16
17};

1SPRITE::SPRITE(BITMAP* load_sprite, int load_width, int load_height, int frame_num, int load_offset_x, int load_offset_y, int draw_offset_x, int draw_offset_y, bool debug_me ) {
2 if (load_sprite != NULL){
3 id = spr::get_safe_id();
4
5 frames = new BITMAP* [frame_num];
6 width = (int)(std::abs((float)(load_width)));
7 height = load_height;
8 max_frames = frame_num;
9 offset_x = draw_offset_x;
10 offset_y = draw_offset_y;
11 for (int a = 0; a < frame_num; a++){
12 frames[a] = create_bitmap(width, height);
13 blit(load_sprite, frames[a], load_offset_x + a*width, load_offset_y, 0, 0, width, height);
14 }
15 destroy_bitmap(load_sprite);
16 }
17 else allegro_message("Error loading a certain sprite");
18}

This is the init() function, which is the first one called within main():

1 
2void init() {
3 int depth, res;
4 allegro_init();
5 depth = desktop_color_depth();
6 if (depth == 0) depth = 32;
7 set_color_depth(depth);
8 res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 480, 320, 0, 0);
9 if (res != 0) {
10 allegro_message(allegro_error);
11 exit(-1);
12 }
13 
14 install_timer();
15 install_keyboard();
16 install_mouse();
17 load_bitmaps();
18 install_sound( DIGI_AUTODETECT, MIDI_AUTODETECT, NULL);
19 load_sounds();
20 /* add other initializations here */
21 set_close_button_callback(End);
22
23 link = OBJ_LINK(); //Construct link
24 helmaroc = OBJ_HELMAROC(); //Construct the helmaroc
25 heart_system = OBJ_HEARTS(8, 8); //Construct the heart system
26 SoundMeter = soundMeter(); //Construct the sound meter
27 rupees = rupeeSystem(8, 142); //construct the rupee system
28 rmtower = clROOM(tower); //create the tower room
29}

Now I cannot see any way that a BITMAP* could go astray and create a pointer error, unless it happens in one of those constructors (which I don't think it does, but if you want to see them you can).
The problem comes later when this code is run:

   link.spr_link_right_walk.draw(105 + 0, 40, 0, 255, 1);

This calls the draw function in the SPRITE class, which simply draws a translucent copy of that frame.

I don't know what could be going wrong, so could someone please help me? I've been stuck on this bug for a while, and it completely stops the programme :(.

GullRaDriel
Member #3,861
September 2003
avatar

i hear somewhere the story of the Fucking Manual and the Evil 'I contain bitmap and contruct them before allegro is loaded' Class.

Maybe you should search more on my story.

I'm sorry but i use C, so i do not have the problem you got.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

ReyBrujo
Moderator
January 2001
avatar

Are you compiling with gcc? Try to debug that, it should give you the answer.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Miles Lombardi
Member #5,876
May 2005

Gull, although that is most likely to be the problem all of the constructors are called after allegro_init(), only the declarations of the classes are called before allegro_init(), and that does not involve any creation of BITMAPs, i think.

A J
Member #3,025
December 2002
avatar

if your program crashes, and you dont know how to find the bug, you need to learn how to use a debugger.

___________________________
The more you talk, the more AJ is right. - ML

Miles Lombardi
Member #5,876
May 2005

Yes I do, Dev-C++s tells me where it goes wrong, but I don't know how to do anything else.

Evert
Member #794
November 2000
avatar

Quote:

all of the constructors are called after allegro_init()

It is my understanding that constructors are called when the variable is declared. Your variables look to be declared before allegro_init(). But even if you do declare them below allegro_init(), I'm not sure if it is guarenteed that the constructors are called after it (it might be though).

As a rule of thumb, don't call Allegro functions from inside a constructor function. There are cases where you can do this, but when in doubt, don't do it.

Miles Lombardi
Member #5,876
May 2005

Well there are actually two constructors for all of those things, and when they are declared globally, and pre allegro_init() it doesn't run any allegro functions because it's just a blank constructor.

ReyBrujo
Moderator
January 2001
avatar

What does Draw do? Are you sure you are not running out of memory when allocating bitmaps? Can you attach the code? Or debug it to see inside the Draw function to see exactly in which line it crashes, and not only the function.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Miles Lombardi
Member #5,876
May 2005

I know exactly where it crashes, on the draw_trans_sprite.
And how can you run out of memory? :S
The computer doesn't crash, just the programme.

ReyBrujo
Moderator
January 2001
avatar

But can you examine if the pointer is NULL, if the trans table is broken in some way, etc?

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Miles Lombardi
Member #5,876
May 2005

...
It is NULL, which is weird.
Why is it weird? Cause it's not NULL in the constructor.
How did this happen?

(top of main.cpp if you need it)

1#include <allegro.h>
2#include "vardec.h"
3#include "timeline.h"
4#include "link.h"
5#include "helmaroc.h"
6#include "systems.h"
7#include "keypress.h"
8 
9 
10void init();
11void deinit();
12void Buffer2Screen();
13void load_sounds();
14void unload_sounds();
15void load_bitmaps();
16void unload_bitmaps();
17void allrooms();
18void room_change(int newroom);
19OBJ_LINK link;
20OBJ_HEARTS heart_system;
21OBJ_HELMAROC helmaroc;
22soundMeter SoundMeter;
23rupeeSystem rupees;
24 
25clROOM rmtower;
26 
27BITMAP *press_start, *title_screen, *sbuffer, *tower, *rock, *door_way;
28SAMPLE *sndLinkHurt, *sndswordSwipe;
29MIDI * tower_music;
30bool run = 1, B2S = 1;
31int stepcounter = 4, room = ROOM_TITLE, view_x = 0, view_y;
32 
33int main(){
34 init();

Edit:
Whoops, I just found that my OBJ_LINK doesn't have a blank constructor.
And now that it does, it doesn't make any difference.
It looks like this:

OBJ_LINK::OBJ_LINK(){
vary = varx = direction = mode = frame = speed = key_length_up = key_length_down = key_length_right = alarm[0] = attacked = 0;
}

As opposed to:

1OBJ_LINK::OBJ_LINK(int x, int y):
2spr_link_up_walk(load_bitmap("link_dir_up.bmp", NULL), 18, 28, 10, 18, 0),
3spr_link_down_walk(load_bitmap("link_dir_down.bmp", NULL), 18, 28, 11, 18, 0),
4spr_link_left_walk(load_bitmap("link_dir_left.bmp", NULL), 22, 27, 10, 19, 0),
5spr_link_right_walk(load_bitmap("link_dir_right.bmp", NULL), 22, 27, 10, 19, 0),
6spr_link_up_stand(load_bitmap("link_dir_up.bmp", NULL), 18, 28, 1, 0, 0),
7spr_link_down_stand(load_bitmap("link_dir_down.bmp", NULL), 18, 28, 1, 0, 0),
8spr_link_left_stand(load_bitmap("link_dir_left.bmp", NULL), 19, 27, 1, 0, 0),
9spr_link_right_stand(load_bitmap("link_dir_right.bmp", NULL), 19, 27, 1, 0, 0),
10spr_link_up_sword(load_bitmap("link_dir_up.bmp", NULL), 37, 31, 6, 0, 28, 13, 2),
11spr_link_down_sword(load_bitmap("link_dir_down.bmp", NULL), 41, 40, 6, 0, 28, 9, 0),
12spr_link_left_sword(load_bitmap("link_dir_left.bmp", NULL), 33, 42, 7, 0, 27, 15, 3),
13spr_link_right_sword(load_bitmap("link_dir_right.bmp", NULL), 33, 42, 7, 0, 27, -1, 2),
14sprite_index(0)
15{
16
17varx = x;
18vary = y;
19direction = LINK_DIR_DOWN;
20mode = MODE_STAND;
21 
22frame = 0;
23speed = 4;
24key_length_up = 0;
25key_length_down = 0;
26key_length_left = 0;
27key_length_right = 0;
28alarm[0] = -1;
29attacked = 0;
30}

Is it still running the sprite constructors?

Go to: