load_bitmap trouble
Raf Vermeulen

I started a new project today, prototyping an addition to a game engine I already have. I pretty much took over all initialization code and the basic objects from the existing code (which works fine), but stripped the unnecessary parts out (like animation code, as I don't plan on animations on the prototype for now)

The dumb thing is, that it doesn't want to load the tileset...
All source code's in the attached zipfile, along with the tileset. The problem lays in either

Tile::Tile() : /* deze methode is sneller dan wanneer ze in de constructor staan */
size(32),
type(0) {
  if(!m_tile) load_tileset("Gfx/Tile.bmp"); 
  if (!m_tile) cout << "Spritesheet not loaded\n";     
}

(file classes.cpp)
or in

void Tile::load_tileset(const char *tileset) {
  Tile::m_tile = load_bitmap(tileset, NULL);
}

as the output always gives: "Spritesheet not loaded".

m_tile is a static, protected bitmap in Tile, btw.

piccolo

i think you posted the wrong version of the code. in this version there are a lot of return errors and it wont compile.

Raf Vermeulen

I only got one version. What're the errors it gives there? Might have something to do with the problem.

The IDE I use, is Dev-C++ v.4.9.9.2, with the standard compiler coming with it and with the Allegro linker parameter.

piccolo
1#1
2//what you have
3int initiaze() {
4 allegro_init();
5 install_keyboard();
6 install_timer();
7
8 LOCK_VARIABLE(counter);
9 LOCK_FUNCTION(timer_handler);
10 install_int_ex(timer_handler,BPS_TO_TIMER(15)); /* Draai op 15 hz */
11 
12 /* Install handler when user presses X at the topright corner */
13 LOCK_VARIABLE(exit_application);
14 LOCK_FUNCTION(exit_button);
15 set_close_button_callback(exit_button);
16 
17 set_color_depth(16);
18 if(set_gfx_mode( GFX_AUTODETECT_WINDOWED, SCR_WIDTH, SCR_HEIGHT, 0, 0)) exit(1);
19 buffer = create_bitmap(WIDTH*32, HEIGHT*32);
20 Tile::load_tileset("Gfx/Tile.bmp");
21}
22
23#2
24 
25virtual int get_index() {};
26 
27 
28 
29 
30 
31//what i put
32#1
33int initiaze() {
34 allegro_init();
35 install_keyboard();
36 install_timer();
37
38 LOCK_VARIABLE(counter);
39 LOCK_FUNCTION(timer_handler);
40 install_int_ex(timer_handler,BPS_TO_TIMER(15)); /* Draai op 15 hz */
41 
42 /* Install handler when user presses X at the topright corner */
43 LOCK_VARIABLE(exit_application);
44 LOCK_FUNCTION(exit_button);
45// set_close_button_callback(exit_button);
46 
47 set_color_depth(16);
48 if(set_gfx_mode( GFX_AUTODETECT_WINDOWED, SCR_WIDTH, SCR_HEIGHT, 0, 0)) exit(1);
49 buffer = create_bitmap(WIDTH*32, HEIGHT*32);
50 Tile::load_tileset("Gfx/Tile.bmp");
51 return 0;
52}
53 
54#2
55virtual int get_index() {return 0};

there are more tell me when you get the code to the state where you said you had the problem then ill down load the code.
you can change file by editing your attachments

Raf Vermeulen

Got some trouble with placing the virtual int get_index() part. It keeps saying "virtual outside class declaration"

piccolo

i c so you did not have a problem with any loading of any map:-X ill take a look at the current code then.

Raf Vermeulen

The problem's with loading the spritesheet;) If I reinstate the draw-function, the program crashes as it doesn't load the bitmap.

piccolo

well i tried i wont be able to do it to night there is just to many things to change and fix.

take a look at this site this is where I and a lot of other people learned about tile maps.

http://agdn.netfirms.com/main/
http://agdn.netfirms.com/main/html/tut_1.htm
http://agdn.netfirms.com/main/html/tut_2.htm
http://agdn.netfirms.com/main/html/tut_3.htm

word of advice compile more so your error don't build up like they have.

this site has a 7 lesson plan that you should follow about making tile maps and editors.

Raf Vermeulen

Ok, thanks. I'll read up on it.

piccolo

feel free to message me about any one of the tutorials be cause i have completed them all.;D

Raf Vermeulen

Hmmm, I went through all the tutorials, but they didn't tell me how to fix the spritesheet loading. It was an interesting read, though.

piccolo

they use sprite sheets in those tutorials.

Raf Vermeulen

Yeah, but so do I in my other code, and it all works, both in that other code and in that tutorial, but I do the same thing in this code, but it doesn't work here =S

piccolo

in your code you have a lot of basic errors stacked on top of each other.

Raf Vermeulen

Hmmm... same thing for the other code (the one from that thread from yesterday), or'm I missing something? That one worked. This one compiles (here, at least), but doesn't work in runtime, so there must be a difference somewhere which I can't spot.

What errors's it give there when compiling?

piccolo

in your code you have a lot of basic errors stacked on top of each other.

Raf Vermeulen

How'm I supposed to fix these errors if my compiler doesn't give any and if you don't tell me what they are when you notice them????

CGamesPlay

How do you run the program? Most likely the problem is that you are in a different directory that you think you are.

Raf Vermeulen

I've tried running it from Dev-C++ right after compiling, from inside the directory, and from inside the other code's directory (which uses the same subfolder and spritesheet's filename), and it all does the same.

CGamesPlay

Try putting this code in the load_tileset function:

if(!file_exists(tileset))
    cerr << "Spritesheet does not exist at location " << tileset << "!" << endl;
else if((m_tile = load_bitmap(tileset, NULL)) == NULL)
    cerr << "Spritesheet exists, but failed to load!" << endl;

Raf Vermeulen

Ok, file_exists didn't quite work (didn't want to compile, and if I added 0, NULL, it gave runtime crashes), so I did it like this:

     FILE * file;
     file = fopen(tileset,"r");
     if (!file) cout << "Error with opening of file\n";
     else cout << "Could open file\n";
     fclose(file);
      
     if( (Tile::m_tile = load_bitmap(tileset, NULL)) == NULL)
         cout << "PROBLEM!\n";

The output of this is:
Could open file
PROBLEM!

So it can reach the file, but something's wrong with the load_bitmap part. Not much that can be done wrong with that, though =S

CGamesPlay

So, what are your color conversion settings? (Do you call set_color_conversion?) What is your color depth? If you compile using the debug version of Allegro, do you get an assertion failure?

Raf Vermeulen

I don't know how to compile with the debug version. Color depth's set to 16. Set_color_conversion's not called. The graphical mode's set like this:

    set_color_depth(16);
    if(set_gfx_mode( GFX_AUTODETECT_WINDOWED, SCR_WIDTH, SCR_HEIGHT, 0, 0)) exit(1);
    buffer = create_bitmap(WIDTH*32, HEIGHT*32);

That's the same as in the other code, where it does load the tileset.

I also tried loading the tileset from the other code, and that gives the same problem.

Kauhiz
Quote:

I also tried loading the tileset from the other code, and that gives the same problem.

Hmm, I wonder where the problem could be, then...

CGamesPlay

You should write a simple test case to load the bitmap and blit it to the screen in as few lines as possible. Don't put the bitmap in a subdirectory or anything, just load and blit. I want to see if this is a problem with Allegro.

Raf Vermeulen

I also tried leaving it out of a subdirectory and just plain in the same directory as the executable (with putting this in the code and putting the image there, obviously). Same results.

I'll comment out everything except the most necessary and'll try to load and blit it without it being a part of a class.

The thing that still confuses me, is how it works fine for one project, but the same code doesn't work in another.

Anyways, on to the testing

CGamesPlay

The proper test case should look something like this:

1#define ALLEGRO_NO_MAGIC_MAIN
2#include <allegro.h>
3#include <iostream>
4 
5using namespace std;
6 
7int main(int argc, char* argv[])
8{
9 install_allegro(SYSTEM_NONE, &errno, atexit);
10 BITMAP* b = load_bitmap("test.bmp", NULL);
11 if(!b)
12 {
13 cout << "Bitmap failed to load" << endl;
14 return 0;
15 }
16 cout << "Bitmap loaded" << endl;
17 destroy_bitmap(b);
18 return 1;
19}

Raf Vermeulen

That one says: "Bitmap loaded"

It crashes with this one:

1int main(int argc, char* argv[])
2{
3 install_allegro(SYSTEM_NONE, &errno, atexit);
4 set_color_depth(16);
5 if(set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0)) {
6 cout << "Problem with setting gfx mode\n";
7 system("pause");
8 exit(1);
9 }
10 BITMAP* b = load_bitmap("Gfx/Tile.bmp", NULL);
11 if(!b)
12 {
13 cout << "Bitmap failed to load" << endl;
14 return 0;
15 }
16 cout << "Bitmap loaded" << endl;
17 blit(b, screen, 0,0,0,0,800,600);
18 destroy_bitmap(b);
19 system("pause");
20 return 1;
21}

Result is "Problem with setting gfx mode".

CGamesPlay

It says "Bitmap loaded" when you use the Gfx/Tile.bmp from the attachment in the first post?

[append]
If you use SYSTEM_NONE, you can't set a graphics mode, or use a keyboard, or anything like that. Change the install_allegro line to a standard allegro_init line for that :)

Raf Vermeulen

It loads and shows fine now (with the allegro_init()). The bitmap's the one from the attachment (the 10 testing floor-tiles and the crappy stickman).

I'll add the code one by one again and'll see where it goes wrong.

Tobias Dammers
Quote:

Result is "Problem with setting gfx mode".

What graphics mode is your desktop set to?

No, wait.

Why do you install the SYSTEM_NONE driver and expect it to give you any useful graphics driver?

Try this one (fixing some errors along the way):

1#include <allegro.h>
2#include <iostream> // may be required on some platforms for cout / cerr
3 
4int main(int argc, char* argv[])
5{
6 allegro_init(); // will pick the system driver for you; the preferred way of installing allegro unless you want to do platform-specific hacking
7 set_color_depth(16);
8 if(set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0)) {
9 cerr << "Problem with setting gfx mode" << endl; // error messages go into the error stream, and use endl over '\n'
10 // system("pause"); // no need for this, better exit right away
11 exit(1);
12 }
13 // it's probably a good idea to try other color depths if 16bpp fails, but I leave that as an exercise for the reader. Hint: the code is in the allegro manual.
14 install_keyboard(); // we need this for readkey() later on
15 BITMAP* b = load_bitmap("./Gfx/Tile.bmp", NULL); // makes sure the path is regarded as relative to the current directory
16 if(!b)
17 {
18 set_gfx_mode(GFX_TEXT, 80, 25, 0, 0); // set a text mode so that text output is visible
19 cerr << "Bitmap failed to load" << endl; // Error to cerr
20 return -1; // return nonzero on error
21 }
22 cout << "Bitmap loaded" << endl;
23 blit(b, screen, 0,0,0,0,800,600);
24 destroy_bitmap(b);
25 // system("pause");
26 // better:
27 readkey(); // waits for keyboard input
28 return 0; // return zero on successful termination
29}
30END_OF_MAIN() // needed by allegro's magic main()

--- EDIT ---
Beaten. Twice.

Raf Vermeulen

Ok... this's getting a bit odd. I'm at the point where it says spritesheet not loaded again. That's when I placed

  if(m_tile == 0) load_tileset("Gfx/Tile.bmp"); 
  if (!m_tile) cout << "Spritesheet not loaded\n";

in

Tile::Tile() : /* deze methode is sneller dan wanneer ze in de constructor staan */
size(32),
type(0) {
  if(m_tile == 0) load_tileset("Gfx/Tile.bmp"); 
  if (!m_tile) cout << "Spritesheet not loaded\n";     
}

This code (in the main loop, which I left in there as double-checking) still works fine:

    BITMAP* b = load_bitmap("Gfx/Tile.bmp", NULL);
    if(!b) {
        cout << "Bitmap failed to load" << endl;
        system("pause");
        return 0;
    }
    masked_blit(b, buffer, 0,0,0,0,32,32);
    cout << "Bitmap loaded" << endl;
    blit(b, screen, 0,0,0,0,800,600);

CGamesPlay

You must have a pointer error somewhere... I guess. I'm at a loss, really. Check valgrind or gdb :)

Kitty Cat

The constructor isn't called globally, is it? It's called after allegro_init and set_gfx_mode?

Raf Vermeulen

I get the spritesheet not loaded comment before any other comment, and the global variables're declared above the main-loop, like this:

1#include "crops.h"
2 
3BITMAP *buffer;
4Tile tile;
5Tile *field[HEIGHT][WIDTH];
6BITMAP *Tile::m_tile;
7int player_x;
8int player_y;
9 
10 
11int main(int argc, char* argv[]) {
12 srand(time(0));
13 initiaze();
14 set_game();
15 BITMAP* b = load_bitmap("Gfx/Tile.bmp", NULL);
16 if(!b) {
17 cout << "Bitmap failed to load" << endl;
18 system("pause");
19 return 0;
20 }
21 masked_blit(b, buffer, 0,0,0,0,32,32);
22 cout << "Bitmap loaded" << endl;
23 blit(b, screen, 0,0,0,0,800,600);
24 destroy_bitmap(b);
25 destroy_bitmap(buffer);
26 system("pause");
27 return 1;
28}
29END_OF_MAIN()

Evert

If the constructor is called before allegro_init() is called, then you're calling an Allegro function before Allegro is initialised - which doesn't work.

Raf Vermeulen

Well I'll be damned. That seems to be the difference between the first project and this one:o

Changing the global var declaration part to this did the trick:

BITMAP *buffer;
BITMAP *Tile::m_tile;
Tile *field[HEIGHT][WIDTH];
int player_x;
int player_y;

It still doesn't draw properly, but I'll check all the rest too to make sure things're going as they should.

WOO! Fixed a few more flaws and it works like a charm now;D Time to do the actual stuff now... the fun part;D

Thread #590176. Printed from Allegro.cc