Fixed FPS ratio... AND OTHERS!

-* How do you all fix the FPS ratio on your programs under SDL?

I used to do something like:

#define FPS (1000 / 35)
int ActualTime, LastTime;

while(!done)
{

GameFrame();
ActualTime = SDL_GetTicks();
if (ActualTime < LastTime + FPS)
    SDL_Delay(LastTime + FPS - ActualTime);
LastTime = ActualTime;

}

This is supposed to give a fixed ratio of 35 frames per second…

I know I should use the elapsed time between frames to move
sprites according to this time, but that involves asigning
speeds (pixels per second) to sprites (maybe in float coord?)
and some integration methods for collision detection…

The above way is very simple but maybe there is a better way
to do it, maybe using a SDL_SuperBFunction() I don’t know :slight_smile:

-* The same goes for moving a sprite/square from a surface to
another… (by example for erasing all the old sprites by moving
the virtual screen background over there, or by moving the
entire screen)… must I do them by my self

-* I would like to know, by example, how to load a PCX (or any other
format, please NOT BMP, I hate them) into a surface, convert it
to the same depth than the screen, set a ColourKey (0,0,0) and
blit it in (x,y) coordinates on the screen…

-* And finally, there was a Linux-stupid-and-crap-programs compo on
es.comp.os.linux.programacion newsgroup and I did some SDL programs.
If anyone would like to take a look to them (just 4Kb) and tell
me if they include bad SDL code and how I should make things, I will
be very grateful:

http://web.jet.es/s.romero/ecol_compo/boom.tar.gz
http://web.jet.es/s.romero/ecol_compo/lands3d.tar.gz
http://web.jet.es/s.romero/ecol_compo/vida.tar.gz

Those are my very first programs with SDL (with the speccy emulator),
a particle simulator (a programmer’s art tree exploding), and pseudo3d
landscape and John Conway’s Life.

Sorry for the big post and thx a lot for any help.
Please answer if possible, this post has all my SDL doubts :-)–
-----------------------------------------------------

NoP / Compiler – sromero at unix-shells.com
POWERED BY - Linux RedHat 6.0 - Reg. User #74.821
http://web.jet.es/s.romero

~-----------------------------------------------------~

-* How do you all fix the FPS ratio on your programs under SDL?

I used to do something like:

#define FPS (1000 / 35)

Learn the C type promotion rules by heart. This causes an integer
(truncated) division, yielding 28. And the name “FPS” is a misnomer,
since it suggests the number of frames per second rather than the time
interval

GameFrame();
ActualTime = SDL_GetTicks();
if (ActualTime < LastTime + FPS)
SDL_Delay(LastTime + FPS - ActualTime);
LastTime = ActualTime;

this probably works, but beware that SDL_Delay might not be very good at
sleeping short times - you may get 10ms or more. If it is acceptable to you,
you should consider using a busy loop for short delays

I know I should use the elapsed time between frames to move
sprites according to this time, but that involves asigning
speeds (pixels per second) to sprites (maybe in float coord?)
and some integration methods for collision detection…

Another way is to keep a fixed logical frame rate, and simply skip rendering
a frame if you have trouble keeping up

-* The same goes for moving a sprite/square from a surface to
another… (by example for erasing all the old sprites by moving
the virtual screen background over there, or by moving the
entire screen)… must I do them by my self

This can be solved in various ways. A common solution is to keep a separate
background surface, and copy rectangles from it to the destination when
"erasing" a sprite. SDL is a low-level library so it doesn’t have the
concept of “sprites”, only surfaces you can blit back and forth

-* I would like to know, by example, how to load a PCX (or any other
format, please NOT BMP, I hate them) into a surface, convert it
to the same depth than the screen, set a ColourKey (0,0,0) and
blit it in (x,y) coordinates on the screen…

SDL_image, SDL_DisplayFormat(), SDL_SetColorKey(), SDL_BlitSurface().
RTFM

-* And finally, there was a Linux-stupid-and-crap-programs compo on
es.comp.os.linux.programacion newsgroup and I did some SDL programs.
If anyone would like to take a look to them (just 4Kb) and tell
me if they include bad SDL code and how I should make things, I will
be very grateful:

can’t promise anything but I might eye it if I get some spare time

if you have detailed questions, drop by #sdl on irc.openprojects.net

this probably works, but beware that SDL_Delay might not be very good at
sleeping short times - you may get 10ms or more. If it is acceptable to you,
you should consider using a busy loop for short delays

I’ve been wondering about this some myself. Does SDL_GetTicks() return
values accurate down to 1ms, or only down to 10ms, out of curiosity?

-bill!

I’ve been wondering about this some myself. Does SDL_GetTicks() return
values accurate down to 1ms, or only down to 10ms, out of curiosity?

depends: in Unix it uses gettimeofday() which is generally more than
accurate enough, and in win32 it uses a millisecond counter which
should do. The Mac implementation still sucks (1/60 s accuracy), but
someone posted a great way to fix it

Mensaje citado por: Santiago Romero :

-* How do you all fix the FPS ratio on your programs under SDL?

The important thing is constant speed no constant FPS
If you have an slow machine your methiod simply doesn’t run.

-* The same goes for moving a sprite/square from a surface to
another… (by example for erasing all the old sprites by moving
the virtual screen background over there, or by moving the
entire screen)… must I do them by my self

Yes, I suppose

-* I would like to know, by example, how to load a PCX (or any
other
format, please NOT BMP, I hate them) into a surface, convert it
to the same depth than the screen, set a ColourKey (0,0,0) and
blit it in (x,y) coordinates on the screen…

Use SDL_Image 1.0…

Miguel
http://www.arianne.cx

Hay que joderse, dos espa?oles hablando entre si en ingles. :wink:

El 9 Jun 2000 16:07:13 -0700, Mattias Engdeg?rd escribi?:

GameFrame();
ActualTime = SDL_GetTicks();
if (ActualTime < LastTime + FPS)
SDL_Delay(LastTime + FPS - ActualTime);
LastTime = ActualTime;

this probably works, but beware that SDL_Delay might not be very
good at sleeping short times - you may get 10ms or more. If it is
acceptable to you, you should consider using a busy loop for
short delays

what do you mean? (busy loop?).
Well, I code under Linux, and surely SDL is accurate enough under
Linux (wasn’t using gettimeofday = microseconds?).

I know I should use the elapsed time between frames to move
sprites according to this time, but that involves asigning
speeds (pixels per second) to sprites (maybe in float coord?)
and some integration methods for collision detection…

Another way is to keep a fixed logical frame rate, and simply skip
rendering a frame if you have trouble keeping up

can do you write simple pseudocode as the above?

-* The same goes for moving a sprite/square from a surface to
another… (by example for erasing all the old sprites by moving
the virtual screen background over there, or by moving the
entire screen)… must I do them by my self

This can be solved in various ways. A common solution is to keep a
separate background surface, and copy rectangles from it to the
destination when “erasing” a sprite. SDL is a low-level library
so it doesn’t have the concept of “sprites”, only surfaces you
can blit back and forth

so I have 2 options:

1.- Copy the entire surface (the background) over the virtual screen.
2.- Write my own function using memcpy() and the number of bpp to
copy rectangles between surfaces…

What’s faster/better under SDL (in speed/eficiency terms)?

-* I would like to know, by example, how to load a PCX (or any other
format, please NOT BMP, I hate them) into a surface, convert it
to the same depth than the screen, set a ColourKey (0,0,0) and
blit it in (x,y) coordinates on the screen…

SDL_image, SDL_DisplayFormat(), SDL_SetColorKey(), SDL_BlitSurface().
RTFM

I like this kind of answers :slight_smile:

can’t promise anything but I might eye it if I get some spare time

if you have detailed questions, drop by #sdl on irc.openprojects.net

nice, didn’t know you had an irc server for SDL…
thx a lot for all the help…–

El ?nico interfaz intuitivo es el pez?n,
todos los dem?s son aprendidos.
-----------------------------------------------------

NoP / Compiler – sromero at unix-shells.com
POWERED BY - Linux RedHat 6.0 - Reg. User #74.821
http://web.jet.es/s.romero

~-----------------------------------------------------~

what do you mean? (busy loop?).

now = SDL_GetTicks();
while(SDL_GetTicks() < now + delay)
do nothing;

This is normally a cardinal sin under Unix but if you know what you are
doing, are alone on your machine and use it for short periods,
it can be excused. But don’t do it if SDL_Delay works for you.

Well, I code under Linux, and surely SDL is accurate enough under
Linux (wasn’t using gettimeofday = microseconds?).

SDL_GetTicks() is accurate. SDL_Delay might not be.

Another way is to keep a fixed logical frame rate, and simply skip
rendering a frame if you have trouble keeping up

can do you write simple pseudocode as the above?

game loop:
start = SDL_GetTicks()
next = start + frametime
advance world one step (update sprite positions, detect collisions, etc)
if(SDL_GetTicks() < next) /* do we have time for graphics? */
draw graphics for this frame
if(SDL_GetTicks() < next)
SDL_Delay(next - SDL_GetTicks())

so I have 2 options:

1.- Copy the entire surface (the background) over the virtual screen.
2.- Write my own function using memcpy() and the number of bpp to
copy rectangles between surfaces…

No need to, SDL_BlitSurface copies any rectangle between two surfaces.

SDL_GetTicks() is accurate. SDL_Delay might not be.

I beleive it is as accurate as select() on Unix systems.

m.On Wed, Jun 14, 2000 at 12:57:51AM +0200, Mattias Engdeg?rd wrote:


Programmer “Ha ha.” “Ha ha.” "What are you laughing at?"
Loki Software "Just the horror of being alive."
http://lokigames.com/~briareos/ - Tony Millionaire

El 13 Jun 2000 16:01:01 -0700, Mattias Engdeg?rd escribi?:

what do you mean? (busy loop?).

now = SDL_GetTicks();
while(SDL_GetTicks() < now + delay)
do nothing;

I used this till I noticed It was using 100% of CPU.
I prefer using something like SDL_Delay() which makes the application
sleep until it’s time to redraw a new frame (uses less CPU). I noticed
that thanks to kcpuload on my KDE panel… :slight_smile:

This is normally a cardinal sin under Unix but if you know what you are
doing, are alone on your machine and use it for short periods,
it can be excused. But don’t do it if SDL_Delay works for you.

exactly… and thinking that I only code for Linux, I think I can use
SDL_Delay() for all purposes, rigth? (because it uses gettimeofday()).

can do you write simple pseudocode as the above?

game loop:
start = SDL_GetTicks()
next = start + frametime
advance world one step (update sprite positions, detect collisions, etc)
if(SDL_GetTicks() < next) /* do we have time for graphics? */
draw graphics for this frame
if(SDL_GetTicks() < next)
SDL_Delay(next - SDL_GetTicks())

that’s what I was looking for…

frametime = 1.000.000 / fps ???

1.- Copy the entire surface (the background) over the virtual screen.
2.- Write my own function using memcpy() and the number of bpp to
copy rectangles between surfaces…

No need to, SDL_BlitSurface copies any rectangle between two surfaces.

SDL_BlitSurface allows copying from (xorg,yorg) to (xdst, ydst) or it
just copies entire surfaces… uhhhh I know RTFM :slight_smile:

thx a lot for all help given :-)–

Sistema Murmis para preparar el pescado al lim?n: Ponga el pescado
sobre su ojo y apunte con el lim?n en cualquier direcci?n.
-----------------------------------------------------

NoP / Compiler – sromero at unix-shells.com
POWERED BY - Linux RedHat 6.0 - Reg. User #74.821
http://web.jet.es/s.romero

~-----------------------------------------------------~

exactly… and thinking that I only code for Linux, I think I can use
SDL_Delay() for all purposes, rigth? (because it uses gettimeofday()).

it doesn’t, gettimeofday only measures time

frametime = 1.000.000 / fps ???

1000 in my example (SDL ticks are milliseconds)

Santiago Romero wrote:

This is normally a cardinal sin under Unix but if you know what you are
doing, are alone on your machine and use it for short periods,
it can be excused. But don’t do it if SDL_Delay works for you.

exactly… and thinking that I only code for Linux, I think I can use
SDL_Delay() for all purposes, rigth? (because it uses gettimeofday()).

What you can do is SDL_Delay() for just a little less than what you want
to wait for (say, 10 ms less), then busy wait the rest. If you want to
be really nifty, you could dynamically adjust the amount of time you
substract from the SDL_Delay() according to how much time is remaining
on average before going into the busy wait… :-)–
Pierre Phaneuf
Systems Exorcist

Pierre Phaneuf wrote:

Santiago Romero wrote:

This is normally a cardinal sin under Unix but if you know what you are
doing, are alone on your machine and use it for short periods,
it can be excused. But don’t do it if SDL_Delay works for you.

exactly… and thinking that I only code for Linux, I think I can use
SDL_Delay() for all purposes, rigth? (because it uses gettimeofday()).

What you can do is SDL_Delay() for just a little less than what you want
to wait for (say, 10 ms less), then busy wait the rest. If you want to
be really nifty, you could dynamically adjust the amount of time you
substract from the SDL_Delay() according to how much time is remaining
on average before going into the busy wait… :slight_smile:

maby SDL_Delay should do this to allow greater acuracy on all systems

Jess