Hi,
Here the source to the demo in question:
(sorry it is more than one page)
You can download this source file and images here:
http://silentheroproductions.com/files/SDL_PerfecT-l-EnginE_5.0_GT.zip=================================================================================
/*
SDL® PerfeT+EnginE 5.0 GT
©opyright 2009 by www.SilentHeroProductions.com
*/
// On my 4 core 2.4GHz CPU it runs at 60 Frames Per Second
// with CPU utilization at about 20% on 1 core…
// How I improve performance???
// Keep in mind that I am doing the following each frame:
// 1. Clear screen with black
// 2. Draw star background
// 3. Draw 600 sprites (400 pixel stars and 200 Mario sprites)
// NOTE: using SDL 1.2 I get 60FPS and using SDL 1.3 I get 40FPS ???
#include
#include “SDL.h”
#include “SDL_image.h”
#include “SDL_ttf.h”
#define NumberOfStars 200 // 3 sets - 2 for stars and 1 for Marios
bool EXITgame = false;
Sint32 Stars_BGX = 0;
Sint32 Stars_BGY = 0;
SDL_Event Event;
Uint32 Ticks = SDL_GetTicks();
Uint32 FrameRateLock = 17;
Uint32 NextFrameTicks = 0;
Uint32 NextSecondTicks = 0;
Uint32 FramesPerSecondArray[10];
Uint8 CurrentFPSIndex = 0;
Uint32 NumberOfFramesInThisSecond = 0;
Uint32 FramesPerSecondAverage = 0;
TTF_Font *Font = NULL;
char VariableText[64];
SDL_Surface *Text = NULL;
SDL_Color TextColor = {0, 255, 0, 255};
SDL_Rect destinationRectangle;
SDL_Surface *Stars_BG = NULL;
SDL_Surface *ImageConvertToScreenFormatSurface = NULL;
SDL_Surface *Stars[3];
Sint32 StarsX[3][NumberOfStars];
Sint32 StarsY[3][NumberOfStars];
//-=(main)=-----------------------------------------------------------------------------------------------------
int main( int argc, char* args[] )
{
if ( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
fprintf(stderr, “Could not initialize SDL: %s.\n”, SDL_GetError());
return(-1);
}
SDL_WM_SetCaption("SDL_PerfecT-l-EnginE_5.0_GT", NULL);
SDL_WM_SetIcon(SDL_LoadBMP("data/visuals/icon.bmp"), NULL);
SDL_putenv("SDL_VIDEO_CENTERED=center");
SDL_Surface *Screen;
Screen = NULL;
Screen = SDL_SetVideoMode(640, 640, 0, SDL_SWSURFACE);
if (Screen == NULL)
{
fprintf(stderr, "Couldn't set 640x640 video mode: %s\n",
SDL_GetError());
return(-1);
}
SDL_SetClipRect(Screen, NULL);
Stars_BG = NULL;
ImageConvertToScreenFormatSurface = NULL;
ImageConvertToScreenFormatSurface =
IMG_Load(“data/visuals/Stars_BG.gif”);
if (ImageConvertToScreenFormatSurface == NULL)
{
fprintf(stderr, “Couldn’t load %s\n”, IMG_GetError());
return(-1);
}
Stars_BG = SDL_DisplayFormat(ImageConvertToScreenFormatSurface);
SDL_FreeSurface(ImageConvertToScreenFormatSurface);
if (Stars_BG->format->palette && Screen->format->palette)
{
SDL_SetColors(Screen, Stars_BG->format->palette->colors, 0,
Stars_BG->format->palette->ncolors);
}
// #define COLORKEY1 255, 255, 255 // Transparent color
// SDL_SetColorKey( Sprite, SDL_SRCCOLORKEY,
SDL_MapRGB(Sprite->format, COLORKEY1) );
Stars[0] = NULL;
ImageConvertToScreenFormatSurface = NULL;
ImageConvertToScreenFormatSurface = IMG_Load("data/visuals/Star_1.gif");
if (ImageConvertToScreenFormatSurface == NULL)
{
fprintf(stderr, "Couldn't load %s\n", IMG_GetError());
return(-1);
}
Stars[0] = SDL_DisplayFormat(ImageConvertToScreenFormatSurface);
SDL_FreeSurface(ImageConvertToScreenFormatSurface);
if (Stars[0]->format->palette && Screen->format->palette)
{
SDL_SetColors(Screen, Stars[0]->format->palette->colors, 0,
Stars[0]->format->palette->ncolors);
}
// #define COLORKEY1 255, 255, 255 // Transparent color
// SDL_SetColorKey( Sprite, SDL_SRCCOLORKEY,
SDL_MapRGB(Sprite->format, COLORKEY1) );
Stars[1] = NULL;
ImageConvertToScreenFormatSurface = NULL;
ImageConvertToScreenFormatSurface = IMG_Load("data/visuals/Star_2.gif");
if (ImageConvertToScreenFormatSurface == NULL)
{
fprintf(stderr, "Couldn't load %s\n", IMG_GetError());
return(-1);
}
Stars[1] = SDL_DisplayFormat(ImageConvertToScreenFormatSurface);
SDL_FreeSurface(ImageConvertToScreenFormatSurface);
if (Stars[1]->format->palette && Screen->format->palette)
{
SDL_SetColors(Screen, Stars[1]->format->palette->colors, 0,
Stars[1]->format->palette->ncolors);
}
// #define COLORKEY1 255, 255, 255 // Transparent color
// SDL_SetColorKey( Sprite, SDL_SRCCOLORKEY,
SDL_MapRGB(Sprite->format, COLORKEY1) );
Stars[2] = NULL;
ImageConvertToScreenFormatSurface = NULL;
ImageConvertToScreenFormatSurface = IMG_Load("data/visuals/Mario.gif");
if (ImageConvertToScreenFormatSurface == NULL)
{
fprintf(stderr, "Couldn't load %s\n", IMG_GetError());
return(-1);
}
Stars[2] = SDL_DisplayFormat(ImageConvertToScreenFormatSurface);
SDL_FreeSurface(ImageConvertToScreenFormatSurface);
if (Stars[2]->format->palette && Screen->format->palette)
{
SDL_SetColors(Screen, Stars[2]->format->palette->colors, 0,
Stars[2]->format->palette->ncolors);
}
#define COLORKEY1 0, 255, 0 // Transparent color
SDL_SetColorKey( Stars[2], SDL_SRCCOLORKEY,
SDL_MapRGB(Stars[2]->format, COLORKEY1) );
if ( TTF_Init() == -1 )
{
fprintf(stderr, "TTF_Init: %s\n", TTF_GetError());
return(-1);
}
Font = NULL;
Font = TTF_OpenFont( "data/fonts/Game_Font.font", 33 );
if (!Font)
{
fprintf(stderr, "TTF_OpenFont: %s\n", TTF_GetError());
return(-1);
}
// srand( (unsigned)time( NULL ) );
for (Sint16 starColorIndex = 0; starColorIndex < 3; starColorIndex++)
{
for (Uint16 starIndex = 0; starIndex < NumberOfStars; starIndex++)
{
StarsX[starColorIndex][starIndex] = rand()%640;
StarsY[starColorIndex][starIndex] = rand()%640;
}
}
for (Uint8 index = 0; index < 10; index++)
FramesPerSecondArray[index] = 0;
NextSecondTicks = SDL_GetTicks()+1000;
// MAIN
LOOP---------------------------------------------------------------------
while (EXITgame == false)
{
Ticks = SDL_GetTicks();
NextFrameTicks = Ticks + FrameRateLock;
if (Ticks >= NextSecondTicks)
{
FramesPerSecondArray[CurrentFPSIndex] =
NumberOfFramesInThisSecond;
NumberOfFramesInThisSecond = 0;
NextSecondTicks = SDL_GetTicks()+1000;
if (CurrentFPSIndex < 9) CurrentFPSIndex++;
else CurrentFPSIndex = 0;
}
SDL_PumpEvents();
SDL_PollEvent(&Event);
{
switch(Event.type)
{
case SDL_QUIT:
EXITgame = true;
break;
case SDL_KEYDOWN:
switch(Event.key.keysym.sym)
{
case SDLK_ESCAPE:
EXITgame = true;
break;
case SDLK_UP:
Stars_BGY++;
break;
case SDLK_DOWN:
Stars_BGY--;
break;
case SDLK_LEFT:
Stars_BGX++;
break;
case SDLK_RIGHT:
Stars_BGX--;
break;
default:
break;
}
}
}
#define COLORKEYFILL 0, 0, 0
SDL_FillRect( Screen, NULL, SDL_MapRGB(Screen->format,
COLORKEYFILL) );
destinationRectangle.x = Stars_BGX;
destinationRectangle.y = Stars_BGY;
SDL_BlitSurface(Stars_BG, NULL, Screen, &destinationRectangle);
for (Sint16 starColorIndex = 2; starColorIndex > -1;
starColorIndex–)
{
for (Uint16 starIndex = 0; starIndex < NumberOfStars;
starIndex++)
{
destinationRectangle.x = StarsX[starColorIndex][starIndex];
destinationRectangle.y = StarsY[starColorIndex][starIndex];
SDL_BlitSurface(Stars[starColorIndex], NULL, Screen,
&destinationRectangle);
if (starColorIndex == 2)
StarsY[starColorIndex][starIndex]++;
else if (starColorIndex == 1)
StarsY[starColorIndex][starIndex]+=2;
else if (starColorIndex == 0)
StarsY[starColorIndex][starIndex]+=3;
if (StarsY[starColorIndex][starIndex] > 640)
{
StarsX[starColorIndex][starIndex] = rand()%640;
StarsY[starColorIndex][starIndex] = -70;
}
}
}
FramesPerSecondAverage = 0;
for (Uint8 index = 0; index < 10; index++)
{
FramesPerSecondAverage+=FramesPerSecondArray[index];
}
FramesPerSecondAverage = FramesPerSecondAverage / 10;
// TextColor = {0, 255, 0, 255}; <— Why does this not work???
sprintf(VariableText, “%d”, FramesPerSecondAverage);
Text = TTF_RenderText_Solid(Font, VariableText, TextColor);
destinationRectangle.x = 0;
destinationRectangle.y = 0;
SDL_BlitSurface(Text, NULL, Screen, &destinationRectangle);
SDL_FreeSurface(Text);
SDL_Flip(Screen);
NumberOfFramesInThisSecond++;
Ticks = SDL_GetTicks();
if (Ticks < NextFrameTicks) SDL_Delay(NextFrameTicks-Ticks); //
The one SDL_Delay()
}
//--------------------------------------------------------------------------
SDL_FreeSurface(Stars_BG);
Stars_BG = NULL;
SDL_FreeSurface(Stars[0]);
Stars[0] = NULL;
SDL_FreeSurface(Stars[1]);
Stars[1] = NULL;
SDL_FreeSurface(Stars[2]);
Stars[2] = NULL;
TTF_CloseFont(Font);
Font = NULL;
SDL_Quit();
return(0);
}
// A 100% by JeZ+Lee…
=================================================================================
Sam Lantinga wrote:
Not sure if this is problem on my end…
I wrote a one page demo using SDL 1.2
that just displays a background
and 400 pixels stars and 200 Mario sprites moving
I ported it to SDL 1.3 and it is 30% slower on same machine
SDL 1.2 version ran 60 Frames Per Second (Code::Blocks)
and
SDL 1.3 version runs at 40 FPS (MSVC++ 2008 EE)
Could a 30% drop in native blitting going from 1.2 to 1.3 be possible ?
SDL 1.3 using the old 1.2 API should be about as fast as SDL 1.2.
There were some bug fixes that might result in a different code path
for certain combinations of blit settings, but if you post your code
and images`someone can take a look.
FYI, the new API was designed to accelerate exactly the sort of thing
you’re doing. Go ahead and take a look at testsprite2.c and testdraw2.c
to see how to use the texture and drawing API. You should get about a
5 to 10 times speedup on most systems.
See ya!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org