Thread: Some bottleneck in coding digital watch simulator

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    51

    Some bottleneck in coding digital watch simulator

    I felt like the cloacking() function have a lot of bugs.
    And sometimes when i ran some program like (Azurues, MyIE2) minute in my program gone crazy(changing very fast)...

    Please give some advised, ccommnet (good or bad will be accepted).

    Code:
    /*
    Title: Digital Watch Simulator
    Author: megablue
    Compiled in : VC++ 6
    */
    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
    #include <sys/timeb.h>
    
    void gotoxy();//Move Cursor To Selected X,Y Point
    void draw_seconds(); //Redraw The Area of Displaying Seconds
    void draw_ss(); //Redraw The Area of displaying seconds/100
    void draw_minute(); //Redraw the area of displaying minute
    void draw_hours(); //Redraw the area of displaying hour
    long calibrate();//Calibrate The Time
    long stopwatch();//Stopwatch mode
    long clocking();//Internal Cloaking Function
    long set_alarm();//Set Alarm on/off
    long alarm();//Alarm function
    long mode();//mode switch
    void backlight();//backlight display mode
    void Initializer();//redraw the whole displaying area
    
    /*
    Task: Move The Cursor To Selected X,Y Point
    */
    void gotoxy(int x, int y)
    {
      COORD coord;//coordinate
      coord.X = x;//X
      coord.Y = y;//Y
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);//set coordinate
    }
    /*
    Task: Redraw The Area of Displaying Second/100
    */
    void draw_ss(int per100)
    {
    	gotoxy(10,1);
    	printf("%2.2d ",per100); 
    }
    
    /*
    Task: Redraw The Area of Displaying Seconds
    */
    void draw_seconds(int sec)
    {
    	gotoxy(7,1);
    	printf("%2.2d:",sec); 
    }
    
    /*
    Task: Redraw The Area of Displaying Minute
    */
    void draw_minute(int min)
    {
    	gotoxy(4,1);
    	printf("%2.2d:",min);
    }
    
    /*
    Task: Redraw The Area of Displaying hour
    Accept Value
    */
    void draw_hours(int hr, int ch)
    {
    	gotoxy(1,1);
    	if(ch==1 && hr==0)
    		hr=12;
    	printf("%2d:",hr);
    
    	gotoxy(17,1);
    
    /* MODE */
    	if(ch==1)
    		printf("AM");
    	else if(ch==2)
    		printf("PM");
    	else if(ch==3)
    		printf("              \n[STOPWATCH MODE]");
    	else if(ch==4)
    		printf("\n[CALIBRATE MODE]");
    	else if(ch==5)
    		printf("\n[SET ALARM MODE]");
    }
    
    long calibrate(int *min, int *hour,int *changed)
    {
    	int idle_sec=0,exit=0,i_h=0,i_m=0,i_s=0,i_ss=0,
    		input,next_value=0,next_unit=0,
    		focus=1,blink_time=1;
    
    	Initializer(*hour,*min,0,0,0); // Update Screen
    	draw_hours(*hour,4);//Display Current Mode Title
    
    	while(!exit)
    	{
    		input='\0';
    		while (kbhit())// Empties buffer
    			input=getch();   
    
    		switch(input)
    		{
    			case '9': // NEXT VALUE
    				next_value=1;
    				*changed=1;
    				break;
    			case '3': // NEXT UNIT
    				next_unit=1;
    				break;
    			case '1': // NEXT MODE
    				exit=1;
    				break;
    		}
    
    		if(next_value)
    		{
    			if(focus==1)
    			{
    				++*hour;
    				if(*hour==24)
    					*hour=0;
    			}
    			else
    			{
    				++*min;
    				if(*min==60)
    					*min=0;
    			}
    
    			next_value=0;
    		}
    		else if(next_unit)
    		{
    			focus++;
    			if(focus>2)
    				focus=1;
    			next_unit=0;
    		}
    		
    
    		if(blink_time%2)
    			Initializer(*hour,*min,0,0,0);
    		else
    		{
    			if( focus==1 )
    				gotoxy(1,1); //Goto Area Of Drawing Hours
    			else
    				gotoxy(4,1); //Goto Area Of Drawing Minutes
    			printf("  :");
    		}
    
    
    		blink_time=idle_sec+=clocking(&i_ss, &i_s, &i_m, &i_h, 0, 0, 2);
    	}
    
    	if(!changed)
    	return idle_sec;
    	else
    		return 0;
    }
    
    long mode(long *resync,int *min, int *hour,long *timeset)
    {
    	long sec_used=0;
    	int changed=0;
    	sec_used+=stopwatch(&(*resync),&changed);
    
    	if(!changed)
    		sec_used+=calibrate(&(*min), &(*hour), &changed);
    	if(!changed)
    		sec_used+=set_alarm(&(*timeset));
    
    	return sec_used;
    }
    
    long alarm(long target_time, int *msec, int *sec,int *min, int *hour)
    {
    	long counter=0,current_time=0;
    	int alarm=0,a=0,b=0,c=0,d=0,input=0;
    	static alarm_pressed=0;
    
    	current_time= *hour *3600 + *min * 60 + *sec;
    	if(target_time!=-1)
    	{
    		if(current_time >= target_time && current_time <= target_time + 30 || current_time >= target_time+90 && current_time <= target_time+120)
    		{
    			while(counter<2)
    			{
    				if(!alarm && !alarm_pressed)
    				printf("\a");
    				alarm=1;
    				counter+=clocking(&(*msec),&(*sec),&(*min),&(*hour), 1, 0, 0);
    			}
    			while (kbhit())
    				input=getch();   // Empties buffer
    			if(input=='9' || input== '3') // Pressed START / RESET Button to pause alarm
    				alarm_pressed=1;
    		}
    		else
    			alarm_pressed=0;
    		return counter;
    	}
    	return 0;
    }
    
    long set_alarm(long *timeset)
    {
    	int a_hour=0,a_min=0,a_sec=0,a_ss=0
    		,exit=0,next_value=0,next_unit=0,
    		focus=1,blink_time=0,input,
    		i_ss=0,i_s=0,i_m=0,i_h=0;
    	long idle_sec=0;
    
    	if(*timeset!=-1)
    	{
    		a_min = *timeset /60;
    		*timeset = *timeset/60 + *timeset % 60;
    		a_hour = *timeset /60;
    		a_sec = *timeset % 60;
    	}
    
    	Initializer(a_hour,a_min,0,0,0); // Update Screen
    	draw_hours(a_hour,5);//Display Current Mode Title
    
    	while(!exit)
    	{
    		
    		input='\0';
    		while (kbhit())// Empties buffer
    			input=getch();   
    
    		switch(input)
    		{
    			case '9': // NEXT VALUE
    				next_value=1;
    				*timeset=0;
    				break;
    			case '3': // NEXT UNIT
    				next_unit=1;
    				break;
    			case '1': // NEXT MODE
    				exit=1;
    				break;
    		}
    
    		if(next_value)
    		{
    			if(focus==1)
    			{
    				++a_hour;
    				if(a_hour==24)
    					a_hour=0;
    			}
    			else if(focus==2)
    			{
    				++a_min;
    				if(a_min==60)
    					a_min=0;
    			}
    			*timeset=0;
    			next_value=0;
    		}
    		else if(next_unit)
    		{
    			focus++;
    			if(focus>3) //If focus more than 3 return to 1
    				focus=1;
    			else if(focus==3) // If focus is 3 Turn off Alarm
    			{
    				*timeset=-1;
    				a_hour=0;
    				a_min=0;
    			}
    			if(focus>0 && focus<3)
    				*timeset=0;
    			next_unit=0;
    		}
    		
    
    		if(blink_time%2)
    			Initializer(a_hour,a_min,0,0,0);
    		else
    		{
    			if( focus==1 || focus==3)
    			{
    				gotoxy(1,1); //Goto Area Of Drawing Hours
    				if(*timeset==-1)
    				printf(" ALARM: OFF");
    			}
    			else
    				gotoxy(4,1); //Goto Area Of Drawing Minutes
    			printf("  ");
    		}
    
    		blink_time=idle_sec+=clocking(&i_ss, &i_s, &i_m, &i_h, 0, 0, 2);
    	}
    	if(*timeset!=-1)
    		*timeset+=a_hour*3600 + a_min*60;
    
    	return idle_sec;
    }
    
    long stopwatch(long *resync, int *changed)
    {
    	long sec_used=0;
    	int exit=0,reset=0,input,idle_hsec=0,idle_sec=0,idle_min=0,idle_hour=0;
    	static int start=0, w_hsec=0,w_sec=0,w_min=0,w_hour=0;
    	
    	Initializer(w_hour, w_min, w_sec, w_hsec, 2);
    	while(!exit)
    	{
    		input='\0';
    		while (kbhit())
    			input=getch();   // Empties buffer
    
    		switch(input)
    		{
    			case '9': // START / STOP
    				putchar('\a');
    				if(!start)
    					start=1;
    				else
    					start=0;
    				*changed=1;
    				break;
    			case '3': // RESET
    				putchar('\a');
    				if(!reset)
    					reset=1;
    				else
    					reset=0;
    				*changed=1;
    				break;
    			case '1': // NEXT MODE
    				exit=1;
    				break;
    		}
    		if(!start && reset)
    		{
    			w_hsec=0;
    			w_sec=0;
    			w_min=0;
    			w_hour=0;
    			reset=0;
    			Initializer(w_hsec, w_hsec, w_hsec, w_hsec);
    		}
    
    		if(reset)
    		{
    			start=0;
    			reset=0;
    		}
    
    		if(start)
    			sec_used+=clocking(&w_hsec, &w_sec, &w_min, &w_hour, 1, *resync, 2 );
    		else
    			sec_used+=clocking(&idle_hsec, &idle_sec, &idle_min, &idle_hour, 0, 0, 2);
    
    		*resync=0; //Reset after synchornized
    	}
    	return sec_used;
    }
    
    void backlight()
    {
    }
    
    long clocking(int *msec, int *sec, int *min, int *hour, int showtimer, long sync_time, int mode)
    {
    	int sync_sec=0,sync_hour=0,sync_min=0,idle_sec=0;
    	struct _timeb tstruct;
    
    	_ftime( &tstruct ); //Get time from system clock
    	*msec=tstruct.millitm; //assign miliseconds
    	*msec+=16; //Milliseconds Fine Tune
    	_sleep(1); //Limit the looping speed by idle for 1ms
    	if(showtimer)
    	draw_ss((int)((double)*msec/1000 * 100)%100);
    
    /* 
    	System Clock Genarator (second)
    	time( &sec );
    	sec%=60;
    */
    	
    	if(sync_time>0) //Format Idle Time
    	{
    		*min+=sync_min= sync_time /60;
    		sync_time = sync_time/60 + sync_time % 60;
    		*hour+=sync_hour= sync_time/60;
    		*sec+=sync_sec= sync_time % 60;
    	}
    if(*msec>999)
    {
    	*sec+=(sync_sec+1);
    	++idle_sec;
    	if(*sec>=60)
    	{
    		*min+=(sync_min+1);
    		*sec-=60;
    		if(showtimer)
    		{
    			draw_seconds(*sec);
    			draw_minute(*min);
    		}
    		
    		if(*min>=60)
    		{
    			*min-=60;
    			*hour+=(sync_hour+1);
    
    			if(mode==1 || mode==0) // Mode 1 is international time, Mode 2 is Sport Mode
    				if(*hour>=24)
    					*hour-=24;
    
    			if(showtimer)
    			{
    				draw_minute(*min);
    
    				if(mode==0)// Mode 0 is AM / PM Format
    				{
    					if(*hour <12)
    						draw_hours(*hour,1);
    					else if(*hour==12)
    						draw_hours(*hour,2);
    					else if(*hour>12)
    						draw_hours(*hour-12,2);
    				}
    				else if(mode==2)
    					draw_hours(*hour, 3);
    				else
    					draw_hours(*hour, 0);
    			}
    		}
    	}
    }
    if(showtimer)
    	draw_seconds(*sec);
    
    	return idle_sec;
    }
    
    void Initializer(int h,int m,int s,int ss,int mode)
    {
    	if(mode==1 && h>=24) // Mode 1 is international time, Mode 2 is Sport Mode
    			h-=24;
    	else
    	if(mode==0)// Mode 0 is AM / PM Format
    	{
    		if(h <12)
    			draw_hours(h,1);
    		else if(h==12)
    			draw_hours(h,2);
    		else if(h>12)
    			draw_hours(h-12,2);
    	}
    	else if(mode==2)
    		draw_hours(h, 3);
    	else
    		draw_hours(h, 0);
    
    	draw_minute(m);
    	draw_seconds(s);
    	draw_ss(ss);
    }
    
    int main(void)
    {
    	char input;
    	int msec=0,sec=0,min=0,hour=0,exit=0,loop=0;
    	long sync_sec=0,idle=0,timeset=-1;
    
    	printf("\t\t\tDigital Watch Simulator\n");
    	Initializer(hour,min,sec,msec, 0);
    	while(!exit)
    	{
    		loop++;
    		printf("\n\n\n\n\n\n\t This Program has performed %d loops", loo); 
    		gotoxy(17,1);
    		printf("\n                   ");
    		input='\0';
    
    		while (kbhit())
    			input=getch();   // Empties buffer
    
    		switch(input)
    		{
    		case '1':
    			sync_sec+=mode(&idle,&min,&hour,&timeset); // MODE return Seconds Need To be Resync
    			break;
    		case '7':
    		//	sync_sec+=backlight();
    			break;
    		case 'q':
    		//	sync_sec+=quit(&exit);
    			break;
    		default:
    			;
    		}
    		idle+=clocking(&msec,&sec,&min,&hour, 1, sync_sec, 0);
    		sync_sec=0;
    		alarm(timeset, &msec,&sec,&min,&hour); // alarm check
    		Initializer(hour,min,sec,(int)((double)msec/1000 * 100)%100, 0);
    		sync_sec=0;
    	}
    	return 0;
    }

  2. #2
    Im a Capricorn vsriharsha's Avatar
    Join Date
    Feb 2002
    Posts
    192
    In your main program, what are you trying to achieve by
    Code:
    while(kbhit())
         input = getch();
    Change it to:
    Code:
    while(!kbhit());
    input = getch();
    That was what I did whenever I wanted to wait for the input from user and whenever he hits a key, I get its value in the variable 'input'.

    -Harsha
    Help everyone you can

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    That sure seems like a lot of work. Maybe something like this would be a better foundation to build on than what you have.
    Code:
    /*
     * Digital Clock by Julienne Guth
     *
     * Created (8/28/2004)
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    
    #define DISPLAY_LENGTH 11 /* dd:dd:ddxx\0 */
    #define DIGIT_HEIGHT 9
    #define DIGIT_WIDTH 5
    
    void clear ( void )
    {
      system ( "cls" );
    }
    
    void sleep ( long milli )
    {
      Sleep ( milli );
    }
    
    char *get_time ( char *buffer, size_t size )
    {
      struct tm *split;
      time_t now;
    
      if ( ( now = time ( NULL ) ) == (time_t)-1 )
        return NULL;
    
      if ( ( split = localtime ( &now ) ) == NULL )
        return NULL;
    
      if ( strftime ( buffer, size, "%I:%M:%S%p", split ) == 0 )
        return NULL;
    
      return buffer;
    }
    
    int digital_display ( char *now,
                          const char digit[10][DIGIT_HEIGHT][DIGIT_WIDTH],
                          const char *sep,
                          FILE *out )
    {
      char *p;
      int i, row, col;
      int am;
    
      /* Get AM/PM designation (formatting assumption) */
      am = now[DISPLAY_LENGTH - 3] == 'A' ? 1 : 0;
    
      /* Display the current time with digital digits */
      for ( row = 0; row < DIGIT_HEIGHT; row++ ) {
        for ( p = now; !isalpha ( (unsigned char)*p ); p++ ) {
          if ( *p == ':' ) {
            fputc ( sep[row], out );
            fputc ( ' ', out );
          }
          else {
            col = 0;
            for ( i = 0; i < DIGIT_WIDTH; i++ )
              fputc ( digit[*p - '0'][row][col++], out );
            fputc ( ' ', out );
          }
        }
    
        fputc ( '\n', stdout );
      }
    
      /* Print AM/PM designation */
      if ( am )
        printf ( "AM *\n\nPM\n" );
      else
        printf ( "AM\n\nPM *\n" );
    
      return 1;
    }
    
    int main ( void )
    {
      char colon[] = "  *   *  ";
      char digit[10][DIGIT_HEIGHT][DIGIT_WIDTH];
      char *p = &digit[0][0][0];
      int ch;
      FILE *in = fopen ( "digits.txt", "r" );
    
      if ( in == NULL )
        return EXIT_FAILURE;
    
      /* Gather digit information */
      while ( ( ch = fgetc ( in ) ) != EOF ) {
        if ( ch != '\n' )
          *p++ = (char)ch;
      }
    
      fclose ( in );
    
      /* Display time infinitely */
      for ( ; ; ) {
        char current[DISPLAY_LENGTH];
    
        if ( get_time ( current, DISPLAY_LENGTH ) == NULL )
          break;
    
        if ( !digital_display ( current, digit, colon, stdout ) )
          break;
    
        sleep ( 1000 );
        clear();
      }
    
      return EXIT_SUCCESS;
    }
    My best code is written with the delete key.

  4. #4
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Wooohooo!!!! She's back!
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    51
    actually what i was trying to understand how the _sleep() function works.... and i'm glad that someone shown me a great example but i not really understand what is the information the program gather from file.

  6. #6
    Registered User
    Join Date
    Jun 2003
    Posts
    51
    Code:
    while(!kbhit());
    input = getch();
    And why should i change to this one?

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >i not really understand what is the information the program gather from file.
    It saved me the trouble of hardcoding all of the digits. Here is the file:
    Code:
     *** 
    *   *
    *   *
    *   *
    *   *
    *   *
    *   *
    *   *
     *** 
        *
        *
        *
        *
        *
        *
        *
        *
        *
     *** 
        *
        *
        *
     *** 
    *    
    *    
    *    
     *** 
     *** 
        *
        *
        *
     *** 
        *
        *
        *
     *** 
    *   *
    *   *
    *   *
    *   *
     *** 
        *
        *
        *
        *
     *** 
    *    
    *    
    *    
     *** 
        *
        *
        *
     *** 
     *** 
    *    
    *    
    *    
     *** 
    *   *
    *   *
    *   *
     *** 
     *** 
        *
        *
        *
        *
        *
        *
        *
        *
     *** 
    *   *
    *   *
    *   *
     *** 
    *   *
    *   *
    *   *
     *** 
     *** 
    *   *
    *   *
    *   *
     *** 
        *
        *
        *
        *
    >And why should i change to this one?
    It depends on what you want to do. If your code and your comment match then you don't want to change; your code does what you want it to. On the other hand, if you want to wait until the user presses a key and then read it, vsriharsha's correction is what you want.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. digital simulator
    By fuzon87 in forum C Programming
    Replies: 1
    Last Post: 03-29-2008, 01:06 PM