Question about SDL and Engines

Started by
4 comments, last by Heewa 18 years, 1 month ago
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
Advertisement
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?
If you post some code, specifically where you load, free and blit the imagse, we may be more able to help.
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
-Matt S.
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 etcsource]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
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 ], 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.

This topic is closed to new replies.

Advertisement