Public Group

# First prototype completed, looking for advice in performance.

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

## Recommended Posts

I agree with both of you, I thought there should be something within my code that works wrong. As for the loading of the file "each time", yes and no... Let me explain it with a bit of code:

      SDL_Rect marco; SDL_Rect coordenadas;         //Marco is "frame", the method I use to select the blitable part of the bitmap. Coordenadas is "Coordinates", the place where everything will be.      SDL_Surface *objeto=NULL;         //Objeto is what I´ll blit into "pantalla", the screen surface.      objeto=CargarImagen("juego.bmp");      marco.w=16; marco.h=16;      for(short int contador=0; contador<1200; contador++)                                         {           switch(matriz[contador])    //Matriz is the game matrix.                                                              {                      case 0: marco.x=0; marco.y=0; break;                 case 1: marco.x=48; marco.y=0; break;                 case 2: marco.x=48; marco.y=16; break;                 case 3: marco.x=16; marco.y=0; break;                 case 4: marco.x=32; marco.y=0; break;                 case 5: marco.x=32; marco.y=16; break;                 case 6: marco.x=0; marco.y=16; break;            }                                    coordenadas.x=((contador%40)*16)+80;  //This is the way I get the            coordenadas.y=((contador/40)*16)+48;  //coordinates.            SDL_BlitSurface(objeto, &marco, pantalla, &coordenadas);                      }

Here, this function loads the tileset and checks the whole matrix. Depending on the value of the matrix a certain portion of the tileset is blitted.

The function is called in each gametic (errr... Every iteration of the main game loop, whether something happens or not... I know, lazy!). You can see that I use a "CargarImagen" function (literally "Loadimage") so each time I run the function I load the bmp file again. What I don´t do is loading the bmp for each blitting "tile" of the matrix.

So, do you advise me to load the bmp file only once?. I could load it in the "main game loop" and send the resulting surface along to the function above like maindrawing(pantalla, objeto)... I could also make it a global surface but I´m not sure about globals (I don´t really dig them, not sure why).

Thanks in advance for all replies and suggestions :).

##### Share on other sites
When you say the tile is loaded once per tick, what do you mean exactly? If you mean you are literally loading the tile from a file each time before drawing then that would certainly be the cause of the slowdown.

SDL is not, as far as I am aware, known to be particularly slow since it sits quite closely to the underlying graphics API (DirectDraw, OpenGL, whatever) that it wraps.

It does sound to me as if the speed is issues in your code rather than with SDL. You can post relevent sections of code here (in [ source ][ /source ] tags but without the spaces) which may enable people to give you better advice.

##### Share on other sites
It must be your algo not SDL.
Try to write/draw things in groups, not every tile apart)

www.nextdawn.nl

##### Share on other sites
Quote:
 Original post by The_Marlboro_ManSo, do you advise me to load the bmp file only once?. I could load it in the "main game loop" and send the resulting surface along to the function above like maindrawing(pantalla, objeto)... I could also make it a global surface but I´m not sure about globals (I don´t really dig them, not sure why).

Yep, that's exactly the problem and you have a good instinct for avoiding globals :)

One way to do it is to make an object that represents the "map", and give it the surface as a data member. This way you can also use RAII to clean up the SDL_Surface later.

class Map {  SDL_Surface* objeto;  // The matrix should probably be a member of this class too. BTW, you can make  // the array 2D for no cost in overhead (it will be laid out in memory as a  // single chunk, and indexing operations will be transformed accordingly). The  // compiler is able to do this because the dimensions are known ahead of time.  // Also, you probably should use an enumerated type instead, but I don't know  // what the values mean so you'll have to do that part :)  int matriz[30][40]; // [rows][columns]  public:  Map(): objeto(CargarImagen("juego.bmp")) {    assert(objeto);  }  ~Map() { SDL_FreeSurface(objeto); }  void draw(SDL_Surface* pantalla) {    SDL_Rect marco, coordenadas;    // Initializing the 'marco' doesn't really help because we're going to set    // it before use every time through the loop.    // It doesn't help any to make the loop counter smaller. You should normally    // just use int for everything unless you have a specific reason you need    // a specific size.    for (int y = 0; y < 30; ++y) {      for (int x = 0; x < 40; ++x) {        switch (matriz[y][x]) {               case 0: marco.x=0; marco.y=0; break;          case 1: marco.x=48; marco.y=0; break;          case 2: marco.x=48; marco.y=16; break;          case 3: marco.x=16; marco.y=0; break;          case 4: marco.x=32; marco.y=0; break;          case 5: marco.x=32; marco.y=16; break;          case 6: marco.x=0; marco.y=16; break;        }        coordenadas.x = (x*16)+80;        coordenadas.y = (y*16)+48;        SDL_BlitSurface(objeto, &marco, pantalla, &coordenadas);                      }    }  }  // And other stuff, e.g. the code that puts values into Matriz};// Then in main(), we create a Map and use it each game tick:int main() {  Map m;  // etc. etc.  while (something) {    m.update();    m.draw(pantalla);  }}

This lets us do what a global would do for us (i.e. keep the 'surface' around between calls to draw() and not have to pass it as a parameter), but it also gives us good protection on that access (so we won't accidentally start using 'objeto' in a way that we shouldn't - it "belongs" to the Map), creates an abstraction (we can think of the Map as a new data type), and lets us create more than one (if we should ever need to).

##### Share on other sites
Zahlman, thanks for your time going through my code and giving better ideas for it :). Though I don´t fully understand them I´ll make sure to study the sintax and meaning... As for the matrix, I actually had it like a bidimensional matrix in the main function but passed only a pointer to it to the draw function, to avoid massive copy of data.

Then there´s the object solution... I wish I could understand it a bit better but for now I haven´t studied any Object Oriented Programming (I will make sure to do it shortly, once I get the hang of structures). I think I shall leave it for now until I understand how classes work (and can, thus, convert the whole work to the object paradigm)... To begin with, I´ll "climb" one level and remove the "loadimage" function from each tic, passing it from the main, then I´ll try to see if there´s any advance in performance.

There´s one last question I have before I get to the code again, and I hope you don´t mind: you commented that initializing the "marco" (frame) "doesn't really help because we're going to set it before use every time through the loop". Is that the "Same" problem?. I mean, would it be better to have it "outside" the function as a global or member of a class?.

Thanks a lot!.

PS: Also, is there any reason not to use short int instead of int?. I didn´t plan the count to be high and I thought I could save 8 bites in all these small counters and vars.

##### Share on other sites
Quote:
 Original post by The_Marlboro_ManAlso, is there any reason not to use short int instead of int?

There is no point in saving a few bits for a counter. And an int is propably faster, because it is the size of the native word.

##### Share on other sites
Took a look at some sites and it seems that, in fact, int fares better than the rest of the data types. I don´t think it could have a significant impact on the game, but I could try and change them.

As for loading the image into a surface once per game and sending a pointer to the surface along to the drawing function it seems that it improved the performance a tiny bit. I wonder how much would it improve with the object approach but so far I think I could try some other things, like improving the drawing algorithm and doing just 3 blits (instead of... 1200).

My next worry lies in the sound, in having all of them loaded at once or loading them when they need to be played. I´ll try and write some small program to compare the options. Thanks a lot for the information :).

1. 1
2. 2
3. 3
Rutin
18
4. 4
JoeJ
14
5. 5

• 14
• 10
• 23
• 9
• 33
• ### Forum Statistics

• Total Topics
632633
• Total Posts
3007543
• ### Who's Online (See full list)

There are no registered users currently online

×