/* ------------------------------------------------------------------------- */ /* */ /* evtimer.c - running event timer by JFB, 12/93 */ /* */ /* ------------------------------------------------------------------------- */ #include "evtimer.h" /* ------------------------------------------------------------------------- */ void main ( void ) { int maxrow, maxcol, tline, bline, choice, result; /* get the current video state and save for restore at the end */ if ( !chk_video_state ( &maxrow, &maxcol ) ) exit(3); get_cursor_size ( &tline, &bline ); set_cursor_size ( 0, 0 ); /* fill the screen with background chars */ qfill ( 1, 1, maxrow, maxcol, background_color, background_color, 176 ); /* look for the presence of a mouse on the system */ init_mouse(); /* initialize the top menu bar as defined in tmenu struct */ menuwnd = maketmenu ( &tmenu ); /* get the user selection of the top menu bar. Note: for some reason, */ /* deeply imbedded in the pcw tmenuinput function, the escape won't */ /* work as an exit signal. Neither will a control-C. */ choice = 0; while ( choice != 'Q' && choice != ESC ) { choice = tmenuinput ( &tmenu ); switch ( choice ) { /* select go to begin timing the event */ case 'G' : if ( mpresent ) hide_mouse(); whide ( menuwnd ); do_timing ( ); wshow ( menuwnd ); output_times(); if ( mpresent ) show_mouse(); break; /* select the file I/O options */ case 'F' : result = files_menu(); break; /* select from various optional functions */ case 'O' : result = options_menu(); if ( result == 1 ) { whide ( menuwnd ); do_timing ( ); wshow ( menuwnd ); output_times(); continue; } else { break; } /* select reset, erase window and begin data at 0 again */ case 'R' : qfill ( 4, 1, maxrow, maxcol, background_color, background_color, 176 ); strset ( data_buffer, '\0' ); count = 1; close_window ( mainwnd ); break; /* select the help text pop-up */ case 'H' : help_popup(); break; } } /* clear windows and reset cursor as it was upon entry */ set_cursor_size ( tline, bline ); close_window ( mainwnd ); close_window ( menuwnd ); if ( mpresent ) hide_mouse(); vcls(); exit(0); } /* ------------------------------------------------------------------------- */ /* */ /* do_timing - function which records the time at any key press and stuffs */ /* it into a data buffer for output to a file later. */ /* */ /* ------------------------------------------------------------------------- */ int do_timing ( void ) { int chk_keybd, result, chr_inp, done, current_row, current_col; char *this_time, *outbuf, *tmpbuf; /* make a big window for displaying the recorded times */ bordercolor ( border_color, background_color ); mainwnd = wframe ( 4, 1, 25, 80, border_color, background_color ); wtitle(mainwnd, TOP, CENTER, "press any key to record a time"); wtitle(mainwnd, BOTTOM, CENTER, "press esc, or q to quit"); /* initialize local vars */ done = 0; outbuf = " 000 0:00:00.00 "; tmpbuf = " "; current_row = 4; current_col = 3; /* get the number of clock ticks at the start */ initial_ticks = clock(); /* record time on every keystroke until a quit signal */ while ( !done ) { /* get the current no. of clock ticks and convert it to an */ /* elapsed time since the initial no. of ticks */ this_time = get_time(); /* check the input buffer for either a keyboard hit or mouse click */ chk_keybd = keypressed(); if ( chk_keybd == 2 ) { /* keyboard hit */ chr_inp = readkey(); result = chr_inp; } else { result = 0; } /* mouse clicks = 3 */ /* and no key pressed = 0 */ if ( chk_keybd != 0 ) { /* reset the text color of the previous line so that only the current */ /* time will appear highlighted */ if ( count != 1 ) qputs ( current_row, current_col, text_color, background_color, outbuf ); /* if the current row gets to the bottom of the screen, shift the */ /* cursor position to make another column. 4 columns of 20 lines */ /* can be displayed in this window. After that erase and start over */ current_row++; if ( current_row > 24 ) { current_row = 5; current_col = current_col + 18; } if ( current_col > 60 ) current_col = 3; /* when the page fills up, clear the window and go back to top-left */ if ( count > 79 && current_row == 5 && current_col == 3 ) qfill ( 5, 3, 24, 79, background_color, background_color, 176 ); sprintf ( outbuf, "%.2d %s", count, this_time ); /* put the recorded time in an output data buffer */ sprintf ( tmpbuf, "%.2d %s\n", count, this_time ); strcat ( data_buffer, tmpbuf ); /* put the recorded time on screen highlighted */ qputs ( current_row, current_col, highlight_color, background_color, outbuf ); /* quit recording times on ctrl-c, escape or Q */ if ( chr_inp == 3 || chr_inp == 27 || chr_inp == 81 || chr_inp == 113 ) done++; count++; } else { /* when not recording a time put the running time on top of screen */ qputs ( 2, CENTER, highlight_color, background_color, this_time ); } } return ( result ); /* more or less meaningless at this time */ } /* ------------------------------------------------------------------------- */ /* */ /* wait_for_keyin - sit in a tight loop and wait for the user to press a */ /* key or mouse button. Then return the key pressed as a result. */ /* */ /* ------------------------------------------------------------------------- */ int wait_for_keyin ( void ) { int chr_inp, done; /* sit here waiting for a key press or mouse button click */ for ( done = 0; !done; ) { if ( keypressed() ) { /* if any old key has been pressed, get it and return with it */ chr_inp = readkey(); done++; return ( chr_inp ); } if ( mpresent ) { /* if the mouse exists, watch for a right button pressed */ if ( get_mpressed ( RITEM ) ) { done++; return ( RITEM ); } /* if the mouse exists, watch for a left button pressed */ if ( get_mpressed ( LEFTM ) ) { done++; return ( LEFTM ); } } } } /* ------------------------------------------------------------------------- */ /* */ /* output_times - take the event times which were recorded in the do_timing */ /* function and stashed in a data buffer and write them out to a data file. */ /* */ /* ------------------------------------------------------------------------- */ int output_times( void ) { WNDPTR *wnd; FILE *outfile; int chr_inp, result; char *tmptxt[2] = { " Writing recorded times to output file", NULL }; char *errtxt[2] = { " Error opening output file", NULL }; /* pop up a small message window saying file IO is going on */ /* it's usually so quick this is probably useless */ bordercolor ( background_color, border_color ); wnd = wframe ( 4, 19, 6, 60, background_color, border_color ); w_block_write ( wnd, 1, 1, tmptxt ); /* open the output data file */ outfile = fopen ( filename, "w" ); /* display warning message if file not opened properly */ if ( !outfile ) { w_block_write ( wnd, 1, 1, errtxt ); wtitle(wnd, BOTTOM, RITE, " ... press any key to continue "); chr_inp = wait_for_keyin(); result = chr_inp; if ( chr_inp == 3 ) exit(3); } /* dump the whole output data buffer as is into the file */ fprintf ( outfile, "%s", data_buffer ); fclose ( outfile ); close_window ( wnd ); return ( result ); } /* ------------------------------------------------------------------------- */ /* */ /* help_popup - display a page of help text at the top menu view. */ /* */ /* ------------------------------------------------------------------------- */ void help_popup() { WNDPTR *wnd; char *hlptxt[15] = { " To start the stopwatch use the arrow keys or mouse to ", " select the menu option. Press enter or mouse button to take", " the appropriate action. ", " To record the event time thereafter type any key EXCEPT ", " Q or ESC. The esc or Q keys will terminate time recording ", " and output the recorded times to a file. ", " ", " Program Options: ", " Count-Up : begin the event recording after a specified", " time delay. Counting is displayed on screen", " Count-Down : begin the event recording after a specified", " time delay but count in reverse. ", " Begin at : begin the event recording immediately but ", " start at a time other than zero. ", NULL }; /* make a pop-up window to overlay the main view */ bordercolor ( background_color, border_color ); wnd = wframe ( 6, 9, 22, 71, background_color, border_color ); wtitle ( wnd, BOTTOM, RITE, " ... press any key to continue " ); w_block_write ( wnd, 1, 1, hlptxt ); /* sit here and wait for a key press before continuing */ wait_for_keyin(); close_window ( wnd ); } /* ------------------------------------------------------------------------- */ /* */ /* get_time - function which reads the system clock and returns the time */ /* string for the current time from the start of the event recording process */ /* */ /* ------------------------------------------------------------------------- */ char *get_time() { clock_t clock_ticks; int hours, minutes, seconds, fraction, total_time, offset, hr, mn, sc; float frac; long t_diff; char *time_out; time_out = " 0:00:00.00 "; sscanf ( start_time, "%d:%d:%d", &hr, &mn, &sc ); offset = sc + ( mn * 60 ) + ( hr * 3600 ); /* get the total number of clock ticks since program start */ clock_ticks = clock(); /* calc. the difference between time on entry and now */ t_diff = clock_ticks - initial_ticks; total_time = ( t_diff / CLK_TCK ) + offset; /* convert the ticks number to clock time hr:min:sec.millisec */ hours = total_time / 3600; minutes = total_time / 60 - ( hours * 60 ); seconds = total_time - ( minutes * 60 ) - ( hours * 3600 ); frac = (float)(t_diff/CLK_TCK) - (int)(t_diff/CLK_TCK); fraction = (int)(frac * 100); /* stuff the parts of time into a data string to return */ sprintf ( time_out, "%d:%.2d:%.2d.%.2d", hours, minutes, seconds, fraction ); return ( time_out ); } /* ------------------------------------------------------------------------- */ /* */ /* options_menu - displays a pulldown meny of optional program functions. */ /* such as count-up, count-down,... */ /* */ /* ------------------------------------------------------------------------- */ int options_menu ( void ) { WNDPTR *wnd; int cmd, result; int i = 0; wnd = makepmenu ( &optmenu ); result = 0; while ( i != 'Q' && i != ESC ) { i = pmenuinput ( &optmenu ); switch ( i ) { case 'U': set_start_time(); count_up ( ); result = 1; i = 'Q'; continue; case 'D': set_start_time(); count_down(); result = 1; i = 'Q'; continue; case 'B': set_start_time(); result = 1; i = 'Q'; continue; case 'Q': continue; } if ( i == 'Q' || i == ESC ) result = 0; } close_window ( wnd ); return(result); } /* ------------------------------------------------------------------------- */ /* */ /* set_start_time - function which asks the user to set a time delay for */ /* a count_up or count_down or a beginning time of the event recording. */ /* */ /* ------------------------------------------------------------------------- */ int set_start_time ( void ) { WNDPTR *wnd; char *inp = " "; int result, hr, mn, sc, tmp1, tmp2; char *inptxt[2] = { " Enter start time (hr:mn:sc) => ", NULL }; if ( mpresent ) hide_mouse(); bordercolor ( background_color, border_color ); wnd = wframe ( 11, 10, 13, 53, background_color, border_color ); w_block_write ( wnd, 1, 1, inptxt ); /* not a very sophisticated input scheme, but it'll do for now */ result = get_chars ( 12, 43, border_color, background_color, 7, inp ); sscanf ( inp, "%d:%d:%d", &hr, &mn, &sc ); if ( sc >= 60 ) { tmp1 = sc - 60; tmp2 = mn + 1; sc = tmp1; mn = tmp2; } if ( mn >= 60 ) { tmp1 = mn - 60; tmp2 = hr + 1; mn = tmp1; hr = tmp2; } sprintf ( start_time, "%d:%.2d:%.2d", hr, mn, sc ); close_window ( wnd ); return ( result ); } /* ------------------------------------------------------------------------- */ /* */ /* count_up - takes the user specified time and counts up to it before */ /* starting the event recording process. */ /* */ /* ------------------------------------------------------------------------- */ void count_up ( void ) { int hr, mn, sc; char *count_time, *outmsg; clock_t time1, time2, tdiff, tprev; hr = 0; mn = 0; sc = 0 ; count_time = "0:00:00"; tdiff = 0; tprev = 0; outmsg = " "; strcpy ( outmsg, "Counting up to: " ); strcat ( outmsg, start_time ); qputs ( 11, CENTER, highlight_color, background_color, outmsg ); time1 = clock(); while ( strcmp(count_time, start_time) != 0 ) { while ( (tdiff - tprev) < 1 ) { time2 = clock(); tdiff = ( time2 - time1 ) / CLK_TCK; } tprev = tdiff; tdiff = 0; sc++; if ( sc > 59 ) { sc = 0; mn++; } if ( mn > 59 ) { mn = 0; hr++; } sprintf ( count_time, "%d:%.2d:%.2d", hr, mn, sc ); qputs ( 13, CENTER, highlight_color, background_color, count_time ); } start_time = "0:00:00"; /* erase the stuff */ qputs ( 11, CENTER, background_color, background_color, outmsg ); qputs ( 13, CENTER, background_color, background_color, count_time ); } /* ------------------------------------------------------------------------- */ /* */ /* count_down - takes the user specified time and counts down to zero before */ /* starting the event recording process. */ /* */ /* ------------------------------------------------------------------------- */ void count_down ( void ) { int hr, mn, sc, seconds; char *count_time, *outmsg; clock_t time1, time2, tdiff, tprev; sscanf ( start_time, "%d:%d:%d", &hr, &mn, &sc ); if ( sc == 60 ) { sc = 0; mn++; } if ( mn == 60 ) { mn = 0; hr++; } seconds = sc + ( mn * 60 ) + ( hr * 3600 ); count_time = "0:00:00"; outmsg = " "; strcpy ( outmsg, "Counting down from: " ); strcat ( outmsg, start_time ); qputs ( 11, CENTER, highlight_color, background_color, outmsg ); tdiff = 0; tprev = 0; time1 = clock(); while ( strcmp(count_time, start_time) != 0 ) { while ( (tdiff - tprev) < 1 ) { time2 = clock(); tdiff = ( time2 - time1 ) / CLK_TCK; } tprev = tdiff; tdiff = 0; seconds--; hr = seconds / 3600; mn = ( seconds / 60 ) - ( hr * 60 ); sc = seconds - ( mn * 60 ) - ( hr * 60 ); sprintf ( start_time, "%d:%.2d:%.2d", hr, mn, sc ); qputs ( 13, CENTER, highlight_color, background_color, start_time ); } /* erase the stuff */ qputs ( 11, CENTER, background_color, background_color, outmsg ); qputs ( 13, CENTER, background_color, background_color, start_time ); } /* ------------------------------------------------------------------------- */ /* */ /* files_menu - displays a pulldown menu of file manipulation options */ /* */ /* ------------------------------------------------------------------------- */ int files_menu ( void ) { WNDPTR *wnd; int cmd, result; int i = 0; wnd = makepmenu ( &filesmenu ); while ( i != 'Q' && i != ESC ) { i = pmenuinput ( &filesmenu ); switch(i) { case 'N': result = new_file(); i = 'Q'; break; case 'S': output_times(); i = 'Q'; break; case 'D': result = do_dir (); break; case 'Q': continue; } if ( i == 'Q' || i == ESC ) result = 0; } close_window ( wnd ); return ( result ); } /* ------------------------------------------------------------------------- */ /* */ /* do_dir - do a file listing of the current directory in an on-screen */ /* pop-up window. */ /* */ /* ------------------------------------------------------------------------- */ int do_dir ( void ) { WNDPTR *wnd; if( mpresent) hide_mouse(); bordercolor ( border_color, background_color ); wnd = wframe ( 1, 20, 25, 62, text_color, background_color ); wtitle ( wnd, BOTTOM, RITE, " Current Directory " ); set_int29(); system ( "dir /p" ); puts ( " ... press any key to return ... " ); reset_int29(); wait_for_keyin(); close_window ( wnd ); return(0); } /* ------------------------------------------------------------------------- */ /* */ /* new_file - ask the user to specify a new file name for timing data output */ /* */ /* ------------------------------------------------------------------------- */ int new_file ( void ) { WNDPTR *wnd; char *inp = " "; int i, result; char *inptxt[2] = { " Enter new file name => ", NULL }; if ( mpresent ) hide_mouse(); bordercolor ( background_color, border_color ); wnd = wframe ( 5, 21, 7, 60, background_color, border_color ); w_block_write ( wnd, 1, 1, inptxt ); i = get_chars ( 6, 47, border_color, background_color, 12, inp ); result = i; filename = inp; close_window ( wnd ); return ( result ); } /* ------------------------------------------------------------------------- */ /* */ /* close_window - to be consistent in how windows are destroyed without */ /* leavin little mouse marks and stuff on screen */ /* */ /* ------------------------------------------------------------------------- */ void close_window ( wnd ) WNDPTR *wnd; { if ( mpresent ) hide_mouse(); wpop ( wnd ); if ( mpresent ) show_mouse(); }