Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » A5 - Can someone figure out why this isn't working?

This thread is locked; no one can reply to it. rss feed Print
A5 - Can someone figure out why this isn't working?
Desmond Taylor
Member #11,943
May 2010
avatar

I have started to re-code Jump Pacman because the code got very very messy but now I can't even load an image without it crashing.

I have attached the entire project without the lib and include directory. (Setup using static libs Allegro 5.0.3)

Anyone have a clue to why this is happening.

This is where it seems to break.

#SelectExpand
1#include "menu.h" 2 3Menu::Menu() 4{ 5 printf( "Menu Started!\n" ); 6 7 game->gfx->Load( "gfx/menu_bg.png" ); // Crashes with this line. 8} 9 10Menu::~Menu() 11{ 12 printf( "Menu Stopped!\n" ); 13} 14 15void Menu::Render() 16{ 17 18}

Hope someone can shed some light on this matter.

Neil Walker
Member #210
April 2000
avatar

The usual response is that relative path may not necessarily be where you think it is, i.e. to the executable. Are you checking for file not exists or if the bitmap creation failed?

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Desmond Taylor
Member #11,943
May 2010
avatar

I am to the archive and it loads that. I know for a fact that the image is in the correct place too. It just seems to crash when calling that function and I've written the function that way many times before without error.

This is what the Load function does.

#SelectExpand
1int Graphics::Load( const char* filename ) 2{ 3 ALLEGRO_BITMAP* tmpBitmap = al_load_bitmap( filename ); 4 if ( tmpBitmap ) 5 { 6 this->bitmap.push_back( tmpBitmap ); 7 return this->bitmap.size() - 1; 8 } 9 10 return -1; 11}

Kris Asick
Member #1,424
July 2001

When I started using A5 recently I found I had difficulty loading stuff as well. Then I learned that A5 has a path-handling system using ALLEGRO_PATH objects. That seemed to solve my problems.

You first create an ALLEGRO_PATH object, then use al_get_standard_path() to get the full path of where your executable is, then you can use al_append_path_component() to go deeper into a directory structure and al_set_path_filename() to set the filename.

Then, to load a file, use al_path_cstr() to convert the contents of an ALLEGRO_PATH object into a string.

Even if this seems overly complicated, it would be good to learn because you can use al_get_standard_path() to get other path locations suitable for storing global data, accessible by all users, or current-user-specific data.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

torhu
Member #2,727
September 2002
avatar

Did you actually create the game, gfx, and bitmap objects?

And there's no shame in using a debugger ;)

Desmond Taylor
Member #11,943
May 2010
avatar

@Kris Asick,

I know that the path is correct :/ I took all of this from my one script version and re-coding it so that I know what's going on since I got lost in the original one.

torhu said:

Did you actually create the game, gfx, and bitmap objects?

Yes, Convert the *.dat file to a *.zip file and extract it. You'll notice the images are in there. You can also use 7z to open it as it is.

Quote:

And there's no shame in using a debugger

I would but I really have no clue on how to use it :/

Edit: I get this when I press F8.

#SelectExpand
1#0 004B91C2 std::auto_ptr<Graphics>::operator->(this=0x0) (c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/c++/backward/auto_ptr.h:195) 2#1 0040165E Menu::Menu(this=0x8d8d858) (E:\Projects\Jump Pacman\src\menu.cpp:7) 3#2 004018B2 Game::Game(this=0xa53a20) (E:\Projects\Jump Pacman\src\game.cpp:38) 4#3 004015CC main(argc=1, argv=0xa527d0) (E:\Projects\Jump Pacman\src\main.c:5)

torhu
Member #2,727
September 2002
avatar

I was thinking about the objects in the code, not the data files.

Desmond Taylor
Member #11,943
May 2010
avatar

I don't get what you mean but I have been sat here trying to work some stuff out and I might have the auto_ptr's setup wrong.

game.h

#SelectExpand
1#ifndef __GAME_H_INCLUDED 2#define __GAME_H_INCLUDED 3 4#include "stdafx.h" 5 6class Game 7{ 8 public: 9 Game(); 10 ~Game(); 11 12 void Run(); 13 void UpdateEventSystem(); 14 void Quit() { this->quit = true; }; 15 void Clear( int r = 0, int g = 0, int b = 0 ); 16 void Flip(); 17 18 void Error( const char* format, ... ); 19
20 std::auto_ptr<Graphics> gfx;
21 std::auto_ptr<Menu> menu;
22 23 protected: 24 ALLEGRO_DISPLAY* display; 25 ALLEGRO_TIMER* timer; 26 ALLEGRO_EVENT_QUEUE* queue; 27 ALLEGRO_EVENT event; 28 GAME_STATE state; 29 bool quit; 30 bool ticked; 31}; 32 33extern std::auto_ptr<Game> game; 34 35#endif // __GAME_H_INCLUDED

game.cpp

#SelectExpand
1Game::Game() 2{ 3 printf( "Game Started!\n" ); 4 5 if ( !al_init() ) 6 this->Error( "Error initializing Allegro." ); 7 8 this->display = al_create_display( 640, 480 ); 9 if ( !this->display ) 10 this->Error( "Error creating the display." ); 11 12 al_set_window_title( this->display, "Jump Pacman" ); 13 14 this->timer = al_create_timer( ALLEGRO_BPS_TO_SECS( 60 ) ); 15 if ( !this->timer ) 16 this->Error( "Error creating timer." ); 17 18 this->queue = al_create_event_queue(); 19 if ( !this->queue ) 20 this->Error( "Error creating event queue." ); 21 22 al_register_event_source( this->queue, al_get_display_event_source( this->display ) ); 23 al_register_event_source( this->queue, al_get_timer_event_source( this->timer ) ); 24 25 al_set_physfs_file_interface(); 26 27 if ( !PHYSFS_init( NULL ) ) 28 this->Error( "Error with PHYSFS_init()." ); 29 30 if ( !PHYSFS_addToSearchPath( "data.dat", 0 ) ) 31 this->Error( "Error with PHYSFS_addToSearchPath()." ); 32
33 this->gfx = std::auto_ptr<Graphics>( new Graphics );
34 this->menu = std::auto_ptr<Menu>( new Menu );
35 36 al_start_timer( this->timer ); 37 38 this->state = GAME_STATE_MENU; 39 this->quit = false; 40 this->ticked = true; 41}

That's where it is declared and then initialized.

Kris Asick
Member #1,424
July 2001

Oh... you're using PHYSFS... That would've been helpful to know ahead of time. :P

I took a look at your entire codebase... I know this sounds trivial, but try changing your vector definition in graphics.h to this:

std::vector<(ALLEGRO_BITMAP*)> bitmap;

Dunno if this will help but I seem to recall having issues using pointers and vectors in the past.

Beyond that, it would help to know exactly which line of Graphics::Load() is crashing the program, whether it's the actual Allegro load itself or your vector handling commands afterwards.

EDIT: Oh, and I've never used auto_ptr objects so if that's where the problem is then I wouldn't've had a clue. ::)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Desmond Taylor
Member #11,943
May 2010
avatar

I just tried that and still the same error. :/

Edit: I was given information on how to use auto_ptr within a class before and can be read on these forums [1]. However, I have done it correctly according to that :/

I'm going to check this by not using auto_ptr and just allocate it myself to see if it gets rid of the error.

Kris Asick
Member #1,424
July 2001

Though... why are you using auto_ptr objects? Just to get around cleanup code? Couldn't you just use "new" and "delete" commands as usual?

gfx = new Graphics;

and in Game::~Game():

delete gfx;

I dunno, that just seems simpler to me, and then it would be far more obvious when and where these objects would be created and destroyed.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Desmond Taylor
Member #11,943
May 2010
avatar

Funny enough, I just edited my last post saying that I am going to see if that fixes my problem.

EDIT: No that didn't fix the error meaning I defiantly set that up correctly. I am now out of ideas on what it causing this.

Evert
Member #794
November 2000
avatar

Are you absolutely sure that Allegro is initialised before you try to call any Allegro functions? There are no global variables anywhere with constructors that that call Allegro functions?

Desmond Taylor
Member #11,943
May 2010
avatar

Evert said:

Are you absolutely sure that Allegro is initialised before you try to call any Allegro functions? There are no global variables anywhere with constructors that that call Allegro functions?

Taken from game.cpp

#SelectExpand
1#include "game.h" 2 3std::auto_ptr<Game> game; 4 5Game::Game() 6{ 7 printf( "Game Started!\n" ); 8
9 if ( !al_init() )
10 this->Error( "Error initializing Allegro." ); 11 12 this->display = al_create_display( 640, 480 ); 13 if ( !this->display ) 14 this->Error( "Error creating the display." );

This is the first class that is initialized and that initializes Allegro so there is no chance of that happening :/ If I comment out the contents of Graphics::Load() so it only returns -1 then it still gives the error. I don't think it is to do with allegro :/

Graphics is initialized after Game but before Menu so it's defiantly all initialized first.

I will edit this with an attachment to an executable.

Edit: Added the attachment.

Kris Asick
Member #1,424
July 2001

I think I know what the problem is, and the fact it's letting you compile and link with this going on is... weird.

Basically, your "game" object should NOT be accessible from menu.cpp.

Try this:

1. Remove the following line from menu.cpp:
game->gfx->Load("gfx/menu_bg.png");

2. Add the following line after creating your new gfx object in game.cpp:
this->gfx->Load("gfx/menu_bg.png");

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Desmond Taylor
Member #11,943
May 2010
avatar

But I wan't it to load from menu.cpp like when I get to player I wan't player.cpp to load the player images.

Neil Walker
Member #210
April 2000
avatar

Can you single step through and into your code and see what might be happening, e.g. the objects are null as mentioned, etc.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Kris Asick
Member #1,424
July 2001

If you want to load your graphics from your menu routine, then your menu routine needs to be made completely aware of your graphics object.

Try this:

game.cpp

this->gfx = std::auto_ptr<Graphics>( new Graphics );
this->menu = std::auto_ptr<Menu>( new Menu );
this->menu->loadgfx(this->gfx);

menu.cpp

#include "menu.h"
#include "graphics.h"

Menu::Menu()
{
  printf( "Menu Started!\n" );
}

int Menu::loadgfx (Graphics *gfx)
{
  return gfx->Load( "gfx/menu_bg.png" );
}

I'm in a rush now and don't have you code in front of me anymore, but I think you can get the idea. Menu doesn't have direct access to your game object which explains why the pointer value is 0x0 when inside your menu routine.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Desmond Taylor
Member #11,943
May 2010
avatar

I could just do that and pass the gfx pointer into
this->menu = std::auto_ptr<Menu>( new Menu( this->gfx ) );

or
this->menu = std::auto_ptr<Menu>( new Menu( this ) ); because I need to get input when I set that class up too xD

Edit: I don't know how to step though the code as I don't know how to use the debugger.

Edit 2: I am going with passing a pointer to the class constructor and storing a pointer to it.

Edgar Reynaldo
Member #8,592
May 2007
avatar

I think you forgot to call al_init_image_addon before you tried to load your graphics. I don't see it in your Game constructor anywhere. Nevermind, I see it in your Graphics constructor now...

#0 004B91C2  std::auto_ptr<Graphics>::operator->(this=0x0) (c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/c++/backward/auto_ptr.h:195)
#1 0040165E  Menu::Menu(this=0x8d8d858) (E:\Projects\Jump Pacman\src\menu.cpp:7)
#2 004018B2  Game::Game(this=0xa53a20) (E:\Projects\Jump Pacman\src\game.cpp:38)
#3 004015CC  main(argc=1, argv=0xa527d0) (E:\Projects\Jump Pacman\src\main.c:5)

See the part in frame #0 where it says 'this = 0x0'. You're trying to dereference a null pointer somehow. I don't know how the address of the auto_ptr got to be null though.

I see what you did.

src\game.h line 33 :

extern std::auto_ptr<Game> game;

src\game.cpp line 3 :

std::auto_ptr<Game> game;

src\main.c line 5 :

    std::auto_ptr<Game> game( new Game );

If you had turned on all of your compiler warnings, you would have noticed this :
src\main.c:5:29: warning: declaration of 'game' shadows a global declaration
(With gcc/MinGW use -Wall and -Wshadow)

So the reason the Menu constructor is crashing is because it uses the global 'game' variable, which has been initialized by the default auto_ptr constructor, which is unable to guess where your object is located, which is why it was trying to dereference a null pointer.

Desmond Taylor
Member #11,943
May 2010
avatar

;D, Stupid me. I shall turn on all compiler warnings now. I have a banging headache at the moment so when the paracetamol kicks in I shall work on it.

Thanks

Neil Walker
Member #210
April 2000
avatar

If you don't know how to use the debugger, I suggest you do it now before you go any further down your programming path.

You mentioned pressing F8, are you using Visual Studio Express 2005?

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Desmond Taylor
Member #11,943
May 2010
avatar

Neil Walker
Member #210
April 2000
avatar

I've never used code blocks but given it's just a front end to mingw you enable the debugging symbols and hopefully c::b includes the debuger.

A quick google says go to the compiler options and tick the box 'produce debugging symbols', then everything else is done via the debug menu like start/stop/jump over/jump in (probably keypresses if you look closely enough in the menu).

That'll get you started in your code (allegro will still be out of bounds as far as drilling down, but most of the time you don't need to anyway). Couldn't be simpler :)

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Desmond Taylor
Member #11,943
May 2010
avatar

Thanks Neil :)

Sorry I didn't reply back so fast I was busy with animating the menu. It looks more like The Simpson's now.

{"name":"604415","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/9\/69fb4283685592832ffb2b55f6c0fa22.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/9\/69fb4283685592832ffb2b55f6c0fa22"}604415

Go to: