synchronization of game cycles

SGDK only sub forum

Moderator: Stef

Post Reply
alko
Very interested
Posts: 172
Joined: Thu Aug 07, 2014 9:31 am
Location: Russian Federation

synchronization of game cycles

Post by alko » Fri Jan 01, 2016 6:58 pm

:wink:
I want to normalize FPS.
fact is that with the appearance of those or other particles also appearance lags.

Code: Select all

  
  int dx;
  int dy;
  ...
  while(TRUE)
    {
handleInput();
drawObjects();
drawParticles1();
drawParticles2();

 SPR_update(sprites, 80);
 VDP_waitVSync();
 }
    
that is, depending on changes FPS must be change values dx dy (increments of the coordinates).

I tried as follows.
But anything sensible did not work.

Code: Select all

int TICKS_PER_SECOND;
    int SKIP_TICKS;
    int MAX_FRAMESKIP ;

   u32 next_game_tick = getTick();
    int loops;
    ...
int main(){
        loops = 0;
MAX_FRAMESKIP = 10;
TICKS_PER_SECOND = 50;
SKIP_TICKS = 1000 / TICKS_PER_SECOND;

  while(TRUE)
 {
    
while( getTick() > next_game_tick && loops < MAX_FRAMESKIP)
 {
handleInput();
drawObjects();
drawParticles1();
drawParticles2();
next_game_tick += SKIP_TICKS;
loops++;
        }
 SPR_update(sprites, 80);
 VDP_waitVSync();
 }
 }
 
Image

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: synchronization of game cycles

Post by Stef » Sat Jan 02, 2016 3:59 pm

Use the V interrupt callback to calculate your base timing, be sure to not miss any interrupt by disabling them too long and that should do it !
To setup the V interrupt callback just use SYS_setVIntCallback(..) method.

alko
Very interested
Posts: 172
Joined: Thu Aug 07, 2014 9:31 am
Location: Russian Federation

Re: synchronization of game cycles

Post by alko » Sat Jan 02, 2016 8:00 pm

I did not understand...

Do you offer like that?

Code: Select all

int TICKS_PER_SECOND;
int SKIP_TICKS;
int MAX_FRAMESKIP ;

u32 CB;

int loops;
...
int main()
{
    loops = 0;
    MAX_FRAMESKIP = 10;
    TICKS_PER_SECOND = 50;
    SKIP_TICKS = 1000 / TICKS_PER_SECOND;
 
 SYS_setVIntCallback(CB);
 
    while(TRUE)
    {
        while( CB > next_game_tick && loops < MAX_FRAMESKIP)
        {
         SYS_setVIntCallback(CB);
         
            handleInput();
            drawObjects();
            drawParticles1();
            drawParticles2();
            next_game_tick += SKIP_TICKS;
            loops++;
        }
        SPR_update(sprites, 80);
        VDP_waitVSync();
    }
}
Thus, the game freezes.
Image

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: synchronization of game cycles

Post by Stef » Sat Jan 02, 2016 8:59 pm

CB is a callback, by callback a mean a method which is called at a specific event.

Code: Select all

// vint method forward declaration
void vint();
...

int main()
{
   ...
   SYS_setVIntCallback(vint);
   ...
   while(TRUE)
   {
      ...
   }
}

void vint()
{
   tick++;
}
As vint() method will be call automatically at each vertical interrupt you are sure your tick variable will be incremented 50/60 times per second.
Then you just need to base your game speed on 'tick'.

alko
Very interested
Posts: 172
Joined: Thu Aug 07, 2014 9:31 am
Location: Russian Federation

Re: synchronization of game cycles

Post by alko » Sun Jan 03, 2016 10:18 am

:cry: ?

Code: Select all


int TICKS_PER_SECOND;
int SKIP_TICKS;
int MAX_FRAMESKIP ;
u32 next_game_tick;
u32 tick ;
int loops;
void vint();
...
int main()
{
    loops = 0;
    MAX_FRAMESKIP = 10;
    TICKS_PER_SECOND = 50;
    SKIP_TICKS = 1000 / TICKS_PER_SECOND;
    SYS_setVIntCallback(vint);
  next_game_tick=tick;
...

   while(TRUE)
    {
            while( tick > next_game_tick && loops < MAX_FRAMESKIP)
            {

 		SYS_setVIntCallback(vint);
 
 ....  //update game

                next_game_tick += SKIP_TICKS;
                loops++;
            }



      SPR_update(sprites, 80);
        }
}


void vint()
{
   tick++;
}
still not working.
Image

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: synchronization of game cycles

Post by Stef » Sun Jan 03, 2016 1:13 pm

You only need to call VDP_setVIntCallback(..) once at initialization.
Also i don't really understand your game synch logic but what about just doing this :

Code: Select all

int main()
{
   SYS_setVIntCallback(vint);
   gameFrame = 0;
   ...
   while(TRUE)
   {
      // wait for at least one game frame
      while(gameFrame == 0);

      while(gameFrame > 0)
      {
         // update game
         ...
         gameFrame--;
      }

      SPR_update(sprites, 80);
   }
}

void vint()
{
   gameFrame++;
}

alko
Very interested
Posts: 172
Joined: Thu Aug 07, 2014 9:31 am
Location: Russian Federation

Re: synchronization of game cycles

Post by alko » Sun Jan 03, 2016 9:07 pm

pace of the game has become normal.
But at the beginning some time: game (coordinates of the objects) is updated, and sprites is don't updated.
Image

alko
Very interested
Posts: 172
Joined: Thu Aug 07, 2014 9:31 am
Location: Russian Federation

Re: synchronization of game cycles

Post by alko » Sat Jan 09, 2016 10:32 am

Code: Select all

  while(TRUE)
    {
        handleInput();
 if(star_game_f==TRUE)
{
u32 current = getTick();
u32 elapsed = current - previous;
previous = current;
lag += elapsed;
while (lag >= VAR)
{
upgate_gaym();
lag -=VAR;
}
 SPR_update(sprites, 80);
}
Now, if the VAR is equal to 10, the gameplay is flawless, but first couple of seconds the sprites are not updated while the coordinates of their updated with furious speed.
If VAR is made equal to 50, then all updated immediately, but the picture is a slideshow.
Image

alko
Very interested
Posts: 172
Joined: Thu Aug 07, 2014 9:31 am
Location: Russian Federation

Re: synchronization of game cycles

Post by alko » Sun Jan 17, 2016 8:27 am

how to reset the timer, which receives time of getTick () ?
Image

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: synchronization of game cycles

Post by Stef » Sun Jan 17, 2016 8:40 pm

You can't reset timer from getTick() which is the "system" timer but you can use

Code: Select all

void startTimer(u16 numTimer);
and

Code: Select all

u32 getTimer(u16 numTimer, u16 restart);
for that (see https://github.com/Stephane-D/SGDK/blob ... nc/timer.h )

Post Reply