/* Federal Climate Complex Surface Meteorological Summary Version 1-1 Display Routine Display routine for the PC - SMOIOX2 and SOCIOX1 compaction routines */ #include #include #include #include #include #include #include #include #include #include "helper.h" #define RSY 1 #include "rsy_open.h" #include "rsy_ptcd.h" #define MSGKEYPRESS " F1 Help ENTER Continue ESC Prior Screen " #define DIRKEYPRESS " Highlight choice, then ENTER (F1 Help ESC Prior Screen) " #define MDLERROR " ISMCS DATA ERROR - contact NOCD, Asheville (press ENTER to continue) " #define TABKEYPRESS " F1 Help F2 Output Movement keys scan table ESC prior screen " #define SEARCHERR " Error in searching for station, Contact NOCD Asheville " #define ANYPRESS " Press any key to continue " #define YELLOW_RED YELLOW + (RED << 4) #define WHITE_RED WHITE + (RED << 4) #define RED_WHITE RED + (LIGHTGRAY << 4) #define WHITE_BLUE WHITE + (BLUE << 4) #define YELLOW_BLUE YELLOW + (BLUE << 4) #define BLINK_YELLOW_BLUE YELLOW + (BLUE << 4) + BLINK #define WHITE_GREEN WHITE + (GREEN << 4) #define GRAY_BLUE LIGHTGRAY + (BLUE << 4) #define LINECNT 136 #define MAX_DATA_LINE 100 #define FFNAMESIZE 16 #define MAXFILES 42 #define MAXSUBS 123 #define BUFFCNT 5000 #define DICT_SIZE 14 #define TRUE 1 #define FALSE 0 #define FIRST_PAGE_LINES 12 #define REPTTR '\x00' #define ASCSWH '\x0F' #define HOMEKEY 327 #define ENDKEY 335 #define UPKEY 328 #define DOWNKEY 336 #define PGUPKEY 329 #define PGDNKEY 337 #define LEFTKEY 331 #define RIGHTKEY 333 #define CTRLLEFTKEY 371 #define CTRLRIGHTKEY 372 #define RTNKEY 13 #define ESCKEY 27 #define F1 315 #define F2 316 #define F3 317 void cd_exit(int); void disphdrcol(void); void scandta(void); void showtab(void); int diskdir(void); int subdir(void); void readhdr(void); #ifdef RSY char *cgets_cd(char *, int, int, int, int, int, char*); int getch_cd(void); void cursor(int); #define nocursor(x) cursor(x) #endif static unsigned char colortable[256]; static FILE *filein; char help_tag[23]; static char data_type[4]; static char cardin[LINECNT]; static char buffin[BUFFCNT], datapath[34]; static char x_line[6][LINECNT], tab_note[10][LINECNT]; static char data_line[MAX_DATA_LINE][LINECNT], sub_line[LINECNT*5]; static char tab_line[5][LINECNT], temp_str[LINECNT*5], por_str[LINECNT]; static char showname[MAXFILES][39], subtable[MAXSUBS * 13]; static int filenum, last_filenum, tablenum, tablelines, arraylines, tablenotes; static int nfiles, nsubs, maxcols, maxrows, toprow, leftcol, tophdr, leftmargin; static int scrrows, scrcols, scrtop, scrleft, row_inc = 1, col_inc = 1; static int n_pairs, n_fields[10], n_fcol[10]; static int last_sub_sel, last_sub_row, last_sub_col, sub_inc; static int last_dir_sel, last_dir_row, last_dir_col; static int input, ftab[40]; static int h_nib, compact; static long int file_pos[MAXSUBS], ptr_hdr[4]; static long int fptr[40]; static struct { int sub_size; char dict[DICT_SIZE+2]; } sub_hdr; #ifdef RSY extern int cdsmos_pathcode; char filename[80]; #endif #ifndef RSY void nocursor(int swap) /* turn off cursor */ { union REGS reg; /* get old shape & save, remove cursor from screen */ if(swap == 0) { reg.h.ah = 1; reg.x.cx = 0x2000; int86(0x10, ®, ®); } else { reg.h.ah = 1; reg.x.cx = 0x0607; int86(0x10, ®, ®); } } #endif #ifdef RSY int getkey(void) { int getch_cd(void); return getch_cd(); } #else int getkey(void) /* Uses the BIOS to read the next keyboard character */ { int key, lo, hi; key = bioskey(0); lo = key & 0X00FF; hi = (key & 0XFF00) >> 8; return((lo == 0) ? hi + 256 : lo); } /* getkey */ #endif void null_fill(char *s, long nchars) { /* completely fill nchars with NULLs starting at s */ int ichar; for(ichar = 0; ichar < nchars; ichar++) *s++ = NULL; return; } /* null_fill */ void writef(int col, int row, int color, int width,...) /* Prints a string in video memory at a selected location in a color */ { va_list arg_ptr; char *format; char output[LINECNT]; va_start(arg_ptr,width); format=va_arg(arg_ptr,char *); vsprintf(output, format, arg_ptr); output[width] = 0; textattr(colortable[color]); gotoxy(col, row); cprintf(output); } /* writef */ void initcolortable(void) /* Sets up the color table */ { int color, fg, bg, fcolor, bcolor; struct text_info ti; gettextinfo(&ti); if (ti.currmode == C80) { for (color = 0; color <= 255; color++) colortable[color] = color; } else { for (fg = BLACK; fg <= WHITE; fg++) { if (fg == BLACK) fcolor = BLACK; else if (fg <= LIGHTGRAY) fcolor = LIGHTGRAY; else fcolor = WHITE; for (bg = BLACK; bg <= LIGHTGRAY; bg++) { if (bg == BLACK) bcolor = BLACK; else { if (fcolor == WHITE) fcolor = BLACK; bcolor = LIGHTGRAY; } colortable[fg + (bg << 4)] = fcolor + (bcolor << 4); } } for (fg = 128; fg <= 255; fg++) colortable[fg] = colortable[fg - 128] | 0x80; } } /* initcolortable */ void scroll(int direction, int lines, int x1, int y1, int x2, int y2, int attrib) /* Scrolls an area of the screen */ { if (lines == 0) window(x1, y1, x2, y2); else switch(direction) { case UPKEY : movetext(x1, y1 + lines, x2, y2, x1, y1); window(x1, y2 - lines + 1, x2, y2); break; case DOWNKEY : movetext(x1, y1, x2, y2 - lines, x1, y1 + lines); window(x1, y1, x2, y1 + lines - 1); break; case LEFTKEY : movetext(x1 + lines, y1, x2, y2, x1, y1); window(x2 - lines + 1, y1, x2, y2); break; case RIGHTKEY : movetext(x1, y1, x2 - lines, y2, x1 + lines, y1); window(x1, y1, x1 + lines - 1, y2); break; } /* switch */ textattr(colortable[attrib]); clrscr(); window(1, 1, 80, 25); } /* scroll */ void print_tab(void) { FILE *printer; int iline, str_length; char work[80]; extern char oPath[80]; char out_line[80], prt_file[20]; char *cptr; char prt_note[] = " Enter output file for Table ( PRN = Printer ): "; writef((80 - strlen(prt_note)) >> 1, 25, RED_WHITE, strlen(prt_note), "%s", prt_note); cgets_cd(prt_file, 12, (52+strlen(prt_note))>>1, 25, WHITE, 1, "PRT_PATH_HELP"); if(*prt_file == 0) { writef((80-46)>>1, 25, WHITE_RED, 46, " Table not output - press any key to continue "); return; } if(stricmp(prt_file,"PRN")!=0) { strcpy(work,oPath); strcat(work,prt_file); strcpy(prt_file,work); openfile("", "", PATHCODE_OUTPUT, NULL); } if ((printer = fopen(prt_file, "wt")) == NULL) { writef(6, 25, WHITE_RED, 68, " Unable to write to %s - press any key to continue", prt_file); return; } fprintf(printer, "------------------INTERNATIONAL STATION METEOROLOGICAL CLIMATE SUMMARY-------------------\n\n "); for (iline = 0; iline < tablelines; iline++) fprintf(printer, "%s\n", tab_line[iline]); fprintf(printer, "\n"); null_fill(temp_str, LINECNT * 5); null_fill(out_line, 80); strcpy(temp_str, sub_line); cptr = strtok(temp_str, "\n"); strcpy(out_line, cptr); while((cptr = strtok(NULL, "\n")) != NULL) { str_length = strlen(out_line) + strlen(cptr) + 3; if(str_length <= 79) { strcat(out_line, " | "); strcat(out_line, cptr); } else { fprintf(printer, "%s\n", out_line); null_fill(out_line, 80); strcpy(out_line, cptr); } } if(*out_line != NULL) fprintf(printer, "%s\n", out_line); fprintf(printer, "\n"); for (iline = 0; iline < arraylines; iline++) fprintf(printer, "%s", x_line[iline]); fprintf(printer, "\n"); for (iline = 0; iline <= maxrows; iline++) fprintf(printer, "%s\n", data_line[iline]); fprintf(printer, "\n"); for (iline = 0; iline < tablenotes; iline++) fprintf(printer, "%s\n", tab_note[iline]); fprintf(printer, "\n\n"); fprintf(printer, "----------------------------FEDERAL CLIMATE COMPLEX ASHEVILLE----------------------------\n "); fflush(printer); fclose(printer); writef((80 - strlen(TABKEYPRESS)) >> 1, 25, YELLOW_BLUE, 80, "%s", TABKEYPRESS); return; } int response(void) { int key; key = getkey(); /* writef(1, 1, YELLOW_BLUE, 4, "%d", key); */ if(key == F1) { helper(help_tag); if(cdsmos_pathcode!=0) openfile("","",cdsmos_pathcode,NULL); } if(key == 301) { scroll(UPKEY, 0, 1, 1, 80, 25, WHITE); nocursor(1); cd_exit(0); } if(key == F2) { print_tab(); response(); } return(key); } /* response */ int selscreen(int inccol, int nshow, char *selname, int *lastshow, int *showrow, int *showcol) { int curcol, currow, ishow, lastcol, lastrow, incshow; int selleft, seltop, selbottom, ncol; /* define boundaries for cursor movement and selection */ if (nshow < 12) ncol = 1; else if (nshow < 43) ncol = 2; else ncol = 6; selleft = (80 - (inccol * ncol)) >> 1; if(selleft == 0) selleft++; incshow = ((nshow-1) / ncol) + 1; seltop = ((22 - incshow) >> 1) + tablelines + 1; selbottom = seltop + incshow - 1; curcol = selleft; currow = seltop; lastcol = ((nshow-1) / incshow) * inccol + selleft; lastrow = nshow - incshow * (ncol - 1) + seltop - 1; /* show select screen */ for (ishow = 0; ishow < nshow; ishow++) { writef(curcol, currow++, WHITE_GREEN, inccol, "%s", selname+ishow*inccol); if(currow > selbottom) { currow = seltop; curcol += inccol; } } writef((80 - strlen(DIRKEYPRESS)) >> 1, 25, LIGHTGREEN, strlen(DIRKEYPRESS), "%s", DIRKEYPRESS); if(*lastshow <= 0) { ishow = 0; curcol = selleft; currow = seltop; } else { ishow = *lastshow; curcol = *showcol; currow = *showrow; } /* movement key driver */ do { writef(curcol, currow, RED_WHITE, inccol, "%s", selname+ishow*inccol); input = response(); /* writef(25, 1, WHITE_RED, strlen(WHITE_RED), "%3d", input); */ writef(curcol, currow, WHITE_GREEN, inccol, "%s", selname+ishow*inccol); switch(input) { case PGUPKEY : ishow -= currow - seltop; currow = seltop; break; case PGDNKEY : ishow += selbottom - currow; if(ishow < nshow - 1) currow = selbottom; else { currow = lastrow; ishow = nshow - 1; } break; case HOMEKEY : currow = seltop; curcol = selleft; ishow = 0; break; case ENDKEY : ishow = nshow - 1; curcol = lastcol; currow = lastrow; break; case UPKEY : if(currow > seltop) { ishow--; currow--; } break; case DOWNKEY : if(currow < selbottom && ishow < nshow-1) { ishow++; currow++; } break; case LEFTKEY : if(curcol > selleft) { ishow -= incshow; curcol -= inccol; } break; case RIGHTKEY : if(curcol < lastcol && ishow + incshow < nshow) { ishow += incshow; curcol += inccol; } break; } /* switch */ } while (input != RTNKEY && input != ESCKEY); if(input == ESCKEY) ishow = -1; strcpy(sub_line, selname+ishow*inccol); strcat(sub_line, "\n"); *lastshow = ishow; *showrow = currow; *showcol = curcol; return(ishow); } /* selscreen */ int diskdir(void) { struct ffblk ffblk; int des_off, wa_type, tbl_tag[38] = { 1, 1, 1, 1, 1, 1, 6, 7, 8, 6, 7, 8, 6, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37}; char dirtitle[65]; char inname[34], wildname[44]; /* the table description array contains the 'short names' of the data tables from the SMOS & NWS (elements 1 to 43), SOCS (44 to 80), WWAS (81). */ static char tabdes[82][36] = {"", "Wind Dir vs Speed by Hr-Month", "CEILING vs VISBY by Hr-Month", "DRY vs WET BULB by Month", "TEMP vs WIND Dir by Month", "Daily MAX TEMP vs Month", "Daily MIN TEMP vs Month", "Daily MEAN TEMP vs Month", "Daily PRECIP vs Month", "Daily SNOW FALL vs Month", "Daily SNOW DEPTH vs Month", "SKY COVER vs Hr-Month", "REL HUM vs Hr-Month", "Wx COND vs Hr-Month", "WIND Dir vs Wx COND by Month", "Mean TEMP & Std Dev vs Month", "Wet BULB Mean & S.D. vs Month", "Mean DEW & Std Dev vs Month", "Mean SEA PRESS & S.D. vs Month", "Mean STA PRESS & S.D. vs Month", "%FLYING CLASS by Hr-Month", "Daily EXTR PRECIP vs Day", "", "EXTR Daily PRECIP vs Yr-Month", "EXTR SNOW FALL vs Yr-Month", "EXTR SNOW DEPTH vs Yr-Month", "", "24hr PEAK GUSTS by Yr-Month", "Mean REL HUM & S.D. by Month", "Daily AVG/EXTR TEMP by Month", "Extr MAX TEMP vs Yr-Month", "Extr MIN TEMP vs Yr-Month", "HEATING Degree Days vs Yr-Mth", "COOLING Degree Days vs Yr-Mth", "Mean TEMP vs Yr-Mth", "Total PRECIP vs Yr-Mth", "Wx COND vs Month", "Station Climatic Summary", "", "", "TEMP Thres & Moisture Stats", "Station Climatic Summary(cont)", "Foreign Station Climate Summary", "Daily Historical Precipitation", "%Freq ATMOS PHENOM fm Hrly", "%Freq Mthly ATMOS PHENOM fm Hr", "%Freq D/W ATMOS PHENOM fm DLY", "%Freq TSTMS fm Hrly", "%ATMOS PHEN vs WND DIR fm Hrly", "%Freq PRECIP fm Dly", "Total Mon PRECIP fm Dly", "Xtrm 24-hr PRECIP by Dly", "%Freq SNOWFALL fm Dly", "Total Mon SNOWFALL fm Dly", "Xtrm 24-hr SNOWFALL by Dly", "%Freq SNOW DEPTH fm Dly", "Xtrm Dly SNOW DEPTH fm Dly", "First & Last SNOWFALL fm Dly", "Peak WNDS fm Dly", "%Freq Dly PEAK WNDS fm Dly", "%Freq WND Dir vs Spd fm Hrly", "%Freq CIG vs VSBY fm Hrly", "%Freq SKY CVR fm Hrly", "Cum %Freq MAX TEMPS fm Dly", "Cum %Freq MIN TEMPS fm Dly", "Cum %Freq MEAN TEMP fm Dly", "Mon MAX TEMPS fm Dly", "Mon MIN TEMPS fm Dly", "Mon MEAN TEMPS fm Dly", "DRY BULB TEMPS fm Hrly", "WET BULB TEMPS fm Hrly", "DEWPT TEMP sum fm Hrly", "Cum %Freq REL HUM fm Hrly", "SEA LVL PRESS fm Hrly", "ALTIM SET fm Hrly", "STN PRESS fm Hrly", "%Freq CROSSWINDS fm Hrly", "HTG DEG DAYS fm Hrly", "CLG DEG DAYS fm Hrly", "AWS CLIMATIC BRIEF", "%CEILING - VISIBILITY vs Mth", "World Wide Airfield Summary"}; wa_type = 0; strcpy(dirtitle, "STATION TABLES"); tablelines = arraylines = tablenotes = tablenum = 0; scroll(UPKEY, 0, 1, 1, 80, 25, BLACK); if(last_filenum == -1) { null_fill(data_type, 4); strcpy(wildname, datapath); /* determine if data path contains the WWAS logo */ if(strstr(datapath, "wa") != NULL || strstr(datapath, "WA") != NULL) { strcat(wildname, ".t01"); if(findfirst(wildname, &ffblk, 0) != 0) { writef((80 - strlen(SEARCHERR)) >> 1, 10, YELLOW_RED, strlen(SEARCHERR), "%s", SEARCHERR); writef((80 - strlen(ANYPRESS)) >> 1, 12, YELLOW_RED, strlen(ANYPRESS), "%s", ANYPRESS); getch_cd(); return(-2); } wa_type = 1; #ifdef RSY openfile(wildname, "rb",cdsmos_pathcode,&filein); strcpy(filename,wildname); #endif des_off = 80; nfiles = 0; fptr[nfiles++] = 0; strcpy(data_type, "WA"); } else { strcat(wildname, ".PCF"); #ifdef RSY openfile("","",cdsmos_pathcode,NULL); #endif if(findfirst(wildname, &ffblk, 0) == 0) { #ifdef RSY openfile(wildname, "rb",cdsmos_pathcode,&filein); strcpy(filename,wildname); #endif fread(fptr, 1, sizeof(fptr), filein); fread(ftab, 1, sizeof(ftab), filein); for(nfiles = 0; ftab[nfiles] != 0; nfiles++) { strncpy(data_type, ffblk.ff_name, 2); /* look thru the data types to find table descriptions */ des_off = -1; if(strcmp(data_type, "SM") == 0 || strcmp(data_type, "WS") == 0) { des_off = 0; } else if(strcmp(data_type, "SO") == 0) { des_off = 43; } if(des_off > -1) { strncpy(inname, ffblk.ff_name + 2, 6); *(inname + 6) = NULL; sprintf(showname[nfiles], "%6s %-31s", inname, tabdes[ftab[nfiles] + des_off]); } } } else { writef((80 - strlen(SEARCHERR)) >> 1, 10, YELLOW_RED, strlen(SEARCHERR), "%s", SEARCHERR); writef((80 - strlen(ANYPRESS)) >> 1, 12, YELLOW_RED, strlen(ANYPRESS), "%s", ANYPRESS); getch_cd(); return(-2); } } } if(stricmp(data_type, "SM") == 0 || stricmp(data_type, "WS") == 0) { strcpy(help_tag, "SMOS_TABLES"); } else if(stricmp(data_type, "SO") == 0) { strcpy(help_tag, "SOCS_TABLES"); } else if(stricmp(data_type, "WA") == 0) { strcpy(help_tag, "WWAS_DISCUSSION"); } scroll(UPKEY, 0, 1, 1, 80, 25, BLACK); if(nfiles > 0) { writef((80-strlen(dirtitle)) >> 1, 1, YELLOW_BLUE, strlen(dirtitle), "%s", dirtitle); /* if station has more than one table, let user choose */ if(nfiles > 1) filenum = selscreen(39, nfiles, showname[0], &last_dir_sel, &last_dir_row, &last_dir_col); /* else - keep-a-goin' */ else filenum = 0; if(filenum < 0) return(-2); if(stricmp(data_type, "SM") == 0 || stricmp(data_type, "WS") == 0) sprintf(help_tag, "TB%2.2d", ftab[filenum]); else if(stricmp(data_type, "SO") == 0) sprintf(help_tag, "TBL%2.2d", tbl_tag[ftab[filenum]]); /* GO TO front of table to get sub_table pointer arrays pointers */ fseek(filein, fptr[filenum], 0); fread(ptr_hdr, 4, 4, filein); if (ptr_hdr[0] != 0) { /* GO TO end of the table for the sub_table pointer arrays */ fseek(filein, fptr[filenum] + ptr_hdr[1], 0); fread(file_pos, 4, (int) ptr_hdr[0], filein); fread(subtable, 1, (int) ptr_hdr[3], filein); } /* is this a bogus subtable or is there data? */ if(strstr(subtable, "\n") == NULL) memset(subtable, NULL, sizeof(subtable)); last_filenum = filenum; /* GO TO front of table for header */ fseek(filein, 17 + fptr[filenum], 0); } else { writef((80 - strlen(MDLERROR)) >> 1, 20, YELLOW_RED, strlen(MDLERROR), "%s", MDLERROR); response(); return(-2); } if(wa_type) return(-1); return(filenum); } /* diskdir */ int subdir(void) { int sub_num; char *p; null_fill(sub_line, LINECNT*5); scroll(UPKEY, 0, 1, tablelines + 1, 80, 25, BLACK); if(subtable[0] != NULL) { writef(20, 12, BLINK_YELLOW_BLUE, 45, "%s", "Loading sub-table directory: PLEASE WAIT ..."); if(last_sub_sel < 0) { p = subtable; for(nsubs = 0; nsubs < ptr_hdr[0]; nsubs++) { for( ; *p != '\n' ; p++); *p = '\0'; } } scroll(UPKEY, 0, 1, tablelines + 1, 80, 25, BLACK); sub_inc = strlen(subtable) + 1; sub_num = selscreen(sub_inc, (int) ptr_hdr[0], subtable, &last_sub_sel, &last_sub_row, &last_sub_col); if(sub_num < 0) return(-1); } else { nsubs = 0; sub_num = 0; writef(25, 12, YELLOW_BLUE, 30, "%s", "Single sub-table: LOADING ..."); } /* GO TO data table */ fseek(filein, file_pos[sub_num] + fptr[filenum], 0); return(sub_num); } /* subdir */ void readhdr(void) { int nline, ipair, iloop, strt_col, line_len; char *ic; scroll(UPKEY, 0, 1, 1, 80, 25, BLACK); fgets(cardin, LINECNT, filein); sscanf(cardin, "%d %d %d %d %*d", &tablenum, &tablelines, &arraylines, &tablenotes); /* skip short description line, already read in */ fgets(cardin, LINECNT, filein); /* initialize all data arrays */ null_fill(sub_line, LINECNT * 5); null_fill(tab_line[0], LINECNT * 5); null_fill(x_line[0], LINECNT * 5); null_fill(tab_note[0], LINECNT * 10); /* first line always station data */ fgets(tab_line[0], LINECNT, filein); *(tab_line[0] + strlen(tab_line[0]) - 1) = '\0'; if((line_len = strlen(tab_line[0])) >= 80) { line_len = 80; strt_col = 1; } else strt_col = (80 - (line_len-1)) >> 1; writef(strt_col, 1, WHITE_RED, line_len, "%s", tab_line[0]); writef(strt_col, 1, WHITE_BLUE, 4, "STA:"); fgets(tab_line[1], LINECNT, filein); *(tab_line[1] + strlen(tab_line[1]) - 1) = '\0'; if((line_len = strlen(tab_line[1])) >= 80) { line_len = 80; strt_col = 1; } else strt_col = (80 - (line_len-1)) >> 1; writef(strt_col, 2, WHITE_RED, line_len, "%s", tab_line[1]); writef((strt_col + (strstr(tab_line[1], ":LAT") - tab_line[1])), 2, WHITE_BLUE, 4, "LAT:"); writef((strt_col + (strstr(tab_line[1], ":LONG") - tab_line[1])), 2, WHITE_BLUE, 5, "LONG:"); writef((strt_col + (strstr(tab_line[1], ":ELEV") - tab_line[1])), 2, WHITE_BLUE, 5, "ELEV:"); writef((strt_col + (strstr(tab_line[1], ":TYPE") - tab_line[1])), 2, WHITE_BLUE, 5, "TYPE:"); /* the rest of the tablelines do not move, just in and out */ for (nline = 2; nline < tablelines; nline++) { fgets(tab_line[nline], LINECNT, filein); writef((80-strlen(tab_line[nline])) >> 1, nline+1, WHITE_RED, strlen(tab_line[nline]), "%s", tab_line[nline]); } /* save x data header and tab notes for later manipulation */ for(nline = 0; nline < arraylines; nline++) fgets(x_line[nline], LINECNT, filein); for(nline = 0; nline < tablenotes; nline++) { fgets(tab_note[nline], LINECNT, filein); for(ic = tab_note[nline] ; *ic != '\n' ; ic++); *ic = '\0'; } fgets(cardin, LINECNT, filein); sscanf(cardin, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", &n_pairs, &n_fields[0], &n_fcol[0], &n_fields[1], &n_fcol[1], &n_fields[2], &n_fcol[2], &n_fields[3], &n_fcol[3], &n_fields[4], &n_fcol[4], &n_fields[5], &n_fcol[5], &n_fields[6], &n_fcol[6], &n_fields[7], &n_fcol[7], &n_fields[8], &n_fcol[8], &n_fields[9], &n_fcol[9]); maxcols = 0; for(ipair = 0; ipair < n_pairs; ipair++) { for(iloop = 0; iloop < n_fields[ipair]; iloop++) maxcols += n_fcol[ipair]; } /* do not forget the POR string */ *por_str = NULL; while(*fgets(cardin, LINECNT, filein) != ':') strcat(por_str, cardin); return; } /* readhdr */ char *getword(char *s, char *q, int *nrep) { char *p, t; unsigned char *u; *q = NULL; p = q; u = s; *nrep = 1; if(*u == NULL) return(u); for( ; *u != NULL ; u++ ) { if(*u <= 127) *p++ = *u; else { t = *u - 128; if(t >= 32) { *p++ = t; *p++ = '.'; } else { *nrep = t; u++; break; } } } *p++ = NULL; return(u); } char *expand(char *s, char *q) { char last_word[40], *p; int filled, packed, ifield, ipair, nstr; ipair = n_pairs - 1; ifield = n_fields[ipair]; p = q; nstr = 1; do { if(--nstr == 0) { s = getword(s, last_word, &nstr); filled = strlen(last_word); } p = stpcpy(p++, last_word); for(packed = filled ; packed < n_fcol[ipair]; packed++) *p++ = ' '; if(--ifield == 0 && ipair > 0) ifield = n_fields[--ipair]; if(ipair < 0) { writef((80 - strlen(MDLERROR)) >> 1, 14, YELLOW_RED, strlen(MDLERROR), MDLERROR); while(response() != RTNKEY); null_fill(q, LINECNT); return(q); } } while (ipair != 0 || ifield != 0 || nstr != 1); /* s = getword(s, last_word, &nstr); filled = strlen(last_word); while(nstr-- > 0) { p = stpcpy(p++, last_word); for(packed = filled ; packed < n_fcol[ipair]; packed++) *p++ = ' '; } */ *p = *s; return(q); } /* expand */ char* get_nibble(char *jc, int* h_nib, int* nib_val) { /* get_nibble inserts the appropriate nibble from jc into the low-order bits from nib_val, and advances to the next nibble */ if(*h_nib) *nib_val = *jc >> 4; else *nib_val = *jc++ & ASCSWH; /* flip nibble */ *h_nib = !*h_nib; return(jc); } /* end get_nibble */ void dict_expand(void) { /* dict_comp is run for every sub table */ char *ic, *jc; char spare; int ix; /* major variables and meanings dict - dictionary of the 14 most used characters in sub-table data ix - current index of dictionary array ndict - # characters in dictionary array (max = 14) *ic - pointer to current expanded char in cardin *jc - pointer to current input byte in buffin h_nib - 4 bit field for input byte (1 - high, 0 - low) compact - translation mode(1 - compaction, 0 - copy as is) */ /* clear out output string */ null_fill(cardin, LINECNT); null_fill(data_line[0], LINECNT * MAX_DATA_LINE); null_fill(buffin, BUFFCNT); maxrows = 0; /* compact always starts as true at the beginning of a line */ compact = TRUE; h_nib = TRUE; ic = cardin; jc = buffin; /* read sub_hdr and sub_table */ fread(&sub_hdr, 1, sizeof(sub_hdr), filein); fread(buffin, 1, sub_hdr.sub_size, filein); /* pull until all data for sub_table is expanded and put in "data_line" */ while(jc - buffin < sub_hdr.sub_size) { jc = get_nibble(jc, &h_nib, &ix); /* is the nibble the repetitor sequence? */ if(ix == REPTTR) { /* save repetitor sequence, and default to compaction */ compact = TRUE; jc = get_nibble(jc, &h_nib, &ix); /* if two repetitor's in a row, then this is the end of the line */ if(ix == REPTTR) { /* finish expansion, store in display array, re-init work array */ expand(strrev(cardin), data_line[maxrows]); strrev(data_line[maxrows++]); null_fill(cardin, LINECNT); ic = cardin; if(maxrows > MAX_DATA_LINE) { writef((80 - strlen(MDLERROR)) >> 1, 14, YELLOW_RED, strlen(MDLERROR), MDLERROR); while(response() != RTNKEY); maxrows = MAX_DATA_LINE; break; } } else *ic++ = ix + 128; } /* is the nibble the switch to/from ASCII sequence ? */ else if(ix == ASCSWH) compact = !compact; /* if compact is on, move the character in the dict to output */ else if(compact) *ic++ = sub_hdr.dict[ix - 1]; /* otherwise, copy the ASCII sequence over */ else { /* save the high nibble and add in the low */ spare = ix << 4; jc = get_nibble(jc, &h_nib, &ix); *ic++ = spare + ix; } } /* merge all the sub_note lines together */ while(*fgets(cardin, LINECNT, filein) != ':') { strcat(sub_line, " | " ); strcat(sub_line, cardin); } return; } /* end dict_expand */ void showtab(void) { int nline, nextline, str_length; char *cptr, out_line[80]; null_fill(temp_str, LINECNT * 5); null_fill(out_line, 80); strcat(sub_line, por_str); nextline = tablelines + 1; scroll(UPKEY, 0, 1, nextline, 80, 25, BLACK); cptr = strtok(sub_line, "\n"); strcpy(out_line, cptr); while((cptr = strtok(NULL, "\n")) != NULL) { str_length = strlen(out_line) + strlen(cptr) + 3; if(str_length <= 79) { strcat(out_line, " | "); strcat(out_line, cptr); } else { writef((80 - strlen(out_line)) >> 1, nextline++, LIGHTCYAN, strlen(out_line), "%s", out_line); null_fill(out_line, 80); strcpy(out_line, cptr); } } if(*out_line != NULL) writef((80 - strlen(out_line)) >> 1, nextline++, LIGHTCYAN, strlen(out_line), "%s", out_line); tophdr = nextline; for(nline = 0; nline < arraylines; nline++) writef(1, nextline++, YELLOW, 80, "%s", x_line[nline]); scrtop = nextline; scrrows = 25 - scrtop; toprow = 0; leftmargin = leftcol = scrleft = n_fcol[0] + 1; scrcols = 81 - scrleft; for(nline = 0; nline <= maxrows && nextline < 25; nline++) { writef(1, nextline, WHITE, 80, "%s", data_line[nline]); writef(1, nextline++, YELLOW, n_fcol[0], "%s", data_line[nline]); } writef((80 - strlen(TABKEYPRESS)) >> 1, 25, YELLOW_BLUE, 80, "%s", TABKEYPRESS); return; } /* showtab */ void displaycol(int strtcol, int stpcol) /* Displays from start column to stop column on the screen using the globals toprow and leftcol as links to the data */ { int row, bottomrow; bottomrow = toprow + scrrows; for (row = toprow; row < bottomrow; row++) writef(strtcol-leftcol+scrleft+1, row-toprow+scrtop, WHITE, stpcol-strtcol+1, "%s", data_line[row]+strtcol); } /* displaycol */ void displayrow(int strtrow, int stprow) /* Displays a row on the screen */ { int row; for (row = strtrow; row <=stprow; row++) writef(scrleft, row-toprow+scrtop, WHITE, scrcols, "%s", data_line[row]+leftcol-1); } /* displayrow */ void disphdrcol(void) /* Prints the column headings */ { int bottomhdr, iline; bottomhdr = tophdr + arraylines - 1; scroll(UPKEY, 0, scrleft, tophdr, 80, bottomhdr, YELLOW); for (iline = 0; iline < arraylines ; iline++) writef(scrleft, iline+tophdr, YELLOW, scrcols, "%s", x_line[iline]+leftcol-1); } /* printcol */ void disphdrrow(int strtrow, int stprow) /* Prints the row headings */ { int row; for (row = strtrow; row <= stprow; row++) writef(1, row-toprow+scrtop, YELLOW, scrleft-1, "%s", data_line[row]); } /* printrow */ void moverowup(int tab_rows) /* Moves up tab_rows rows */ { int nrow; if(toprow - tab_rows < 0) { nrow = toprow; toprow = 0; } else { nrow = tab_rows; toprow -= tab_rows; } if (nrow > 0) { scroll(DOWNKEY, nrow, 1, scrtop, 80, 24, WHITE); displayrow(toprow, toprow+nrow-1); disphdrrow(toprow, toprow+nrow-1); } } /* moverowup */ void moverowdown(int tab_rows) /* Moves down one row */ { int nrow, bottomrow; bottomrow = toprow + scrrows; if(bottomrow + tab_rows - 1 > maxrows) { nrow = maxrows - bottomrow + 1; if(nrow > 0) toprow = maxrows - scrrows + 1; } else { nrow = tab_rows; toprow += tab_rows; } if (nrow > 0) { scroll(UPKEY, nrow, 1, scrtop, 80, 24, WHITE); displayrow(bottomrow, bottomrow + nrow - 1); disphdrrow(bottomrow, bottomrow + nrow - 1); } } /* moverowdown */ void movecolleft(int tab_cols) /* Moves left tab columns */ { int ncol; if(leftcol - tab_cols < leftmargin) { ncol = leftcol - leftmargin; leftcol = leftmargin; } else { ncol = tab_cols; leftcol -= tab_cols; } if (ncol > 0) { scroll(RIGHTKEY, ncol, leftmargin, tophdr, 80, 24, WHITE); displaycol(leftcol, leftcol+ncol-1); if(arraylines > 0) disphdrcol(); } } /* movecolleft */ void movecolright(int tab_cols) /* Moves right one column */ { int ncol, rightcol; rightcol = leftcol + scrcols - 1; if(rightcol+tab_cols > maxcols) { ncol = maxcols - rightcol; if(ncol > 0) leftcol = maxcols - scrcols + 1; } else { ncol = tab_cols; leftcol += tab_cols; } if (ncol > 0) { scroll(LEFTKEY, ncol, leftmargin, tophdr, 80, 24, WHITE); displaycol(rightcol, rightcol+ncol-1); if(arraylines > 0) disphdrcol(); } } /* movecolright */ void scandta(void) /* The main program loop */ { int n; do { input = response(); for(n = 0; *tab_note[n] != NULL; n++) { writef((80 - strlen(TABKEYPRESS)) >> 1, 25, YELLOW_BLUE, 80, "%s", TABKEYPRESS); if(input == *tab_note[n] && input != 32) { writef((80 - strlen(tab_note[n])) >> 1, 25, RED_WHITE, 80, "%s", tab_note[n]); break; } } switch(input) { case PGUPKEY : moverowup(scrrows); break; case PGDNKEY : moverowdown(scrrows); break; case CTRLLEFTKEY : movecolleft(scrcols); break; case CTRLRIGHTKEY : movecolright(scrcols); break; case UPKEY : moverowup(row_inc); break; case DOWNKEY : moverowdown(row_inc); break; case LEFTKEY : movecolleft(col_inc); break; case RIGHTKEY : movecolright(col_inc); break; } /* switch */ } while (input != ESCKEY); return; } /* run */ int cd_smos(char cd_drive[40], char cd_sta[10]) { int isub, irtn; input = 0; last_filenum = -1; initcolortable(); nocursor(0); /* helper_init("", "HELPFIL.HLP", "HELPER.HLQ"); */ /* signal(SIGINT, cd_exit); */ delay(0); scroll(UPKEY, 0, 1, 1, 80, 25, YELLOW_BLUE); sprintf(datapath, "%s%.2s\\%s", cd_drive, cd_sta+5, cd_sta); /* first page is 'firm wired' */ /* for(nline = 0; nline < FIRST_PAGE_LINES; nline++) { sscanf(first_page[nline], "%d", &iline); ic = first_page[nline] + 3; writef((80 - strlen(ic)) >> 1, iline, YELLOW_BLUE, strlen(ic), "%s", ic); } response(); */ scroll(UPKEY, 0, 1, 1, 80, 25, WHITE); last_dir_sel = -1; while((irtn = diskdir()) >= -1) { readhdr(); last_sub_sel = -1; do { if((isub = subdir()) >= 0) { dict_expand(); showtab(); scandta(); } } while(nsubs > 1 && isub >= 0); if(irtn == -1) break; if(nfiles<2) break; } scroll(UPKEY, 0, 1, 1, 80, 25, WHITE); nocursor(1); fclose(filein); return(0); }