Archived

This topic is now archived and is closed to further replies.

thekid

Sprite Manager?

Recommended Posts

Hi I am working on my sprite manager and I have a few questions. I want to be able to request an image with a filename. Then I want the sprite manager to return a pointer to the image and If the sprite is not in memory then it loads it from file. How do I do this I know some others have done it but I dont how to do it. Any source? Thanx

Share this post


Link to post
Share on other sites
Hi,
just use a little struct :


typedef struct TSprite
{
bool Loaded;
int SurfaceIndex;
char FileName[25];
};


And if you request the filename and "Loaded" is true, then you can blit it from the surface, else you gotta load it into a surface again.

CU

Graphix Coding @
Skullpture Entertainment
http://www.skullpture.de

Share this post


Link to post
Share on other sites
Yea but How do you find the image you are trying to find with the filename.

For Example:

I have a function like this

GetImage(char *filename);

If I use your method I would have to index through all the images and check if the filname is equal to the filename in the struct.

Is their some more direct way like an index or something?

Anything is helpfull

Share this post


Link to post
Share on other sites
You could just set up a binary search tree of all the filenames loaded, or of the actual surfaces themselves. I haven''t implemented this yet, but I''m planning on it. First, I''d create a class that has the method GetImage(). This would return a pointer to a DX surface (if you''re using DX). The class itself would have a binary search tree of structs:

struct NODE
{
struct NODE *left, *right;
char *filename;
LPDIRECTDRAWSURFACE7 lpddsSurface;
};

When an filename is requested, the class looks through the BST to see if it has been loaded yet, and if not, it loads it, puts it into the BST, then returns the actual pointer to the image. You may want something slightly faster if you plan on calling GetImage() from the class a million times while executing your program, but I think this implementation would be just fine if that''s all you''re looking for.

Good luck!


ColdfireV

Share this post


Link to post
Share on other sites
Alright For restoreing my images and directx surfaces I use a system like this.

typedef struct IMAGE {
int h,w;
LPCTSTR name;
LPDIRECTDRAWSURFACE4 buffer;
BOOL V_BITMAP;
int flag;
BOOL mask;
} IMAGE;
typedef struct V_BITMAP {
IMAGE *Bitmap;
V_BITMAP *next;
} V_BITMAP;
static V_BITMAP *bitmap_list;

Then In my load bitmap function I take The parameters passed to it and store them in the list. (But only if the image is being loaded into video memory.) Then if I loss focus and my surfaces are destoryed I just loop through the list and restore the surfaces by calling the load bitmap function with the parameters saved in the list. This works pretty well and I havent had any speed problems.

Share this post


Link to post
Share on other sites
I am still a little lost. By all of your methods I will have to loop through all my surfaces with alot of if elses to find if the filename matches.

Maybe I am just not understanding

Any source code?

Share this post


Link to post
Share on other sites
I'm planning on doing something like this for my game developement library soon.

What I would do is set up a system where you register your images with a function like this:


int MakeImage( const char* szFileName );


That function would return a resource ID of sorts. Then, when you needed access to the image, you would use a function like this:


LPDIRECTDRAWSURFACE GetImage( int iResourceID );


What I would do internally is to use an array of pointers and use the ID as the array index. Then you could implement GetImage like so:


LPDIRECTDRAWSURFACE GetImage( int iResourceID )
{
if( ! ImageInfoStructs[ iResourceID ]->Loaded ) {
LoadBitmap( &ImageInfoStructs[ iResourceID ] );
}
return ImageInfoStructs[ iResourceID ]->Surface;
}


You might also want to implement some sort of flushing where you can release surfaces not being used.

This should give you a general idea of how to do it. Hope it helps!

Josh
http://www.jh-software.com

Edited by - Josh on 4/4/00 7:10:20 AM

Share this post


Link to post
Share on other sites
If you're in C++, then look into std::map<char*, Sprite*> for one quick and easy solution. It works wonders for me and took under half an hour to implement since I already was familiar with STL code.

Edited by - Kylotan on 4/4/00 8:35:46 AM

Share this post


Link to post
Share on other sites
Kylotan: Your method works, but is it fast enough?

I wouldn''t think that using a map would be as fast as an array index. Of course I haven''t tried it, so I wouldn''t actually know. Your method would definately be easier


Josh
http://www.jh-software.com

Share this post


Link to post
Share on other sites
i''ve used STL map before. of course it wasn''t as fast as Josh''s method (which is great, btw), but i was storing a surface pointer in the game object and just got the pointer when object was created, not every time it was drawn. i didn''t have any "rapid-fire machine gun" that would search the map for bullet gfx 200x/min, but that seemed to be my impression of the speed concept that was brought up.
a map could be useful for a quick, stable (with little testing) way of doing this.

crazy166

some people think i'm crazy, some people know it

Share this post


Link to post
Share on other sites
when i created a surface manager for my engine, i first thought a STL map<> would be ideal.
well, it certainly was concerning programming comfort, but i requested surfaces every frame before they are drawn.
when i profiled my engine, i saw that those plain map lookups were taking up near half (!) of the process time.
so now i am using a c array which is of course helluva fast

Share this post


Link to post
Share on other sites
Still got a problem. With Josh''s method you must store a bunch of intigers somewhere and remember them all to access a bitmap. And also with his BitmapLoad function he has no information to load a bitmap. Like where do you get the filename?

Maybe I still dont get it?

Share this post


Link to post
Share on other sites
quote:

Still got a problem. With Josh''s method you must store a bunch of intigers somewhere and remember them all to access a bitmap. And also with his BitmapLoad function he has no information to load a bitmap. Like where do you get the filename?



Everything needed would be kept in a struct:


struct ImageInfo {
bool bLoaded;
string sFileName;
LPDIRECTDRAWSURFACE Surface;
// whatever else you need here...
};


Now, make a few globals:

const int MAX_IMAGES = 100;
ImageInfo* ImageInfoArray[ MAX_IMAGES ];
int iCurImage = -1;


Now, you could implement MakeImage and LoadBitmap like so:

int MakeImage( const char* szFileName )
{
if( ++iCurImage >= MAX_IMAGES ){ --iCurImage; return -1; }

ImageInfoArray[ iCurImage ] = new ImageInfo;
ImageInfoArray[ iCurImage ]->bLoaded = false;
ImageInfoArray[ iCurImage ]->sFileName = szFileName;

return iCurImage;
}

LPDIRECTDRAWSURFACE LoadBitmap( ImageInfo* pImageInfo )
{
Some_Bitmap_Function( pImageInfo->Surface, pImageInfo->sFileName );

return pImageInfo->Surface;
}


Of course, you would want to put in error handling, but I''m trying to keep this as simple as possible. Hope this clears things up.


Josh
http://www.jh-software.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by thekid

I am still a little lost. By all of your methods I will have to loop through all my surfaces with alot of if elses to find if the filename matches.

Maybe I am just not understanding

Any source code?


I find it interesting these days that if a person doesn''t know the concept of a binary tree or a linked list, they require code explinations in order to implement them.

I remember back in HS when I took pascal (yes I am old) that things like linked list and binary trees were the first and foremost data structures to learn in any thing related to programming.

The trend nowadays seems to be "teach yourself in 21 days --- and try to grab as much of other peoples canned code as possible".... honestly, this makes me sad, that one day, the true hard-core programmer will go the way of the do-do.

Share this post


Link to post
Share on other sites
O Please!!!

Whatever!!!

What I hate about you OLD accoplished coders is that you expect everyone else to be as good as you. This is a comunity and Sharing code is one of the strong points here. If you dont want to then FINE forget I ever asked but dont flame me for doing so.

I have been programing for over a year now and NO I dont know how to do binary search tree. I have read alot of books and I come here every day so I guess I will learn about thems sometime.

Share this post


Link to post
Share on other sites
I've never had a problem with STL speed. It often uses a lot of memory, but is quite fast. The array method mentioned earlier requires that you get an ID number back. That is, of course, quicker, but defeats the original idea of being able to get a sprite based on the name.To get one based on the name, you'd have to have a lookup to get the ID based on the name, and then look in the array, so you'd probably be best off with the map anyway. For the array method, you will have to declare a global variable to hold each ID that gets returned, which may be great for many uses but a hassle for others. Sometimes it's nice to be able to just do:
Draw(GetGraphic("sidebar.bmp");
rather than
int SidebarID = MakeImage("sidebar.bmp"); // in Initialisation section
extern int SidebarID; // in some other file
Draw GetImage(SidebarID);


As it doesn't require adding in extra variables just to draw more graphics, etc. And you can guarantee that "sidebar.bmp" is an accurate description of what you're drawing, whereas SidebarID could be anything you felt like loading into that integer.

Not that I'm knocking Josh's method - I use it myself for certain things (my pathfinding returns PathIDs, for instance.) Just that it's always worth considering other methods

Edited by - Kylotan on 4/5/00 5:30:24 AM

Share this post


Link to post
Share on other sites