Search code examples
cmarquee

How to create an efficient marquee function in c


I tried to create a marquee function that moves the given text every time it is called(it is placed inside an infinite loop). but it uses too much CPU process. Is there a way to make it efficient?

int myfunc_Marquee ( COORD StartPosition, int Direction, char Text [ ], int Delay)
{

    int Length = strlen ( Text ),
        width,
        height;
    clock_t time2,timeD;
    static clock_t time1;
    static COORD CurrentPosition;
    static BOOL flag;
    COORD RestorePosition = { wherex ( ), wherey ( ) };
    width = 60;
    height = 20;
    time2 = clock ( );
    timeD = time2 - time1; //time difference
    if ( time1 == 0 ) //on first call just prints the text
    {
       CurrentPosition = StartPosition;
       myfunc_gotoxy ( CurrentPosition.X, CurrentPosition.Y );
       fputs ( Text, stdout );
       Direction %= 4;
       if ( ( Direction == 2) || ( Direction == 3 ) )
       flag = 1;
       time1 = time2;
    }
    else if ( timeD > Delay) // if more than the given delay time has passed move the text
    {
         myfunc_SetOutputColor ( 0, 0 );//erases the last printed text
         myfunc_gotoxy ( CurrentPosition.X, CurrentPosition.Y );
         fputs ( Text, stdout );
         if (Direction%2 == 0) //0 for horizontal or 1 for vertical
         {
           if (flag == 0)//move left or right
           {
              if ( CurrentPosition.X < width)
              {
                 CurrentPosition.X++;
              }
              else
              {
                  flag = 1;
                  CurrentPosition.X--;
              }
           }
           else
           {
               if ( CurrentPosition.X  > 2 )
               {
                  CurrentPosition.X--;
               }
               else
               {
                   flag = 0;
                   CurrentPosition.X++;
               }
           }
         }
         else
         {
           if (flag == 0) //move up or down
           {
              if ( CurrentPosition.Y < height)
              {
                 CurrentPosition.Y++;
              }
              else
              {
                  flag = 1;
                  CurrentPosition.Y--;
              }
           }
           else
           {
               if ( CurrentPosition.Y > 1)
               {
                  CurrentPosition.Y--;
               }
               else
               {
                   flag = 0;
                   CurrentPosition.Y++;
               }
           }
         }
         myfunc_gotoxy ( CurrentPosition.X, CurrentPosition.Y ); /* positions the cursor at given coordinates */
         myfunc_SetOutputColor ( 0, 10 );/*prints the text*/
         fputs ( Text, stdout );
         time1 = time2;
    }
    myfunc_gotoxy ( RestorePosition.X, RestorePosition.Y );//restores the cursor position
    return 0;
}

is there a function to wait for the given delay to expire or another activity and resume execution, so that it wouldn't have to keep looping just to check the given delay has passed.


Solution

  • You should do the following inside your loop:

    1. Measure Time
    2. Reprint the text
    3. Measure Time again and calculate difference to 1.
    4. Sleep(delay - difference);
    5. Start from 1. again