sdl not working?

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
bocochoco
Posts: 317
Joined: Thu Aug 06, 2009 8:22 pm UTC

sdl not working?

Postby bocochoco » Wed Oct 13, 2010 8:22 pm UTC

So I'm trying to get it working displaying a single image on the screen.. doesn't like doing that. The console window opens, then the SDL window opens, then they both close with no messages or anything. Count me among the confused.


[main.cpp]

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <string>

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

#include "entity.h"

using namespace std;

SDL_Surface *screen = NULL;

int main( int argc, char** argv )
{
   SDL_Init(SDL_INIT_EVERYTHING);

   screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

   // Create stuff..
   entity player = entity(1, "The Player");
   player.set_pos(10, 10, 100, 100);
   player.load_image("../pchu.png");

   // Show on screen..
   SDL_BlitSurface(player.get_image(), NULL, screen, &player.get_pos());
   SDL_Flip(screen);

   SDL_Delay(2000);
   return 0;
}


[entity.h]

Code: Select all

#include <string>

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

#ifndef ENTITY_H_
#define ENTITY_H_

struct object
{
      int id;

      std::string name;

      SDL_Surface *image;
      SDL_Rect pos;
};

class entity
{
   protected:
      object _this;

   private:
      bool enabled;

   public:
      entity(int id, std::string name);
      bool load_image(std::string filename);
      SDL_Surface *get_image(void);
      SDL_Rect get_pos(void);
      void set_pos(int x, int y, int width, int height);
};

#endif /* ENTITY_H_ */


[entity.cpp]

Code: Select all

#include <memory>

#include "entity.h"

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

entity::entity(int id, std::string name)
{
   _this.id = id;
   _this.name = name;
}

bool entity::load_image(std::string filename)
{
   SDL_Surface *img_in = NULL;
   SDL_Surface *img_out = NULL;
   img_in = IMG_Load( filename.c_str() );
   if( img_in == NULL )
      return false;

   img_out = SDL_DisplayFormat( img_in );
   SDL_FreeSurface( img_in );

   memmove(_this.image, img_out, sizeof(SDL_Surface));
   SDL_FreeSurface( img_out );

   return true;
}

void entity::set_pos(int x, int y, int width, int height)
{
   _this.pos.x = x;
   _this.pos.y = y;
   _this.pos.w = width;
   _this.pos.h = height;
}

SDL_Surface *entity::get_image(void)
{ return _this.image; }

SDL_Rect entity::get_pos(void)
{ return _this.pos; }


I've tried using the new keyword when creating an instance of the entity class, but I get an error from that. I think that might be a large part of the problem, but i cant figure that one out either.. the error message it gives me for that is main.cpp:21:46: error: conversion from 'entity*' to non-scalar type 'entity' requested.

I'm writing this in eclipse helios (not sure which version) using mingw.
Image

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: sdl not working?

Postby You, sir, name? » Wed Oct 13, 2010 9:41 pm UTC

I don't understand what you are trying to do with memmove.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
SWGlassPit
Posts: 312
Joined: Mon Feb 18, 2008 9:34 pm UTC
Location: Houston, TX
Contact:

Re: sdl not working?

Postby SWGlassPit » Wed Oct 13, 2010 10:21 pm UTC

They both close because your program is segfaulting. It's this line:

Code: Select all

memmove(_this.image, img_out, sizeof(SDL_Surface));


The problem is, _this.image is never set by anything, so basically, you're trying to write to a location pointed to by a pointer that was never initialized.

Change your code as follows:

change the load_image function:

Code: Select all

bool entity::load_image(std::string filename)
{
   SDL_Surface *img_in = NULL;
   SDL_Surface *img_out = NULL;
   img_in = IMG_Load( filename.c_str() );
   if( img_in == NULL )
      return false;

   _this.image = SDL_DisplayFormat( img_in );
   SDL_FreeSurface( img_in );

   return true;
}


Add a destructor (and declare it in your entity.h file):

Code: Select all

entity::~entity()
{
        if (_this.image != NULL)
            SDL_FreeSurface( _this.image );
}


Add this line to your constructor:

Code: Select all

_this.image = NULL;
Up in space is a laboratory the size of a football field zipping along at 7 km/s. It's my job to keep it safe.
Image
Erdös number: 5

User avatar
bocochoco
Posts: 317
Joined: Thu Aug 06, 2009 8:22 pm UTC

Re: sdl not working?

Postby bocochoco » Thu Oct 14, 2010 2:04 pm UTC

Ah that explains it. Not sure why I used memmove to begin with. I always forget the destructor, thank you for pointing that out. Now it doesnt just fail without warning, it just.. fails to work correctly, something to do with the filename I tell it to load. Not sure why though, there isn't much of an error to go on.

Code: Select all

int main( int argc, char** argv )
{
   SDL_Init(SDL_INIT_EVERYTHING);

   screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

   // Create stuff..
   entity player = entity(1, "The Player");
   player.set_pos(10, 10, 100, 100);
   if (player.load_image("pchu.png"))
      printf("Loaded");
   else
      printf("Couldnt load");

   // Show on screen..
   SDL_Rect offset = player.get_pos();
   SDL_BlitSurface(player.get_image(), NULL, screen, &offset);
   SDL_Flip(screen);

   SDL_Delay(2000);
   return 0;
}


Problem is with player.load_image("pchu.png"). If I supply ../pchu.png, it runs but doesn't load an image. If I leave it as pchu.png it loads the image (or so it says), but it instacloses. Another segfault? My potentially fixed load image function is

Code: Select all

bool entity::load_image(std::string filename)
{
   SDL_Surface *img_in = NULL;
   img_in = IMG_Load(filename.c_str());
   if(img_in == NULL) return false;

   img_in = SDL_DisplayFormat(img_in);
   _this.image = img_in;
   SDL_FreeSurface(img_in);
   return _this.image == NULL ? false : true;
}


If i don't use my class to contain the loaded image, everything works fine. Now I'm really confused.
Image

User avatar
SWGlassPit
Posts: 312
Joined: Mon Feb 18, 2008 9:34 pm UTC
Location: Houston, TX
Contact:

Re: sdl not working?

Postby SWGlassPit » Thu Oct 14, 2010 3:13 pm UTC

The code as I posted works fine when compiled with g++. I'd suggest running it through a debugger, step by step, to see what line it's failing on.
Up in space is a laboratory the size of a football field zipping along at 7 km/s. It's my job to keep it safe.
Image
Erdös number: 5

User avatar
bocochoco
Posts: 317
Joined: Thu Aug 06, 2009 8:22 pm UTC

Re: sdl not working?

Postby bocochoco » Thu Oct 14, 2010 3:44 pm UTC

SWGlassPit wrote:The code as I posted works fine when compiled with g++. I'd suggest running it through a debugger, step by step, to see what line it's failing on.



It was failing at loading the image. Not sure why, both my function and the changed one you posted seem to do the same thing, though yours works and mine does not.

Code: Select all

//bool entity::load_image(std::string filename)
//{
//   SDL_Surface *img_in = NULL;
//   img_in = IMG_Load(filename.c_str());
//   if(img_in == NULL) return false;
//
//   img_in = SDL_DisplayFormat(img_in);
//   _this.image = img_in;
//   SDL_FreeSurface(img_in);
//   return _this.image == NULL ? false : true;
//}

bool entity::load_image(std::string filename)
{
   SDL_Surface *img_in = NULL;
   img_in = IMG_Load( filename.c_str() );
   if( img_in == NULL )
      return false;

   _this.image = SDL_DisplayFormat( img_in );
   SDL_FreeSurface( img_in );

   return true;
}


The only thing worse than not knowing why code doesn't work, is not knowing why it does work.. The two functions are essentially identical, except SDL_DisplayFormat...
Image

User avatar
SWGlassPit
Posts: 312
Joined: Mon Feb 18, 2008 9:34 pm UTC
Location: Houston, TX
Contact:

Re: sdl not working?

Postby SWGlassPit » Thu Oct 14, 2010 10:21 pm UTC

SDL_DisplayFormat returns type (if I recall) SDL_Surface *.

That is, img_in is just a pointer to a SDL_Surface object. When you say

Code: Select all

_this.image = img_in;

_this.image simply takes on the address of your image object, but when you free img_in, _this.image becomes a dangling pointer, pointing to the memory address formerly occupied by img_in. Furthermore, the image originally pointed to by img_in no longer has a reference to it, so it becomes a memory leak.

If you say

Code: Select all

_this.image = SDL_DisplayFormat( img_in )

then _this.image is a new address, not the same as img_in, leaving you safe to free img_in.

Gotta watch out for pointers, they can be tricky. Just remember that img_in and _this.image don't actually contain your image, they just point to it.
Up in space is a laboratory the size of a football field zipping along at 7 km/s. It's my job to keep it safe.
Image
Erdös number: 5

User avatar
bocochoco
Posts: 317
Joined: Thu Aug 06, 2009 8:22 pm UTC

Re: sdl not working?

Postby bocochoco » Fri Oct 15, 2010 1:18 pm UTC

SWGlassPit wrote:SDL_DisplayFormat returns type (if I recall) SDL_Surface *.

That is, img_in is just a pointer to a SDL_Surface object. When you say

Code: Select all

_this.image = img_in;

_this.image simply takes on the address of your image object, but when you free img_in, _this.image becomes a dangling pointer, pointing to the memory address formerly occupied by img_in. Furthermore, the image originally pointed to by img_in no longer has a reference to it, so it becomes a memory leak.

If you say

Code: Select all

_this.image = SDL_DisplayFormat( img_in )

then _this.image is a new address, not the same as img_in, leaving you safe to free img_in.

Gotta watch out for pointers, they can be tricky. Just remember that img_in and _this.image don't actually contain your image, they just point to it.


That makes sense. Thank you, I always get stuck on pointers.
Image


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 10 guests