Sign in to follow this  

help with loop (SDL Images)

This topic is 4654 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I'm making a SDL game at the moment, and for each image I want in the game I've got:
    //load menu image
    img_menu = SDL_LoadBMP("data/menu.bmp");
    if(img_menu == NULL)
        fprintf(stderr,
                "Unable to load image %s\n",
                SDL_GetError());
                
    //load cursor image
    img_cursor = SDL_LoadBMP("data/cursor.bmp");
    if(img_cursor == NULL)
        fprintf(stderr,
                "Unable to load image %s\n",
                SDL_GetError());
    
    //load background image
    img_arena = SDL_LoadBMP("data/arena.bmp");
    if(img_arena == NULL)
        fprintf(stderr,
                "Unable to load image %s\n",
                SDL_GetError());
etc, is there a way I can put "menu", "cursor", "arena" etc into a vector and just iterate through that vector throwing the data into that little chunk of code each time? The main problem I see is getting it within the ""'s for the image file directory. Thanks in advance.

Share this post


Link to post
Share on other sites
Sure there is:

#include <vector>

std::vector<SDL_Surface*> images;

bool LoadImage(std::string filename){
SDL_Surface* temp = SDL_LoadBMP(filename.c_str());
if(temp){
images.push_back(temp);
return true;
}
return false;
}

void DrawImages(){
for(std::vector<SDL_Surface*>::iterator pos = images.begin(); pos != images.end(); pos++){
// Draw Image - DrawIMG(*pos);
}
}


Is that similar to what you're looking for? I haven't compiled any of that so be warned.

Share this post


Link to post
Share on other sites
no I don't think so sorry... either it's not quite what I'm after, or I just don't understand what you've written....

taking into note that in my first post is how it looks now, what I'm after would be something like this:


string image[] = {"menu",
"cursor",
"background",
"health",
"title",
"badguy",
"END"};

//load all images
for (int i = 0; image[i] != "END"; i++)
{
string varName = "img_" + image[i];
string location = "data/images/" + image[i] + ".bmp");

varName = SDL_LoadBMP(location);
if(varName == NULL)
fprintf(stderr,
"Unable to load image %s\n",
SDL_GetError());

}


of course the string varName is pretty much.. nonsensicle, and doesn't work... but that's what I'm after... being able to use a string variable in the name of another variable..


If anyone can gimme a hand I'll be greatly appreciative!
Thanks in advance!

Share this post


Link to post
Share on other sites
I think you are close with your last post. However there is one little problem:

varName = SDL_LoadBMP(location);
if(varName == NULL)
fprintf(stderr,
"Unable to load image %s\n",
SDL_GetError());






Since varName is defined as a string, that will not compile (incorrect data types). Consider this:

vector<string> image;
image.push_back("menu");
image.push_back("cursor");
image.push_back("background");
image.push_back("health");
image.push_back("title");
image.push_back("badguy");

vector <SDL_Surface*> DataImages;
//load all images
for (int i = 0; i < image.size(); i++)
{
string varName = "img_" + image[i];
string location = "data/images/" + image[i] + ".bmp");

DataImages.push_back( SDL_LoadBMP(location) ); // Rob's idea [wink]
if(DataImages[ DataImages.size() - 1 ] == NULL)
fprintf(stderr, "Unable to load image[%s]: %s\n", location .c_str(), SDL_GetError());
}





Give that a try out. Basically it will add all the images to a vector as Rob has suggested in previous posts. You will definitly need to track all of the images so you can SDL_FreeSurface them at the end [smile].

Share this post


Link to post
Share on other sites
First, @Rob: storing things in a non-keyed container like a vector and rejecting nulls is a bad idea. You saddle the rest of the code with the task of figuring out the index into the vector for each successfully loaded image, given the successes/failures. Needlessly complex. Better to leave the nulls in, or better yet (probably), replace them with pointers to a Null Object.

Anyway. I think you two are misunderstanding; the OP seems to want to create new identifier names at runtime.

@OP: Sorry, it can't be made to work exactly as you seem to want it. The variable names don't exist at run-time. The calculation of the variable name that you want - i.e. appending whatever to the "img_" - can't happen until the program is already compiled and running, and at that point it is too late for the compiler to say "oh wait, we need a variable with this name, too".

You need to have some structure that will hold all the images instead, such as an array, a std::vector (as illustrated), or what I will suggest, a std::map. The map is a data structure which lets you insert and look up its contents by "key" - which is of a type of your choosing - rather than by a numerical index; the information about key values is preserved at runtime, as part of the map data. What this means is that you can use the "friendly" names when looking things up:


#include <map>
#include <string>
using namespace std;

map<string, SDL_Surface*> img;

const string imageNames[] = {
"menu", "cursor", "background", "health", "title", "badguy"
};

// Create Null Object
SDL_Surface * nullSurface = SDL_CreateRGBSurface(0, 0, 0, 8, 0, 0, 0, 0);

//load all images
const int imageCount = sizeof(imageNames) / sizeof(string);
for (int i = 0; i < imageCount; i++) {
string location = "data/images/" + imageNames[i] + ".bmp");

// the std::map overloads operator[] to do what you'd expect - you supply the
// key where you would normally put an array index, and you get a reference to
// that "slot".
// if the load fails, we'll point at the null object instead.
img[imageNames[i]] = SDL_LoadBMP(filename.c_str()) || nullSurface;
// May as well log an error in that case
if (img[imageNames[i]] == nullSurface) {
cerr << "Unable to load image[" << location << "]: "
<< SDL_GetError() << endl;
}
}

// Now you access an image like this:
do_something_with(img["cursor"]); // rather than img_cursor
// If you specify a bad name, you'll get a null pointer, rather than a pointer
// to our null object, unfortunately. To fix that we'd need to make a
// wrapper class to encapsulate our SDL_Surface* (and in the default ctor, make
// the SDL_Surface* data member point at the null object). Basically, the map
// returns a default-constructed element of the value type in this case;
// "default-constructed" primitives are zero, i.e. NULL for pointers.

Share this post


Link to post
Share on other sites
Quote:
The variable names don't exist at run-time.

Ah. of course. :) I knew my particular chunk of code wasn't going to work, I just put that there to demonstrate exactly what I was trying to acomplish, but thinking about it logically, it could never have worked for that exact reason. I don't know why I thought it would work... I think I used a similar idea in Flash ActionScript once... :p

ok, so I suppose I'll use the map idea, unless I can't figure it out, in which case i'll just use a good ol'e vector like the others suggested, all in all, thanks a lot guys!

EDIT: Looking back over it, Rob's first reply will work quite nicely indeed! sorry for not just running with that one the first time. on another note; rob, it was your SDL tuts I used to get me started, so thanks for that too!!

EDIT2: Looking through it another time, each suggestion was really a kinda.. better version of the prev one, so I'm gonna go w/ the last one there, but I'm a little confused with this line:

Quote:
img[imageNames[i]] = SDL_LoadBMP(filename.c_str()) || nullSurface;


should: filename.c_str()
in there just be: location

or even : location.c_str()

on that note, what is .c_str() ?

Thanks again!

[Edited by - Lord_Spatulator on March 22, 2005 4:40:50 AM]

Share this post


Link to post
Share on other sites

This topic is 4654 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this