Sign in to follow this  
esperknight

Question about SDL and Engines

Recommended Posts

esperknight    124
I have been working on an engine that uses its own scripting. It is a general engine for playing Visual Novel games (think choose your own adventure type of game) and have noticed something interesting, as it's blitting text it sucks up memory, the same when it's blitting backgrounds and characters. Each section has its own class (text_class, graphics_class, and a parent class that contains variables that each need). I declared the main screen for blitting in the parent class, and then the child classes inherent that variable and blit to it. I also declare the screens used for frame and such as variables of the class and not self contained in functions(I'm thinking this might be my main problem). I have noticed that if I free up the surface used for the frame that blits text, it cuts way down on how much memory gets sucked up when you go through the whole script but it doesn't crash as it should since it gets called over and over (there is no redeclaration of it). My other question is when SDL free's a surface, is it just free up the image itself, or the actual memory of the image. Sorry if this is confusing more than it should be, but I do appreciate the help. Thanks! EK

Share this post


Link to post
Share on other sites
Heewa    140
I'm not sure what you're doing, really. But, if you're deleteing and creating the objects you use to represent your text every frame (or just more often than you need to), then that's very slow. Try creating them once and storing them.

Another thing to check out is how you're using your objects. Do you have an object for each character of text, or one object for an entire string?

I don't understand your question about SDL freeing up an image or the memory of the image. What's the difference? What would freeing up an image without freeing up the memory for it even mean?

Share this post


Link to post
Share on other sites
ender_341    136
Quote:
Original post by Heewa
I don't understand your question about SDL freeing up an image or the memory of the image. What's the difference? What would freeing up an image without freeing up the memory for it even mean?


I think he's talking about when you try to delete/move an image in windows it tells you its in use. though please correct me if I am wrong

Share this post


Link to post
Share on other sites
esperknight    124
Sorry I think I made it real confusing but here's some of my code

My parent class VN_Class


class VN_Class
{
public:
struct save_struct
{
string text_data;

string left_character;
string right_character;
string middle_character;

string background;

int position;

string file;

}save_game;

SDL_Surface *screen;
SDL_Surface *temp_surface;

SDL_Event event;
Uint32 bpp;
VN_Class();
~VN_Class();

static vector<string> script_data;
static int position;

int Load_Data(string data_file, bool RESET_DATA = false, bool RESET_POS = false);
int Jump(string text_string);

string Game_State(string text_string);
};



My child class that inherest

class Text_Class: public VN_Class
{
public:
Text_Class();
~Text_Class();
SDL_Surface *frame;
TTF_Font *font;

vector<string> string_text;
string char_name;


int Display_Text(string text_data);
vector<string> Split_Text(string text_data);
int Blit_Text(string text_string);
int Multi_Line(string text_string, vector<string> *split_text, int frame_width);
int Display_Choice(vector<string> choice_string);

};



The problem arrises when blitting anything to the screen, for some reason teh memory keeps increasing each time one thing is blitted to the screen (when I ran it straight through, it reached 160megs before crashing). I made it so when it use the Blit_Text it free's the frame surface each time, although I neve reinitiate frame at all except for loading an image to it (I had thought that SDL_FreeSurface completely deletes it but I'm not so sure now). The child class uses the parent's class screen to blit too. I'm wondering if for some reason it's recreating a new screen pointer or a new frame pointer each time the class is accessed (the way I have it, it exits out of the classes and goes back into main() to find out what it needs to do next, then heads into which ever class it needs wether text or graphics and does what it needs to do)

example of this is

while(done == 0)
{
SDL_PollEvent(&cGame_Loop.event);

if ( cGame_Loop.event.type == SDL_QUIT ) {done = 1; }

if (cGame_Loop.position < cGame_Loop.script_data.size())
{
string state = cGame_Loop.Game_State(cGame_Loop.script_data[cGame_Loop.position] );

if (state == "<JUMP=")
{
cGame_Loop.Jump(cGame_Loop.script_data[cGame_Loop.position]);
}

if (state == "<TALK=")
{
done = cText.Display_Text(cGame_Loop.script_data[cGame_Loop.position]);
}

if (state == "</>")
{
done = cText.Display_Text(cGame_Loop.script_data[cGame_Loop.position]);
}

etc etc
source]

I hope this helps... really overall I'm trying ot figure out where the memory leak is located, or if I'm doing something wrong, I know it has to deal with blitting to the screen but that's about all I can tell. I appreciate the help! Thanks!

EK

Share this post


Link to post
Share on other sites
Heewa    140
That's still not very clear. A combination of psudo-code and actual code can be easier to understand.

I'll tell you what I did for one of my projects. I had a Graphics class that did the drawing, and you'd call functions on it, passing an image to draw. There was a printString() function that took a string and called the draw functions for each letter on the Graphics class (the class that held the printString function had an array of images, one for each character, by ascii value).

So, something like this:


...
Image* letters[ 255 ];
// Where each item in the array is a pointer to the image structure we
// used, indexed by ascii value. So, if you did letters['A'], it'd
// get you a pointer to the graphic for a capital A.
...

void TextManager::printString( string & text, int posX, int posY ) {

for( int i=0; i < text.size(); i++ ) {

graphics.draw( letters[ text[i] ], posX, posY );

posX += LETTER_WIDTH;

}

}



That was fast enough for us (but we also used Direct3D, in a pretty optimized way for 2D graphics). But, if you wanted something better. You could make a function that creates a surface, draws the text to it, and you keep that surface around (between frames) and draw it in one blit per frame, instead of each letter each frame. Then release the surface when you're not displaying that text anymore.

Either way, you definitely definitely shouldn't be creating and releasing surfaces every frame.

Share this post


Link to post
Share on other sites

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