#include #include #include #include #include #include #include #include #include // Parallel port address for LPT1 #define DATA 0x378 // DATA bits used, D0,1 through D5,32 for tracks // For now, track 1..4 are only used (they're really 2..5 and 0 & 6 ignored. #define PP_TRACK_1 2 #define PP_TRACK_2 4 #define PP_TRACK_3 8 #define PP_TRACK_4 16 #define MAX_CARS 20 #define CTRACKS 4 // display info #define TRACK_COL_START 31 #define PLACE_COL_START 37 #define PLACE_ROW 0 #define CAR_NUM_ROW 1 #define TIME_ROW 2 #define AVGMPH_ROW 3 #define MPH_ROW 4 #define LANE_NUMBER_ROW 5 #define SEVEN_SEG_HEIGHT 6 #define SEVEN_SEG_WIDTH 6 #define SEVEN_SEG_ROW_START 1 #define SEVEN_SEG_ROW_STOP 6 #define STATUS_ROW 25 #define HEAT_COL_OFFSET (TRACK_COL_START+23) #define HEAT_COL_NUMOFFSET (TRACK_COL_START+23+5) #define HEAT_COL_STATUSOFFSET (TRACK_COL_START+23+5+4) #define TRACK_ROW_1 7 #define TRACK_ROW_2 8 #define TRACK_ROW_3 9 #define TRACK_ROW_4 10 #define CAR_TRACK 1 #define CAR_NUMBER 2 #define TRACK_NUM_WIDTH 3 #define TRACK_1 (TRACK_NUM_WIDTH+1) #define TRACK_2 (TRACK_1+TRACK_NUM_WIDTH) #define TRACK_3 (TRACK_2+TRACK_NUM_WIDTH) #define TRACK_4 (TRACK_3+TRACK_NUM_WIDTH) #define TRACK_SUM (TRACK_4+TRACK_NUM_WIDTH) #define STATUS_INPUT_LINE 25 #define GOTO_ROW_COL(r,c) printf( "\033[%d;%dH", r, c ) #define GOTO_ROW(r) printf( "\033[%dH", r ) #define SET_FOREGROUND_BACKGROUND(f,b) printf( "\033[1;%d;%dm", f, b ) #define CLS() fputs( "\033[2J", stdout ) // Columns where data is shown on the screen #define TIME_OFFSET_COL (7+PLACE_COL_START) #define MPH_OFFSET_COL (7+PLACE_COL_START) #define AVGMPH_OFFSET_COL (7+PLACE_COL_START) #define MPH_COL 25 #define MPH_AVG_COL 33 #define STATUS DATA+1 // The two status inputs used for pushbutton 1 and pushbutton 2 // 0 means pushed 1 means not pushed. #define PB_2 32 #define PB_1 128 #define CONTROL DATA+2 // READ/WRITE bit for setting parallel port data to read(able) #define CONTROL_RW 32 #define BOTH_BUTTONS_PUSHED(buttons) ((buttons&(PB_2|PB_1))==0) #define BUTTON_1_PUSHED(buttons) ((buttons&PB_1)==0) #define TRACK_LENGTH (31*12+3) // Based on a 7" car vs a 186" car, in thousandths of a mph. // 186"*10^6usec*3600sec*1ft*1mi / 1car*1sec*1hr*12"*5280ft then *1000 to // get thousandths of mph #define USEC_TO_MPH_SCALE(u) (10568182182/u) // avg speed depends on how many 7" car lengths are in the track len so //#define USEC_TO_AVG_MPH_SCALE(u) (10568182182/(u/(TRACK_LENGTH/7))) #define USEC_TO_AVG_MPH_SCALE(u) ((TRACK_LENGTH*10568182182/u)/7) //#define USEC_TO_AVG_MPH_SCALE_4_RUNS(u) (10568182182/((u/4)/(TRACK_LENGTH/7))) #define USEC_TO_AVG_MPH_SCALE_4_RUNS(u) ((4*TRACK_LENGTH*10568182182/u)/7) #define RACE_STATUS(x) GOTO_ROW_COL(STATUS_ROW,HEAT_COL_NUMOFFSET);SET_FOREGROUND_BACKGROUND(31,40);printf("#%2.2d",girace_num+1);GOTO_ROW_COL(STATUS_ROW,HEAT_COL_STATUSOFFSET);fputs(x, stdout);fflush(stdout) // States for each track, Start is waiting for a car to cross, // Finish is a car has started to cross, // Idle is back of car cleared, and/or waiting for a reset for another race. #define START_TRACK_STATE 0 #define FINISH_TRACK_STATE 1 #define IDLE_TRACK_STATE 2 // Master state machine, Idle means nothing happening, or race all done. // Race_in_progress means there are still cars that haven't finished. // Report_mph is only used to dump all the speed data, then goes to Idle. #define IDLE_STATE 0 #define SETUP_STATE 1 #define RACE_IN_PROGRESS_STATE 2 #define REPORT_MPH_STATE 3 #define REDRAW_MPH_STATE 4 #define SUCCESS 0 #define FAIL 1 extern void sevenseg( int x, int y, int n, int color, int bkcolor ); extern void dorace( int mstate, char *pracetxt, int icar, int ccar ); extern void heat_stats( int ccar ); #define PLACETEXT(x) ( ( ( x >= 0 ) && ( x < 3 ) ) ? aplacetext[x] : "th" ) extern int gasort[MAX_CARS]; extern int grace_results[CTRACKS][MAX_CARS]; extern int grace_time_results[CTRACKS][MAX_CARS]; extern int grace_sum[MAX_CARS]; extern int grace_sumtime[MAX_CARS]; extern int gcar_number[MAX_CARS]; extern long gusec_finish[CTRACKS]; // time in usec from reset to car crossing. extern long gusec_speed[CTRACKS]; // time in usec from front of car to back. extern int gplaces[CTRACKS]; // storage for what place each tracks car. extern int girace_num; // current race number. extern void swap( int i, int j ); extern void heat_stats( int ccar ); extern void race_screen( ); extern int recover_race_data( char *pracetxt, int iheat ); extern void dump_speed( long usec, FILE *race_stream ); #define min(a,b) ((a)>(b)?(b):(a)) #define max(a,b) ((a)<(b)?(b):(a))