Thanks for the help. I've got everything working now, although I haven't tried to implement colorkeys or alpha yet.
One concern I had is that the surfaces are never freed because my imagemanager class holds on to a copy of the pointer in its map. How could I fix this? Do I need to use weak pointers or something? Is this even something I need to worry about?
Here is what my code looks like now
imagemanager.h
#ifndef IMAGEMANAGER_H#define IMAGEMANAGER_H#include "SDL/SDL.h"#include "shared_ptr.hpp"#include <string>#include <map>class Image;typedef boost::shared_ptr<Image> img_sptr;class Image{ SDL_Surface *mysurface; // Only implement these if you really need to. // Most of the time you don't want to be copying SDL_Surfaces, // it is expensive // Better to simple use boost::shared_ptr<Image> // // Declare them here, private and don't implement them // This means that the compiler won't generate its defaults Image(const Image &other); Image &operator=(const Image &other); // You should only need to store the surface pointer here // Other state information like the per-surface alpha and // colour key can be obtained from surface->format IIRC. public: // you could have another constructor that takes a SDL_RWops // if you want to make Image instances from memory data. // // Image(const std::string &file); //not implemented yet //Image(const std::string &file, const SDL_Color &colorkey); //Image(const std::string &file, Uint8 alpha); // This class is not intended to be subclassed. // This means you can avoid having a virtual destructor ~Image(); // You can have as many overloads as you like // For example, to perform clipped blits you could have an overload // that takes a SDL_Rect parameter. // These should be marked as const, but I'm not sure if // SDL is const-correct with surface blitting due to internal // issues, but try to do so if you can. void draw(int x, int y, SDL_Surface *screen, SDL_Rect *clip = NULL) const; // Don't bother providing set/get SDL_Surface, I don't think you need it // Best not to provide functions like setColorKey or setAlpha at all // if you can avoid it. See below for details.};//////////////////////////////////////////////////////////////class imageManager{ static std::map<std::string, img_sptr > mymap; public: static img_sptr demand( std::string);};#endif
imagemanager.cpp
#include "imagemanager.h"#include <iostream>Image::Image(const std::string &file){ SDL_Surface * loadedimage; SDL_Surface * displayimage; loadedimage = SDL_LoadBMP( file.c_str() ); if (loadedimage != NULL) { mysurface = SDL_DisplayFormat( loadedimage ); //converts the surface to a form //that is "suitable for fast blitting" std::cout << file << " loaded sucessfully\n"; } else { mysurface = NULL; }}Image::~Image(){ std::cout << "An image was deconstructed\n"; SDL_FreeSurface (mysurface);}void Image::draw(int x, int y, SDL_Surface *screen, SDL_Rect *clip) const{ SDL_Rect temp; temp.x=x; temp.y=y; if (screen == NULL) { std::cout << "Screen is NULL\n"; } if (mysurface == NULL) { std::cout << "MySurface is NULL\n"; } std::cout << "Draw begun ...\n"; std::cout << "Mysurface is " << mysurface << "\n"; std::cout << SDL_BlitSurface(mysurface, clip, screen, &temp) << "\n"; std::cout << "Draw finished\n";}std::map<std::string, img_sptr > imageManager::mymap;img_sptr imageManager::demand(std::string imgname){ std::map<std::string, img_sptr >::iterator iter; img_sptr newpointer; std::cout << imgname << " demanded.\n"; iter = mymap.find(imgname); if (iter == mymap.end()) { std::cout << "Demand not in map\n"; newpointer.reset( new Image( imgname )); mymap.insert( std::pair<std::string, img_sptr >( imgname, newpointer ) ); return newpointer; } else { std::cout << "Demand in map\n"; return iter->second; }}