Rev 46 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/************************************************************************** Copyright (C) 1995 Embedded Solutions* All rights reserved** file: src\teamupd.c** purpose: Team data edit and display* This module contains all the functions required to define and* alter the team definitions** functions* team_update - Update team data on the screen* team_display - Display team data on the screen* leg_mods - Modify team leg times* d_display - Display all team information* d_leg - Display / Update leg time information* d_field - Display / Update field on the screen* g_tnum - Get a team number from the operator* g_record - Read a team record from disk* clr_team - Clear team data from file* put_team_record - Save team record to disk* init_team_data - Initialize the team data file* fix_team_data - Close team data file** programmer: David Purdie** revision date by reason* 00.0 27/01/95 DDP Tidies up the program and formatted the file***************************************************************************/#ifndef HI_TECH_C#include <fcntl.h>/*#include <memory.h> */#endif#include "consts.h"#include "structs.h"#include "proto.h"int team; /* Current team number */team_type team_buf; /* Holds team data currently under display */int team_fd; /* Team data file descriptor */int leg = 0; /* Leg under investigation *//*========================================================================** Update team data on the screen** Purpose:* This function is called to update team data on the screen* This function will prompt the operator to select a team number* If the team is defined then the data will be displayed on the screen** Parameters:* None** Returns:* TRUE - Change made**========================================================================*/void team_update(void){if( !g_tnum( 0, n_lines - 2, "Enter team number" ) )return; /* Exit operation *//*** Fetch the team record into memory** If the record does not exist a record with an invalid flag** will be returned*/do{clearscreen();g_record( team, &team_buf );d_display( M_TEAM );put_team_record( team, &team_buf );} while( g_tnum( 0, n_lines - 2, "Enter next team or RETURN to exit" ) );}/*=======================================================================** Display team data on the screen** Purpose:* This function is called to Display team data on the screen* This function will prompt the operator to select a team number* If the team is defined then the data will be displayed on the screen** Parameters:* None** Returns:* TRUE - Change made**========================================================================*/void team_display(void){if( !g_tnum( 0, n_lines - 2, "Enter team number" ) )return; /* Exit operation *//** Fetch the team record into memory* If the record does not exist a record with an invalid flag* will be returned*/do{clearscreen();if( g_record( team, &team_buf ) )d_display( M_DISPLAY );else{cur( 0, n_lines - 1 );printf( "Team %-1d has not yet been entered", team );beep();}} while( g_tnum( 0, n_lines - 2, "Enter next team or RETURN to exit" ) );}/*========================================================================** Modify team leg times** Purpose:* This function is called to modify team leg times* This function will prompt the operator to select a team number* If the team is defined then the data will be displayed on the screen** Parameters:* None** Returns:* TRUE - Change made**========================================================================*/void leg_mods(void){if( !g_tnum( 0, n_lines - 2, "Enter team number" ) )return; /* Exit operation *//*** Fetch the team record into memory** If the record does not exist a record with an invalid flag** will be returned*/do{clearscreen();if( g_record( team, &team_buf ) ){set_times( &team_buf );d_display( M_LEGS );put_team_record( team, &team_buf );}else{cur( 0, n_lines - 1 );printf( "Team %-1d has not yet been entered", team );beep();}} while( g_tnum( 0, n_lines - 2, "Enter next team or RETURN to exit" ) );}/*========================================================================** Display all team information** Purpose:* This function is called to display all the team information** Parameters:* operation Operation to perform** Returns:* Nothing**========================================================================*/void d_display( int operation ){int valid = team_buf.flags.valid;int opr;int i, j;int age_sum;/*** Refresh the entire display (using a recursive call)*/if( operation != M_DISPLAY )d_display( M_DISPLAY );/*** Display the team number** This cannot be edited.*/d_field( 0, 0, "Team number : ", D_NUMBER, 6, &team_buf.numb, TRUE,M_DISPLAY );/*** Determine the type of operation required** Update or Display*/opr = ( operation & M_TEAM ) ? M_UPDATE : M_DISPLAY;/*** Display / Update the team name*/do{d_field( 20, 0, "Team name : ", D_STRING, MAX_TM_NAME, team_buf.name,valid, opr );if( abort_flag )return;} while( ( opr == M_UPDATE ) && ( !strlen( team_buf.name ) ) );/*** Display / Update the class*/do{d_field( 0, 1, "Class : ", D_CLASS, 1, &team_buf.class, valid, opr );if( abort_flag )return;} while( ( opr == M_UPDATE ) && !team_buf.class );/*** The record is now active** It may not be usefull, but it has the start of a valid recird*/if( opr == M_UPDATE )team_buf.flags.valid = TRUE;/*** Display / Update the country name*/d_field( 30, 1, "Country :", D_COUNTRY, 4, &team_buf.country, valid,opr );if( abort_flag )return;/*** Display / Update the name and sex of each team member*/age_sum = 0;opr = ( operation & M_TEAM ) ? M_UPDATE : M_DISPLAY;for( i = 0; i < MAX_MEMB; i++ ){d_field( 0, 3 + i, "Name : ", D_STRING, MAX_PERSON_NAME,team_buf.members[i].name, valid, opr );if( abort_flag )return;d_field( MAX_PERSON_NAME + 10, 3 + i, "Sex : ", D_SEX, 0,&team_buf.members[i].sex, valid, opr );if( abort_flag )return;d_field( MAX_PERSON_NAME + 25, 3 + i, "Age : ", D_AGE, 3,&team_buf.members[i].age, valid, opr );if( abort_flag )return;/*** Sum ages** -1 indicates invalid age*/if ( age_sum >= 0 ){ushort age = team_buf.members[i].age;if ( age > 0 && age < 255 ){age_sum += age;}else{age_sum = -1;}}}/*** Display / Update the leg informarion for each configured leg*/for( j = 1; j <= config.num_legs; j++, i++ ){d_leg( 4 + i, j, &team_buf.leg[j], valid, operation );if( abort_flag ){i += config.num_legs - j + 1;break;}}/*** Display the summary information** For the team** Event and class placing information** Total age*/d_leg( 4 + i, 0, &team_buf.leg[0], valid, M_DISPLAY );d_field( 0, 6 + i, "Event placing : ", D_NUMBER, 1,&team_buf.leg[0].le_place, valid, M_DISPLAY );d_field( 20, 6 + i, "Class placing : ", D_NUMBER, 1,&team_buf.leg[0].lec_place, valid, M_DISPLAY );d_field( 40, 6 + i, "Total Age : ", D_STRING, 5,age_a(age_sum), valid, M_DISPLAY );if( team_buf.flags.non_equestrian )d_field( 0, 7 + i, "Non-Equestrian", D_NULL, 1, 0, valid, M_DISPLAY );else if( team_buf.flags.disqualified )d_field( 0, 7 + i, "Disqualified", D_NULL, 1, 0, valid, M_DISPLAY );}/*========================================================================** Display / Update leg time information** Purpose:* This function is called to display and update the leg* time information.** Parameters:* y Screen position* leg Leg to process* data Leg data* valid Data valid flag* operation Operation to perform** Returns:* Nothing**========================================================================*/void d_leg( int y, int leg, leg_type * data, int valid, int operation ){int i;int oprs, oprf;/*** Display the field header*/if( operation == M_DISPLAY ){if( leg != 0 ){d_field( 0, y, "Leg ", D_NUMBER, 1, &leg, TRUE, M_DISPLAY );d_field( 7, y, "", D_STRING, MAX_LEG_NAME,config.leg_name[leg - 1], TRUE, M_DISPLAY );}elsed_field( 0, y, "Overall team times", D_STRING, 0, "", TRUE,M_DISPLAY );}/*** If we are doing an update,. then ensure that all the team times** have been tested*/if( operation & M_ALL )test_times( &team_buf, 0 ); /* Set up all team times */oprs = ( ( parallel_legs )|| ( operation & M_ALEGS )|| ( operation & M_LEGS ) ) ? M_UPDATE : M_DISPLAY;oprf = ( operation & M_LEGS ) ? M_UPDATE : M_DISPLAY;/*** if start time edited then flag as manual entry** redo calculations and refresh screen with new information*/if( d_field( 25, y, data->manual ? "MS " : " S ", D_TIME, 8, &data->start, valid,oprs ) ){data->manual = TRUE;test_times( &team_buf, 0 );for( i = leg; i <= config.num_legs; i++ )d_leg( y + i - leg, i, &team_buf.leg[i], valid, M_DISPLAY );d_leg( y + i - leg, 0, &team_buf.leg[0], valid, M_DISPLAY );}/*** If time changed then redo calcs and refresh screen*/if( d_field( 37, y, "F ", D_TIME, 8, &data->end, valid, oprf ) ){set_times( &team_buf );test_times( &team_buf, 0 );for( i = leg; i <= config.num_legs; i++ )d_leg( y + i - leg, i, &team_buf.leg[i], valid, M_DISPLAY );d_leg( y + i - leg, 0, &team_buf.leg[0], valid, M_DISPLAY );}d_field( 48, y, "E ", D_TIME, 8, &data->elapsed, valid, M_DISPLAY );if( leg == 0 ){d_field( 60, y, "", D_STRING, 10,( team_buf.flags.bad_times ==TRUE ) ? "Incomplete" : " ", valid, M_DISPLAY );}else{d_field( 60, y, "", D_NUMBER, 4, &data->le_place, valid, M_DISPLAY );d_field( 65, y, "", D_NUMBER, 4, &data->l_place, valid, M_DISPLAY );d_field( 70, y, "", D_NUMBER, 4, &data->lec_place, valid, M_DISPLAY );d_field( 75, y, "", D_NUMBER, 4, &data->lc_place, valid, M_DISPLAY );}}/*========================================================================** Display / Update simple time information** Purpose:* This function is called to display and update the leg* time information.** Parameters:* x, y Screen position* prompt Prompt to display* data Address of time data* valid Data valid flag** Returns:* Nothing**========================================================================*/void d_time( int x, int y, char *prompt, time_t *data, int valid ){d_field( x, y, prompt, D_TIME, 8, ( char * ) data, valid, M_DISPLAY );d_field( x, y, prompt, D_TIME, 8, ( char * ) data, valid, M_UPDATE );}/*========================================================================** Display / Update field on the screen** Purpose:** This function is called to display and update a field on the screen* This routine will display a record from the team structure* The type of data and other parameters is passed in* This function is fundimental to the entire display subsystem**** Parameters:* x The screen col* y The line number* prompt The field lable* type type of field* length Length of the numeric field* data Pointer to the data* valid data field is valid* operation Operation type** Returns:* TRUE - Change has been made**========================================================================*/bool d_field( int x,int y,char *prompt,int type, int length, void *data, int valid, int operation ){time_t t;int i;sex_type s;int change = 0;int idata;/*** Position the cursor and display the field title*/cur( x, y );printf( "%s", prompt );/*** If the ABORT flag is set then DISPLAY the field*/if( abort_flag )operation = M_DISPLAY;/*** Display the current field value** Only if the data field is valid** Only if the M_DISPLAY operation is requested*/if( valid && ( operation == M_DISPLAY ) ){switch ( type ){case D_STRING:case D_USTRING:printf( "%-*.*s", length, length, (char *)data );break;case D_NUMBER:printf( "%-*d", length, *( short * ) data );break;case D_SEX:if( *( sex_type * ) data != unknown )printf( "%s",( *( sex_type * ) data ==male ) ? "Male" : "Female" );break;case D_TIME:printf( "%s", time_a( *( time_t * ) data ) );break;case D_CLASS:if( *( short * ) data > 0 ){printf( "%2.2s", config.team_class[( *( int * ) data ) - 1].abr );printf( " %-*.*s", LEN_CLASS_NAME, LEN_CLASS_NAME,config.team_class[( *( int * ) data ) - 1].full_name );}break;case D_COUNTRY:if( *( short * ) data > 0 ){printf( "%4.4s",config.country_name[( *( int * ) data ) - 1].abr );printf( " %-*.*s", LEN_CNTRY_NAME, LEN_CNTRY_NAME,config.country_name[( *( int * ) data ) -1].full_name );}break;case D_AGE:if( *( uchar * ) data > 0 ){printf( "%-*d", length, *( uchar * ) data );}break;case D_NULL:break;default:printf( "Unknown data type" );break;}}/*** If updating the field then extract the required information*/if( operation == M_UPDATE ){switch ( type ){case D_STRING:change = ( getstring( length, data, Alphanum ) );break;case D_USTRING:change = ( getstring( length, data, AlphnumUpper ) );break;case D_NUMBER:idata = *(short *)data;change = getnum( length, &idata );if ( change )*( short *)data = idata;break;case D_SEX:if( ( s = getsex() ) != unknown ){change = ( *( sex_type * ) data != s );*( sex_type * ) data = s;}break;case D_TIME:if( ( t = get_time(*( time_t * ) data) ) >= 0 ){change = ( *( time_t * ) data != t );*( time_t * ) data = t;}break;case D_CLASS:if( ( i = getclass() ) != 0 ){change = *( short * ) data != i;*( short * ) data = i;}break;case D_COUNTRY:if( ( i = getcountry() ) != 0 ){change = *( short * ) data != i;*( short * ) data = i;}break;case D_AGE:idata = *(uchar *)data;change = getnum( length, &idata );if ( change )*( uchar *)data = idata;break;case D_NULL:break;default:printf( "Unknown data type" );break;}/*** Having accepted the input now DISPLAY the data (once again)** Done to allow aborted field to re-display original values*/d_field( x, y, prompt, type, length, data, TRUE, M_DISPLAY );}return ( change );}/*========================================================================** Get a team number from the operator** Purpose:* This function is called to Get a team number from the operator* Prompt the operator for a team number* Verify that the team number is valid* Allow escape characters in the process** This routine will return TRUE if the team number is valid* The team number is returned in the global variable "team"** Parameters:* x,y Screen coords* prompt Operator prompt** Returns:* TRUE : Number OK**========================================================================*/bool g_tnum( int x, int y, char *prompt ){int new_team = 0; /* team number that will be input */while( TRUE ){team = 0;abort_flag = FALSE;cur( x, y );printf( "%s : ", prompt );console_clreol();if( !getnum( 6, &new_team ) )return ( FALSE ); /* No input *//** verify that the team number is within the allowed numbers*/if( !valid_field( new_team ) ){beep();printf( "\nTeam %-1d is not valid", new_team );continue;}team = new_team;return ( TRUE );}}/*========================================================================** Read a team record from disk** Purpose:* This function is called to Read a team record from disk* Locate the team record in the team data file* if the record does not exist create a blank record** The function will return FALSE if the record was not on disk* otherwise TRUE** Parameters:* int_team Team record required* data Area to return record** Returns:* FALSE : No data available**========================================================================*/bool g_record( int _team, team_type * data ){int len; /* length of record read in */long pos; /* File pointer */pos = _team;pos *= sizeof( team_type );len = lseek( team_fd, pos, 0 );len = read( team_fd, ( char * ) data, sizeof( team_type ) );if( ( len == sizeof( team_type ) ) && ( _team == data->numb ) )return ( data->flags.valid );else{clr_team( _team, data );return ( FALSE );}}/*========================================================================** Clear team data from file** Purpose:* This function is called to Clear team data from file* This routine will set the team data to INVALID** Parameters:* tm Team number* data Pointer to the data** Returns:* Nothing**========================================================================*/void clr_team( int tm, team_type * data ){int len;memset( ( char * ) data, 0, ( int ) sizeof( team_type ) );data->flags.valid = FALSE;data->flags.bad_times = TRUE;data->numb = tm;for( len = 0; len < MAX_LEGS + 1; len++ ){data->leg[len].start = -1;data->leg[len].end = -1;data->leg[len].elapsed = -1;data->leg[len].l_place = 0;data->leg[len].le_place = 0;data->leg[len].lec_place = 0;data->leg[len].lc_place = 0;data->leg[len].manual = 0;}}/*========================================================================** Save team record to disk** Purpose:* This function is called to save team record to disk** Parameters:* _team Team number* data Pointer to the data** Returns:* FALSE : Error in save**========================================================================*/bool put_team_record( int _team, team_type * data ){int len; /* length of record read in */long pos; /* file pointer */pos = _team;pos *= sizeof( team_type );lseek( team_fd, pos, 0 );len = write( team_fd, ( char * ) data, sizeof( team_type ) );if( len != sizeof( team_type ) ){perror( "Team record write" );sleep( 5 );}return ( len == sizeof( team_type ) );}/*========================================================================** Initialize the team data file** Purpose:* This function is called to Initialize the team data file and* prepare it for processing** Parameters:* None** Returns:* FALSE : Error encountered**========================================================================*/bool init_team_data(void){team_fd = open( datfile, OPEN_RW, 0 );if( team_fd < 0 ){/** file does not exist - create it*/printf( "The team data file does not exist.\n" );if( getyes( "Create the data file" ) ){team_fd = creat( datfile, 0664 );if( team_fd > 0 ){close( team_fd ); /* Close th file */team_fd = open( datfile, OPEN_RW, 644 );if( team_fd < 0 )perror( "Team datafile" );}}}return ( team_fd >= 0 );}/*========================================================================** Close team data file** Purpose:* This function is called to close the team data file** Parameters:* None** Returns:* Nothing**========================================================================*/void fix_team_data(void){if( team_fd > 0 )close( team_fd );}/********************************* EOF ***********************************/