Search code examples
cteensy

Increasing an integer through a time delay


I'm producing a game in C on a microprocessor. The score is controlled by how long you can survive; the score increases by 1 every 3 seconds. The score is an integer which is declared globally, but displayed from a function.

int score = 0;//globally declared

void draw_score(int score_d)
{
    char score_draw[99];
    sprintf(score_draw,"%d", score_d);
    draw_string(score_draw, 9, 0);
}

I was thinking of a function which just increases the score by one with a delay on it, however that has not worked.

void score_increaser(int score)
{
    score++;
    _delay_ms( 3000 );
}

Does it need to be in a while loop? the function itself would go into a while loop in the main anyway.


Solution

  • C is pass by value.

    score_increaser() as shown in your question increases just a copy of what is passed in.

    To fix this there are (mainly) two options:

    1. As score is defined globally, do not pass in anything:

      void score_increaser(void) {
        score++;
        _delay_ms( 3000 );
      }
      

      This modifes the globale score directly.

    2. Pass in the address of score and de-reference it inside the function

      void score_increaser(int * pscore) {
        (*pscore)++;
        _delay_ms( 3000 );
      }
      

      Call it like this

      ...
      score_increaser(&score);
      ...
      

    A 3rd, a bit more complex, approach (which assumes signals are supported on the target platform) would

    1. setup a signal and a referring handler, then
    2. setup a timer to fire a signal every N seconds.
    3. This signal then is handled by the handler, which in turn
    4. increases the global score and
    5. starts the timer again.

    This might look like:

    #include <signal.h> /* for signal() and sig_atomic_t */
    #include <unistd.h> /* for alarm() */
    
    
    #define DURATION (3) /* Increase score every 3 seconds. */
    
    sig_atomic_t score = 0;
    
    
    void set_alarm(unsigned);
    
    void handler_alarm(int sig)
    {
      ++score;
      set_alarm(DURATION);
    }
    
    void set_alarm(unsigned duration)
    {
      signal(SIGALRM, handler_alarm);
      alarm(duration);
    }
    
    
    int main(void)
    {
      set_alarm(DURATION);
    
      ... /* The game's codes here. */
    }
    

    This latter approach has the advantage that your game's code does not need to take care about increasing score. score is just increased every 3 seconds as long as the program runs.