/* Warning! This C source contains extended characters! */ #include #include #include #include #include #include #include #include #include int getmode(void) /* get the current video mode since Turbo-C may be out of sync */ { union REGS regs; regs.h.ah=(unsigned)'\xF'; int86(0x10,®s,®s); return((int)regs.h.al); } int getcolumn(void) /* get the current number of column since Turbo-C may be out of sync */ { union REGS regs; regs.h.ah=(unsigned)'\xF'; int86(0x10,®s,®s); return((int)regs.h.ah); } void findports(PARAMETERTYPE *parameter, int verbose) /* plays STEREO iff two parallel ports found */ /* plays SINGLE iff one parallel port found */ /* plays SPEAKER iff no parallel port found */ /* shuts off initially any parallel port to be used */ { if (parameter->A) if (parameter->B) { if (verbose) message(8); strcpy(parameter->ports,STEREO); strcat(parameter->ports,PORT1S); shutup(PORT1); strcat(parameter->ports,PORT2S); shutup(PORT2); parameter->C=FALSE; } else if (parameter->C) { if (verbose) message(8); strcpy(parameter->ports,STEREO); strcat(parameter->ports,PORT1S); shutup(PORT1); strcat(parameter->ports,PORT3S); shutup(PORT3); } else { if (verbose) message(26); strcpy(parameter->ports,SINGLE); strcat(parameter->ports,PORT1S); shutup(PORT1); } else if (parameter->B) if (parameter->C) { if (verbose) message(8); strcpy(parameter->ports,STEREO); strcat(parameter->ports,PORT2S); shutup(PORT2); strcat(parameter->ports,PORT3S); shutup(PORT3); } else { if (verbose) message(26); strcpy(parameter->ports,SINGLE); strcat(parameter->ports,PORT2S); shutup(PORT2); } else if (parameter->C) { if (verbose) message(26); strcpy(parameter->ports,SINGLE); strcat(parameter->ports,PORT3S); shutup(PORT3); } else { if (verbose) message(9); strcpy(parameter->ports,SPEAKER); } } int scannumber(char source[]) /* scans a strings for a positive decimal integer */ /* the source must contain the number only */ { int number,ptr; char c; if (source[0]=='\0') error(23); number=ptr=0; while ((c=source[ptr++])!='\0') if ((c>='0') && (c<='9')) number=10*number+(int)(c-'0'); else error(23); return(number); } void scanarguments(int argc, char *argv[], char menuname[], PARAMETERTYPE *parameter) /* scans command line parameters */ { int argptr; for (argptr=1 ; argptrtempdrive=(int)((char)toupper((int)argv[argptr][2])-'A'); if (argv[argptr][3]!='\0') error(23); } else if ((char)toupper((int)argv[argptr][1])==MODEFLAG) parameter->videomode=scannumber(&(argv[argptr][2])); else if ((char)toupper((int)argv[argptr][1])==COLORFLAG) switch (argv[argptr][2]) { case '1':coloroutline=scannumber(&(argv[argptr][3])); break; case '2':colortitle=scannumber(&(argv[argptr][3])); break; case '3':coloritem=scannumber(&(argv[argptr][3])); break; case '4':colorpicked=scannumber(&(argv[argptr][3])); break; case '5':colorcurrent=scannumber(&(argv[argptr][3])); break; case '6':colorcursor=scannumber(&(argv[argptr][3])); break; case '7':colorborder=scannumber(&(argv[argptr][3])); break; default:error(23); } else error(23); } else /* short parameter */ if ((char)toupper((int)argv[argptr][1])==SPEED1FLAG) parameter->speed[1]='a'; else if ((char)toupper((int)argv[argptr][1])==SPEED2FLAG) parameter->speed[1]='b'; else if ((char)toupper((int)argv[argptr][1])==SPEED3FLAG) parameter->speed[1]='c'; else if ((char)toupper((int)argv[argptr][1])==FRENCHFLAG) language=FRENCH; else if ((char)toupper((int)argv[argptr][1])==ENGLISHFLAG) language=ENGLISH; else if ((char)toupper((int)argv[argptr][1])==GERMANFLAG) language=GERMAN; else if ((char)toupper((int)argv[argptr][1])==HIGHFLAG) { coloroutline|=HIGHINT; colortitle|=HIGHINT; coloritem|=HIGHINT; colorpicked|=HIGHINT; colorcurrent|=HIGHINT; colorcursor|=HIGHINT; colorborder|=HIGHINT; } else if ((char)toupper((int)argv[argptr][1])==MOUSEFLAG) parameter->mouse=TRUE; else if ((char)toupper((int)argv[argptr][1])==SONGFLAG) { parameter->verbose=FALSE; parameter->DOS=FALSE; } else if ((char)toupper((int)argv[argptr][1])==VERBOSEFLAG) { parameter->verbose=TRUE; parameter->DOS=FALSE; } else if ((char)toupper((int)argv[argptr][1])==DOSFLAG) { parameter->verbose=FALSE; parameter->DOS=TRUE; } else if ((char)toupper((int)argv[argptr][1])==PAUSEFLAG) parameter->pause=TRUE; else if ((char)toupper((int)argv[argptr][1])==BIOSFLAG) parameter->rawvideo=FALSE; else if (argv[argptr][1]==NOPORTFLAG) { parameter->A=parameter->B=parameter->C=FALSE; strcpy(parameter->ports,SPEAKER); } else if (argv[argptr][1]==PORT1FLAG) { parameter->A=TRUE; parameter->ports[0]=ODDPORTS; } else if (argv[argptr][1]==PORT2FLAG) { parameter->B=TRUE; parameter->ports[0]=ODDPORTS; } else if (argv[argptr][1]==PORT3FLAG) { parameter->C=TRUE; parameter->ports[0]=ODDPORTS; } else if ((char)toupper((int)argv[argptr][1])==QUESTIONFLAG) error(1); else error(23); else /* must be a menu name */ if (strlen(argv[argptr])>=(LINELENGTH-strlen(MENUENDING))) error(22); else strcpy(menuname,argv[argptr]); } colorcurrent<<=4; colorcursor<<=4; colorborder<<=4; /* no harm done if the user specifies three parallel ports */ if (parameter->A || parameter->B || parameter->C) findports(parameter,FALSE); } void extractstring(char **scannerptr, char target[], int targetlength, int spacesin) /* copies "intelligently" a token from a string into another string */ /* target has a fixed width */ { int scanner; /* skip leading spaces */ while ((**scannerptr==' ') && (**scannerptr!='\0') && (**scannerptr!='\n')) (*scannerptr)++; /* there should be something left to read */ if ((**scannerptr=='\0') || (**scannerptr=='\n')) error(10); if (spacesin) { /* read until EOL or nothing left */ for (scanner=0 ; (**scannerptr!='\0') && (**scannerptr!='\n') ; (*scannerptr)++) target[scanner++]=**scannerptr; /* discard pending spaces for now */ while (target[scanner-1]==' ') scanner--; } else /* read until space, EOL, or nothing left */ for (scanner=0 ; (**scannerptr!=' ') && (**scannerptr!='\0') && (**scannerptr!='\n') ; (*scannerptr)++) target[scanner++]=**scannerptr; /* check if not too long */ if (scanner>targetlength) error(11); /* fill with space until full length */ while (scanner=0) target[endptr--]=target[ptr--]; while (endptr>=0) target[endptr--]=' '; } void centerstring(char target[], int targetlength) /* inserts spaces until the content is centered */ { int ptr,endptr; ptr=targetlength-1; while (target[ptr]==' ') ptr--; endptr=(ptr+targetlength)/2; while (ptr>=0) target[endptr--]=target[ptr--]; while (endptr>=0) target[endptr--]=' '; } void pathcopy(SONGSTYPE *songs, char newDOSpath[]) /* copies a paths to the pool and updates the last song */ { char *poolptr; int scanner; scanner=LINELENGTH-1; /* length of newDOSpath */ while ((newDOSpath[--scanner]==' ') && (scanner>=0)) newDOSpath[scanner]='\0'; poolptr=songs->songpath+songs->songpathoffset; songs->song[songs->songnumber].DOSpath=poolptr; songs->songpathoffset+=strlen(newDOSpath); if (songs->songpathoffset++>PATHLENGTH) error(24); strcpy(poolptr,newDOSpath); } void readmenu(FILE *menufile, SONGSTYPE *songs) /* each line contains diskette name, path name, DOS file name, and song name */ /* these subitems are surrounded by spaces */ /* the song name may contain spaces */ { char line[LINELENGTH]; char newdiskname[LINELENGTH]; char newscore[LINELENGTH]; char newDOSpath[LINELENGTH]; char newDOSname[LINELENGTH]; char newsongname[LINELENGTH]; char *errorchar; char *scannerptr; errorchar=fgets(line,LINELENGTH,menufile); /* let fgets handle EOL */ while (errorchar!=NULL) { if (strlen(line)==(LINELENGTH-1)) error(4); if (line[0]!=COMMENTFLAG) { scannerptr=line; extractstring(&scannerptr,newdiskname,DISKNAMELENGTH,FALSE); flushright(newdiskname,DISKNAMELENGTH); extractstring(&scannerptr,newscore,SCORELENGTH,FALSE); flushright(newscore,SCORELENGTH); extractstring(&scannerptr,newDOSpath,(LINELENGTH-1),FALSE); extractstring(&scannerptr,newDOSname,DOSNAMELENGTH,FALSE); extractstring(&scannerptr,newsongname,SONGNAMELENGTH,TRUE); centerstring(newsongname,SONGNAMELENGTH); songs->songnumber++; if (songs->songnumber>MAXSONGS) error(5); strcpy(songs->song[songs->songnumber].diskname,newdiskname); strcpy(songs->song[songs->songnumber].score,newscore); pathcopy(songs,newDOSpath); strcpy(songs->song[songs->songnumber].DOSname,newDOSname); strcpy(songs->song[songs->songnumber].songname,newsongname); songs->song[songs->songnumber].picked=0; } errorchar=fgets(line,LINELENGTH,menufile); } if (songs->songnumber==0) error(6); printf(" %d",songs->songnumber); message(7); printf(" %d",(int)(((long)100*(long)songs->songpathoffset)/(long)PATHLENGTH)); message(0); } int findport(int port) /* port deemed valid iff data can be written and read back */ /* returns TRUE iff parallel port found */ /* bus remanence (?!) calls for the delay used between write and read */ /* this delay also makes for a not so loud speaker noise */ /* warning: may not work on some parallel ports */ { int data; shutup(port); data=0x0; do { data++; outportb(port,(unsigned char)data); delay(SHUTUPDELAY); if ((unsigned char)data!=inportb(port)) return(FALSE); } while (data!=0xFF); shutup(port); return(TRUE); } int findprogram(char program[], int tempdrive, int currentdrive) /* searches temporary drive(RAM?), PATH(HD?), and current drive */ /* returns drive number or -1 */ { struct ffblk fff; setdisk(tempdrive); if (searchpath(program)==NULL) { setdisk(currentdrive); /* normal, read-only, hidden, system, archive */ if (findfirst(program,&fff,39)) return(-1); else return(currentdrive); } else { setdisk(currentdrive); return(tempdrive); } } int moveprogram(PARAMETERTYPE *parameter, char program[], int *programcopied) /* the program is on the temporary drive (or path), or on the current drive */ /* if necessary, the program is moved temporarily onto the temporary drive */ /* this will most likely optimize the speed of operation of system() calls */ /* returns TRUE iff the program has been found */ { char buffer[BUFFERSIZE]; char filename[LINELENGTH]; FILE *source,*target; int programdrive,errorint,tomove,moved; char temporarytext[3]; char programtext[3]; *programcopied=FALSE; programdrive=findprogram(program,parameter->tempdrive, parameter->currentdrive); if (programdrive==-1) return(FALSE); if (programdrive!=parameter->tempdrive) { strcpy(temporarytext,"A:"); strcpy(programtext,"A:"); temporarytext[0]+=(char)parameter->tempdrive; programtext[0]+=(char)programdrive; message(10); strcpy(filename,programtext); strcat(filename,program); source=fopen(filename,"rb"); if (source==NULL) error(13); strcpy(filename,temporarytext); strcat(filename,program); target=fopen(filename,"wb"); if (target==NULL) error(14); tomove=(int)fread(buffer,(unsigned)1,(unsigned)BUFFERSIZE,source); while (tomove!=0) { moved=(int)fwrite(buffer,(unsigned)1,(unsigned)tomove,target); if (moved!=tomove) error(15); tomove=(int)fread(buffer,(unsigned)1,(unsigned)BUFFERSIZE,source); } errorint=fclose(source); if (errorint==EOF) error(16); errorint=fclose(target); if (errorint==EOF) error(17); *programcopied=TRUE; message(11); } else message(12); return(TRUE); } void readparameter(PARAMETERTYPE *parameter, MOUSETYPE *mousedata, int songnumber) /* collects information about drives, program location, ports and screen */ { int height; int found; int lastdrive; int bigtotal; message(28); printf("%c\n",(char)toupper((int)parameter->speed[1])); if (parameter->verbose) { message(41); parameter->itemlength=1+DISKNAMELENGTH+1+SCORELENGTH+1+DOSNAMELENGTH+1+ SONGNAMELENGTH+1; } else if (parameter->DOS) { message(46); parameter->itemlength=1+DOSNAMELENGTH+1; } else { message(42); parameter->itemlength=1+SONGNAMELENGTH+1; } message(13); parameter->currentdrive=getdisk(); printf("%c\n",(char)((int)'A'+parameter->currentdrive)); /* works iff LASTDRIVE statement found in CONFIG */ lastdrive=setdisk(parameter->currentdrive)-1; if (parameter->tempdrive==ODDDRIVE) { if (parameter->currentdrive<=1) /* from floppy */ parameter->tempdrive=lastdrive; else /* from hard-disk or RAM-disk */ parameter->tempdrive=parameter->currentdrive; } message(14); printf("%c\n",(char)((int)'A'+parameter->tempdrive)); if ((parameter->tempdrive<0) || (parameter->tempdrive>lastdrive)) error(30); message(15); printf("%s:\n",MODPLAY1); found=moveprogram(parameter,MODPLAY1,&(parameter->modplaycopied)); if (!found) { message(15); printf("%s:\n",MODPLAY2); found=moveprogram(parameter,MODPLAY2,&(parameter->modplaycopied)); if (!found) { message(15); printf("%s:\n",MODPLAY3); found=moveprogram(parameter,MODPLAY3,&(parameter->modplaycopied)); if (!found) error(12); } } message(15); printf("%s:\n",PKUNZIP1); found=moveprogram(parameter,PKUNZIP1,&(parameter->pkunzipcopied)); if (!found) message(29); parameter->pkunzipfound=found; if (parameter->ports[0]==ODDPORTS) { message(16); parameter->A=findport(PORT1); parameter->B=findport(PORT2); if (!parameter->A || !parameter->B) parameter->C=findport(PORT3); findports(parameter,TRUE); } else message(27); message(17); if (parameter->rawvideo) message(48); else message(49); if (parameter->videomode==ODDMODE) { message(18); parameter->videomode=getmode(); printf("%d\n",parameter->videomode); } else { message(47); printf("%d\n",parameter->videomode); } parameter->maxcolumn=getcolumn(); printf(" %d ",parameter->maxcolumn); message(19); parameter->maxline=25; printf(" %d ",parameter->maxline); message(20); height=(int)peekb((unsigned)0x40,(unsigned)0x84)+1; /* guess if this information makes sense */ if ((height>25) && (height<=60)) { parameter->maxline=height; printf(" %d ",parameter->maxline); message(21); } /* number of item lines in menu */ parameter->bigline=parameter->maxline-4; /* number of item columns in menu */ parameter->bigcolumn=(parameter->maxcolumn-4)/parameter->itemlength; /* total number of items on menu */ bigtotal=parameter->bigcolumn*parameter->bigline; /* adjust if screen not fully used */ if (bigtotal>songnumber) { /* number of item columns in menu */ parameter->bigcolumn=(songnumber-1)/parameter->bigline+1; /* number of item lines in menu */ parameter->bigline=(songnumber-1)/parameter->bigcolumn+1; } if (parameter->bigcolumn<1) error(7); if (parameter->bigline<1) error(8); /* total number of item lines, displayed and not displayed */ parameter->hugeline=(songnumber-1)/parameter->bigcolumn+1; /* left out column space */ parameter->leftcolumn=parameter->maxcolumn-4- parameter->bigcolumn*parameter->itemlength; if (parameter->mouse) { message(44); if (setupmouse(parameter,mousedata)) message(45); else error(31); } if (parameter->pause) { bellit(); message(22); switch (bioskey(0)) { case KEYESC:error(9); default:break; } } }