home *** CD-ROM | disk | FTP | other *** search
- /* after years of fiddling..
- 'v1.0 September 89
- 'Jim Butterfield */
-
- /* compile with lc -Lcd -v <filename> */
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <stdio.h>
- #define BUFFERLINE 50
- #define INFOSIZE sizeof(struct FileInfoBlock)
- #define TRAILLEN 100
-
- /* File Support structures */
- struct CityData {
- char *CityName; /* full name w/state */
- char *StateName; /* state/province only */
- struct CityData *CityLink; /* init letter chain */
- struct CityData *StateLink; /* init letter chain */
- struct RouteData *RoadList; /* roads to/from city */
- struct CityData *WorkList; /* temp job queue */
- struct CityData *NextCity[2]; /* result links */
- /* Mindist[0] doubles as CityDupe flag during file input */
- unsigned short MinDist[2]; /* closest so far */
- unsigned char StateDupe; /* one name per state */
- unsigned char Colum; /* goes with RoadList */
- };
- struct RouteData {
- struct CityData *CityNum[2]; /* cities each end */
- unsigned short Dist[2]; /* distance, time */
- char *Hiway; /* name of Highway */
- struct RouteData *RLink[2]; /* link for each city */
- unsigned char Colm[2]; /* goes with RLink */
- };
- struct RouteData *Route0, *Route9;
- struct CityData *City0, *City9;
- struct CityData *CharLink[0x20];
- struct CityData *ChStLink[0x20];
- static char InBuff[BUFFERLINE];
- static struct CityData *Trail[TRAILLEN][2];
- unsigned short TrailPoint[2];
- void TimeShow(unsigned short,char *);
- int CityMatch(struct CityData *,char *);
- unsigned short ParseCities(char *,long);
- unsigned short ParseRoutes(char *,long);
- struct CityData * AskCity();
- void Navigate(struct CityData *,struct CityData *);
- void main()
- {
- long fh, lok;
- unsigned short Column, ColStart, ColEnd;
- unsigned short NextCol, NewCol;
- unsigned short AllocCount, errnum;
- unsigned short TrackTrail;
- struct FileInfoBlock *fibb;
- long CitySize, RouteSize;
- char *CityBlox, *RouteBlox, *DataScan, *Active;
- char *StringStart, *FieldStart;
- char *CityPoint, *RoutePoint;
- struct CityData *From, *Dest, *Via, *SearchCity;
- struct CityData *FLink;
- struct RouteData *NextRoute, *NewRoute;
- unsigned short Cities, Roads;
- unsigned short CityPSize, RoutePSize;
- unsigned char Ct0; /* general character work value */
- static unsigned short Result[2][2];
- static unsigned short tTime, tMiles;
- static char ActCity[]="Cities";
- static char ActRoad[]="Roads";
- for (Ct0=0; Ct0 < 0x20; Ct0++) CharLink[Ct0]= 0;
- for (Ct0=0; Ct0 < 0x20; Ct0++) ChStLink[Ct0]= 0;
-
- AllocCount=0;
- errnum=2; /* no memory */
- if ( (long) (fibb = (struct FileInfoBlock *) AllocMem(INFOSIZE,0L))
- != 0L)
- {
- AllocCount=1;
- errnum=3; /* file problems */
- fprintf(stderr,"RoadRoute V1.5 .. Jim Butterfield\n");
- fprintf(stderr," Release version: 1990 04 09\n");
- Cities=0;
- Active=ActCity;
- if ( (lok = Lock("Cities",ACCESS_READ)) != 0L)
- {
- if ( (fh=Examine(lok,fibb)) !=0L)
- {
- CitySize=fibb->fib_Size;
- if ( (long) (CityBlox = AllocMem(CitySize,0L)) != 0L)
- {
- AllocCount=2;
- if ( (fh = Open("Cities",MODE_OLDFILE)) != 0L)
- {
- errnum=0;
- Read(fh,CityBlox,CitySize);
- Close(fh);
- } /* City file opened */
- } /* data alloc OK */
- } /* examine OK */
- UnLock(lok);
- } /* lock OK */
- } /* examine alloc OK */
- if (errnum == 0)
- {
- for (DataScan=CityBlox;DataScan < CityBlox+CitySize;DataScan++)
- if (*DataScan == 0x0A) Cities++;
- CityPSize=Cities*sizeof(struct CityData);
- if ( (long) (CityPoint = AllocMem(CityPSize,0L)) != 0L)
- AllocCount=3;
- else
- errnum=2;
- }
- if (errnum ==0 )
- {
- errnum=3; /* file problems */
- Active=ActRoad;
- Roads=0;
- if ( (lok = Lock("Roads",ACCESS_READ)) != 0L)
- {
- if ( (fh=Examine(lok,fibb)) !=0L)
- {
- RouteSize=fibb->fib_Size;
- if ( (long) (RouteBlox = AllocMem(RouteSize,0L)) != 0L)
- {
- AllocCount=4;
- if ( (fh = Open("Roads",MODE_OLDFILE)) != 0L)
- {
- errnum=0;
- Read(fh,RouteBlox,RouteSize);
- Close(fh);
- } /* file opened */
- } /* data alloc OK */
- } /* examine OK */
- UnLock(lok);
- } /* lock OK */
- }
- if (errnum == 0)
- {
- for (DataScan=RouteBlox;DataScan < RouteBlox+RouteSize;DataScan++)
- if (*DataScan == 0x0A) Roads++;
- RoutePSize=Roads*sizeof(struct RouteData);
- if ( (long) (RoutePoint = AllocMem(RoutePSize,0L)) != 0L)
- AllocCount=5;
- else
- errnum=2;
- }
- if (errnum == 0)
- {
- Active=ActCity;
- fprintf(stderr,">> %d Cities\n",Cities);
- City0 = (struct CityData *) CityPoint;
- errnum=ParseCities(CityBlox,CitySize);
- }
- if (errnum == 0)
- {
- Active=ActRoad;
- fprintf(stderr,">> %d Roads\n",Roads);
- Route0 = (struct RouteData *) RoutePoint;
- errnum=ParseRoutes(RouteBlox,RouteSize);
- }
- switch (errnum)
- {
- case 0: /* no errors, do main job */
- Ct0='Y';
- while (Ct0 == 'Y')
- {
- TrailPoint[0]=0;
- TrailPoint[1]=0;
- fprintf(stderr,"City from: ");
- if (gets(InBuff) == 0 || *InBuff =='\0') From=City0;
- else From=AskCity();
- fprintf(stderr,"From %s to: ",From->CityName);
- if (gets(InBuff) == 0)
- {
- InBuff[0]='?';
- InBuff[1]='\0';
- }
- Dest=AskCity();
- fprintf(stderr,"%s->%s via (or RETURN): ",
- From->CityName,Dest->CityName);
- Via=0;
- if (gets(InBuff) != 0 && *InBuff != '\0')
- {
- Via = AskCity();
- fprintf(stderr,"\n%s->%s via %s\n",
- From->CityName,Dest->CityName,Via->CityName);
- Navigate(From,Via);
- Navigate(Via,Dest);
- }
- else
- {
- fprintf(stderr,"\n%s->%s DIRECT\n",From->CityName,Dest->CityName);
- Navigate(From,Dest);
- }
- for (Column=0; Column<2; Column++)
- {
- Result[0][Column]=0; /* dist */
- Result[1][Column]=0; /* time */
- SearchCity=From;
- for (TrackTrail=0; TrackTrail <TrailPoint[Column]; TrackTrail++)
- {
- FLink=Trail[TrackTrail][Column];
- NextRoute=SearchCity->RoadList;
- NextCol=SearchCity->Colum;
- while (NextRoute !=0 &&
- FLink != NextRoute->CityNum[1-NextCol])
- {
- NewRoute=NextRoute->RLink[NextCol];
- NewCol=NextRoute->Colm[NextCol];
- NextRoute=NewRoute;
- NextCol=NewCol;
- }
- Result[1][Column]=Result[1][Column]+NextRoute->Dist[1];
- Result[0][Column]=Result[0][Column]+NextRoute->Dist[0];
- SearchCity=FLink;
- } /* next Link */
- } /* next Column */
- ColStart=0;
- ColEnd=1;
- if (Result[0][0]==Result[0][1])
- {
- ColStart=1;
- ColEnd=1;
- }
- if (Result[1][0]==Result[1][1])
- {
- ColStart=0;
- ColEnd=0;
- }
- for (Column=ColStart; Column<=ColEnd; Column++)
- {
- fprintf(stderr,"%4d Miles, time: ",Result[0][Column]);
- TimeShow(Result[1][Column],InBuff);
- fprintf(stderr,"%s\n",InBuff);
- } /* next Column */
- if (ColStart != ColEnd)
- {
- Ct0='B';
- fprintf(stderr,"FASTEST, SHORTEST (or BOTH) ");
- if ((StringStart=gets(InBuff)) != 0) Ct0=*StringStart;
- if (Ct0 > 'Z') Ct0 -=32;
- if (Ct0 =='S') ColEnd=0;
- if (Ct0 =='F') ColStart=1;
- } /* fastest/shortest question */
- else
- {
- fprintf(stderr,"Press any key to continue\n");
- gets(InBuff);
- }
- for (Column=ColStart; Column<=ColEnd; Column++)
- {
- printf ("From: %s\nTo: %s\n",From->CityName,Dest->CityName);
- if (Via != 0) printf ("Via: %s\n",Via->CityName);
- tMiles=0;
- tTime=0;
- SearchCity=From;
- for (TrackTrail=0; TrackTrail <TrailPoint[Column]; TrackTrail++)
- {
- FLink=Trail[TrackTrail][Column];
- NextRoute=SearchCity->RoadList;
- NextCol=SearchCity->Colum;
- while (NextRoute > 0 &&
- FLink!=NextRoute->CityNum[1-NextCol])
- {
- NewRoute=NextRoute->RLink[NextCol];
- NewCol=NextRoute->Colm[NextCol];
- NextRoute=NewRoute;
- NextCol=NewCol;
- } /* wend, no NextRoute */
- tTime=tTime+NextRoute->Dist[1];
- tMiles=tMiles+NextRoute->Dist[0];
- TimeShow(NextRoute->Dist[1],InBuff);
- /* Print highway link information */
- printf("%4d %s ",NextRoute->Dist[0],InBuff);
- StringStart=InBuff;
- FieldStart=SearchCity->CityName;
- while (*FieldStart != ',')
- *StringStart++ =*FieldStart++;
- *StringStart++ =' ';
- *StringStart++ ='-';
- *StringStart++ =' ';
- FieldStart=FLink->CityName;
- while (*FieldStart != ',')
- *StringStart++ =*FieldStart++;
- *StringStart++ =0;
- printf("%s via %s\n",InBuff,NextRoute->Hiway);
- SearchCity=FLink;
- } /* next link */
- printf (" Total Miles: %d\n",tMiles);
- TimeShow(tTime,InBuff);
- printf (" Driving Time: %s\n",InBuff);
- } /* next Column */
- Ct0='N';
- fprintf (stderr,"Another trip? ");
- if ((StringStart=gets(InBuff)) != 0) Ct0=*StringStart;
- if (Ct0 > 'Z') Ct0 -=32;
- } /* another trip */
- break;
- case 1: /* trouble in file data */
- fprintf(stderr,"----> Correct data in file %s and try again.\n",Active);
- break;
- case 2: /* AllocMem refused */
- fprintf(stderr,"----> Not enough memory to run RoadRoute.\n");
- break;
- case 3: /* real trouble with file */
- fprintf(stderr,"----> Can't proceed due to unreadable file %s.\n",Active);
- break;
- default:
- fprintf(stderr,"System error: %d\n",errnum);
- } /* error switch area */
- switch (AllocCount)
- {
- case 5: FreeMem(RoutePoint,RoutePSize);
- case 4: FreeMem( (char *) RouteBlox,RouteSize);
- case 3: FreeMem(CityPoint,CityPSize);
- case 2: FreeMem( (char *) CityBlox,CitySize);
- case 1: FreeMem( (char *) fibb,INFOSIZE);
- } /* memory cleanup */
- if (errnum != 0)
- {
- fprintf(stderr,"Press any key to quit\n");
- gets(InBuff);
- }
- }
-
-
- void TimeShow(Time, Buffer)
- unsigned short Time;
- char *Buffer;
- {
- unsigned short MinFlag, radix, digit, SuppressLimit, FillChar, Hours[2];
- Hours[0]=Time/60;
- Hours[1]=Time%60;
- SuppressLimit=1;
- FillChar=':';
- radix=10000;
- while (radix>Hours[0] && radix>SuppressLimit)
- {
- radix/=10;
- *Buffer++ =' ';
- }
- for (MinFlag=0;MinFlag<2;MinFlag++)
- {
- while (radix>0)
- {
- digit=Hours[MinFlag]/radix;
- Hours[MinFlag]%=radix;
- *Buffer++ =digit+'0';
- radix/=10;
- } /* more digits */
- *Buffer++ =FillChar;
- FillChar=0;
- SuppressLimit=10;
- radix=10;
- } /* next MinFlag */
- }
-
- int CityMatch(TabPoint,CityText)
- struct CityData *TabPoint;
- char *CityText;
- {
- /* Name must match exactly; state is optional */
- int Match, StateMatch;
- char TablChar, TextChar;
- char *TableName;
- TableName=TabPoint->CityName;
- TablChar=*TableName++; if (TablChar > 'Z') TablChar-=0x20;
- TextChar=*CityText++; if (TextChar > 'Z') TextChar-=0x20;
- Match=1;
- StateMatch=0;
- while (Match == 1 && TextChar != ',')
- {
- if (TablChar != TextChar)
- {
- if (TablChar ==',' && TextChar =='/') StateMatch=1;
- else Match=0;
- }
- TablChar=*TableName++; if (TablChar > 'Z') TablChar-=0x20;
- TextChar=*CityText++; if (TextChar > 'Z') TextChar-=0x20;
- }
- if (Match==1)
- {
- if (TablChar != 0 && TablChar !=',') Match=0;
- if (TabPoint->MinDist[0]==1 && StateMatch ==0) Match=0;
- }
- return (Match);
- }
-
- unsigned short ParseCities(CitiesBlock,CBlockSize)
- char *CitiesBlock;
- long CBlockSize;
- {
- struct CityData *CityStruct, *CityScan;
- char *LineBegin, *EndLine, *NewName, *OldName;
- unsigned short CityError;
- unsigned char CityIndex,NewChar,OldChar;
- unsigned char FoundFlag, StateFlag;
- CityError=0;
- CityStruct = City0;
- LineBegin = CitiesBlock;
- FoundFlag=0;
- for (EndLine=CitiesBlock;EndLine < CitiesBlock+CBlockSize;EndLine++)
- if (*EndLine == ',' || *EndLine == 0x0A)
- {
- if (*EndLine == ',')
- {
- FoundFlag=1;
- CityStruct->CityName=LineBegin;
- /* MinDist[0] used as temporary dupe CityName flag */
- CityStruct->MinDist[0]=0; /* No City Duplicate Name */
- CityIndex = *LineBegin & 0x1F; /* strip first char */
- CityScan = CharLink[CityIndex];
- while (CityScan != 0)
- {
- NewName=LineBegin;
- OldName=CityScan->CityName;
- NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
- OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
- while (NewChar == OldChar && NewChar != ',')
- {
- NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
- OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
- }
- if (NewChar == OldChar) /* Dupe City Name */
- {
- CityStruct->MinDist[0]=1;
- CityScan->MinDist[0]=1;
- }
- CityScan = CityScan->CityLink;
- } /* chain search for input city name */
- CityStruct->CityLink = CharLink[CityIndex];
- CityStruct->RoadList = 0;
- CharLink[CityIndex]=CityStruct;
- LineBegin=EndLine+1;
- } /* end of comma..City parsing */
- else /* NewLine */
- {
- *EndLine=0;
- if (FoundFlag ==0)
- {
- fprintf(stderr,"*FILE Cities: NO COMMA:\n%s\n",LineBegin);
- CityError=1;
- }
- FoundFlag=0;
- CityStruct->StateName=LineBegin;
- CityStruct->StateDupe=1;
- CityIndex = *LineBegin & 0x1F; /* strip first char */
- CityScan = ChStLink[CityIndex];
- StateFlag = 0;
- while (CityScan != 0 && StateFlag == 0)
- {
- NewName=LineBegin;
- OldName=CityScan->StateName;
- NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
- OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
- while (NewChar == OldChar && NewChar !=0 && OldChar !=0)
- {
- NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
- OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
- }
- if (NewChar == OldChar)
- {
- CityScan->StateDupe=0;
- StateFlag=1;
- }
- CityScan = CityScan->StateLink;
- } /* more states in chain */
- CityStruct->StateLink = ChStLink[CityIndex];
- ChStLink[CityIndex]=CityStruct;
- CityStruct++;
- LineBegin=EndLine+1;
- } /* end of NewLine parsing */
- }
- City9=CityStruct;
- return(CityError);
- }
-
- unsigned short ParseRoutes(DataBlock,BlockSize)
- char *DataBlock;
- long BlockSize;
- {
- struct RouteData *RouteStruct;
- struct CityData *CityScan, *FoundCity;
- unsigned short ErrorFlag, CityColm, CityFlag, CityValue, Multiplier;
- unsigned char CtNameKey, Digit;
- char *LineStart,*LineEnd,*FieldStart,*FieldEnd,*NumPtr;
- ErrorFlag=0;
- RouteStruct = Route0;
- LineStart = DataBlock;
- for (LineEnd=DataBlock;LineEnd < DataBlock+BlockSize;LineEnd++)
- if (*LineEnd == 0x0A)
- {
- *LineEnd=0;
- FieldStart=LineStart;
- for (CityColm=0 ; ErrorFlag==0 && CityColm < 2 ; CityColm++)
- {
- for (FieldEnd=FieldStart ;
- *FieldEnd !=',' && FieldEnd < LineEnd ; FieldEnd++);
- if (*FieldEnd !=',')
- {
- fprintf(stderr,"*FILE Roads: MISSING FIELDS:\n%s\n",LineStart);
- ErrorFlag=1;
- } /* no comma! */
- /* ***** search city name chain */
- CtNameKey = *FieldStart & 0x1F; /* strip first char */
- CityScan = CharLink[CtNameKey];
- CityValue =0;
- while (CityScan != 0 && CityValue ==0)
- {
- if (CityMatch(CityScan,FieldStart)==1)
- {
- CityValue=1;
- FoundCity=CityScan;
- }
- CityScan = CityScan->CityLink;
- } /* chain search for input city name */
- if (CityValue ==0)
- {
- fprintf(stderr,"*FILE Roads: CITY NOT FOUND:\n%s\n",LineStart);
- ErrorFlag=1;
- }
- RouteStruct->CityNum[CityColm]=FoundCity;
- RouteStruct->RLink[CityColm]=FoundCity->RoadList;
- RouteStruct->Colm[CityColm]=FoundCity->Colum;
- FoundCity->RoadList=RouteStruct;
- FoundCity->Colum=CityColm;
- FieldStart=FieldEnd+1;
- } /* two-city loop */
- /* Now grab mileage, time, and Hiway */
- for (CityColm=0 ; ErrorFlag==0 && CityColm < 2 ; CityColm++)
- {
- for (FieldEnd=FieldStart ;
- *FieldEnd !=',' && FieldEnd < LineEnd ; FieldEnd++);
- if (*FieldEnd !=',')
- {
- fprintf(stderr,"FILE Roads: MISSING FIELDS:\n%s????\n",LineStart);
- ErrorFlag=1;
- } /* no comma! */
- CityValue=0 ; CityFlag=0;
- Multiplier=10;
- for (NumPtr=FieldStart ; CityFlag==0 && NumPtr < FieldEnd ;
- NumPtr++)
- {
- Digit=*NumPtr;
- if (Digit >='0' && Digit<='9')
- {
- CityValue=CityValue * Multiplier + Digit - '0';
- Multiplier=10;
- }
- else if (Digit ==':') Multiplier = 6;
- } /* Scan for colon */
- RouteStruct->Dist[CityColm]=CityValue;
- FieldStart=FieldEnd+1;
- } /* Two value paramemters */
- RouteStruct->Hiway=FieldStart;
- RouteStruct++;
- LineStart=LineEnd+1;
- } /* end of routefile scan */
- Route9 = RouteStruct;
- return(ErrorFlag);
- } /* if no error, table build */
-
- #define MENUSIZE 15
- struct CityData * AskCity()
- {
- char *InputString, *InputName, *TableName;
- unsigned char MulKey, CityKey, InChar, CityChar, StateFlag;
- struct CityData *CityStruct, *CityPStruct;
- unsigned short MenuPointer, MenuList;
- static struct CityData *Menu[MENUSIZE];
-
- InputString=InBuff;
- CityKey = *InputString & 0x1F; /* strip first char */
- CityStruct = CharLink[CityKey];
- MulKey = 0; /* Single menu */
- CityPStruct = 0;
- MenuPointer = 0;
- while (CityStruct != 0)
- {
- MenuPointer = 0;
- while ( CityStruct !=0 && MenuPointer < MENUSIZE )
- {
- InputName=InputString;
- TableName=CityStruct->CityName;
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- while (InChar == CityChar && InChar != 0)
- {
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- }
- if (InChar == 0)
- {
- Menu[MenuPointer++]=CityStruct;
- CityPStruct = CityStruct;
- }
- CityStruct = CityStruct->CityLink;
- } /* chain search for input city name */
- if ( MenuPointer > 1)
- {
- for (MenuList=0;MenuList < MenuPointer;MenuList++)
- fprintf(stderr,"%d: %s\n",MenuList+1,Menu[MenuList]->CityName);
- fprintf(stderr,">>> Pick 1 to %d:",MenuPointer);
- if (CityStruct != 0)
- {
- fprintf(stderr," or RETURN for more:");
- CityStruct = CityPStruct;
- MulKey=1; /* Multiple menus */
- }
- else if ( MulKey != 0 )
- {
- fprintf(stderr," or RETURN to restart list:");
- CityStruct = CharLink[CityKey]; /* return to first menu */
- }
- StateFlag=0;
- if ((InputString=gets(InBuff)) != 0)
- {
- InChar=*InputString++;
- while (InChar != 0)
- {
- if (InChar >='0' && InChar<='9')
- StateFlag=StateFlag * 10 + InChar - '0';
- InChar=*InputString++;
- }
- } /* endif, not RETURN */
- if (StateFlag < 1 || StateFlag > MenuPointer) StateFlag=1;
- else CityStruct = 0;
- CityPStruct=Menu[StateFlag-1];
- } /* endif cities to pick from */
- } /* while more cities in list */
- switch (MenuPointer)
- {
- case 0: /* No city match */
- fprintf(stderr,"Province or State: ");
- if ((InputString=gets(InBuff)) == 0) InputString=City0->CityName;
- /* Search for state as input */
- MenuPointer = 0;
- Menu[MenuPointer]=City0;
- CityKey = *InputString & 0x1F; /* strip state first char */
- CityStruct = ChStLink[CityKey];
- if (CityStruct == 0) CityStruct = City0;
- while (CityStruct != 0)
- {
- if (CityStruct->StateDupe == 1) /* one flag set per state*/
- {
- InputName=InputString;
- TableName=CityStruct->StateName;
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- while (InChar == CityChar && InChar != 0)
- {
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- }
- if (InChar == 0)
- if (MenuPointer < MENUSIZE) Menu[MenuPointer++]=CityStruct;
- }
- CityStruct = CityStruct->StateLink;
- } /* more states in chain */
- if (MenuPointer == 0) /* search for first letter state */
- {
- CityStruct = ChStLink[CityKey];
- if (CityStruct == 0) CityStruct = City0;
- while (CityStruct != 0)
- {
- if (CityStruct->StateDupe == 1)
- {
- InputName=InputString;
- TableName=CityStruct->StateName;
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- if (InChar == CityChar)
- if (MenuPointer < MENUSIZE) Menu[MenuPointer++]=CityStruct;
- }
- CityStruct = CityStruct->StateLink;
- } /* while more states in alpha chain */
- } /* endif, single char state search */
- if (MenuPointer > 1)
- {
- for (MenuList=0;MenuList < MenuPointer;MenuList++)
- fprintf(stderr,"%d: %s\n",MenuList+1,Menu[MenuList]->StateName);
- fprintf(stderr,">>> Pick 1 to %d:",MenuPointer);
- StateFlag=0;
- if ((InputString=gets(InBuff)) != 0)
- {
- InChar=*InputString++;
- while (InChar != 0)
- {
- if (InChar >='0' && InChar<='9')
- StateFlag=StateFlag * 10 + InChar - '0';
- InChar=*InputString++;
- }
- if (StateFlag<1 || StateFlag>MenuPointer) StateFlag=1;
- StateFlag -=1;
- }
- CityStruct=Menu[StateFlag];
- } /* endif, pick state from list */
- if (MenuPointer == 0) CityStruct=City0;
- if (MenuPointer == 1) CityStruct=Menu[0];
- /* Now track cities within a given state */
- InputString=CityStruct->StateName;
- CityKey = *InputString & 0x1F; /* strip first char */
- /* Track the state alpha list */
- MulKey=0; /* not multiple menu */
- CityStruct = ChStLink[CityKey];
- CityPStruct = 0;
- MenuPointer = 0;
- while (CityStruct != 0) /* search cities in a state */
- {
- MenuPointer = 0;
- while ( CityStruct != 0 && MenuPointer < MENUSIZE )
- {
- InputName=InputString;
- TableName=CityStruct->StateName;
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- while (InChar == CityChar && InChar != 0)
- {
- InChar=*InputName++; if (InChar > 0x60) InChar -= 0x20;
- CityChar=*TableName++; if (CityChar > 0x60) CityChar -= 0x20;
- }
- if (InChar == CityChar)
- {
- Menu[MenuPointer++]=CityStruct;
- CityPStruct = CityStruct;
- }
- CityStruct = CityStruct->StateLink;
- } /* while more cities and space in menu */
- if (MenuPointer > 1)
- {
- for (MenuList=0;MenuList < MenuPointer;MenuList++)
- fprintf(stderr,"%d: %s\n",MenuList+1,Menu[MenuList]->CityName);
- fprintf(stderr,">>> Pick 1 to %d:",MenuPointer);
- if (CityStruct != 0)
- {
- fprintf(stderr," or RETURN for more:");
- MulKey=1; /* multiple menus */
- CityStruct = CityPStruct;
- }
- else if ( MulKey != 0 )
- {
- fprintf(stderr," or RETURN for to restart list:");
- CityStruct = ChStLink[CityKey]; /* back to first menu */
- }
- StateFlag=0;
- if ((InputName=gets(InBuff)) != 0)
- {
- InChar=*InputName++;
- while (InChar != 0)
- {
- if (InChar >='0' && InChar<='9')
- StateFlag=StateFlag * 10 + InChar - '0';
- InChar=*InputName++;
- } /* while more numeric string */
- } /* endif, non-RETURN */
- } /* endif, pick city within state */
- if (StateFlag < 1 || StateFlag > MenuPointer) StateFlag =1;
- else CityStruct = 0;
- CityPStruct=Menu[StateFlag-1];
- } /* while more cities in state list */
- if (MenuPointer == 0) CityPStruct=City0;
- if (MenuPointer == 1) CityPStruct=Menu[0];
- break;
- case 1: /* unique input city match */
- CityPStruct = Menu[0];
- } /* endswitch, unique or no match */
- return(CityPStruct);
- }
-
- void Navigate(struct CityData *Start,struct CityData *Finish)
- {
- unsigned short Column, Travel;
- unsigned short NextCol, NewCol;
- struct CityData *CityScan;
- struct CityData *BLink, *SearchCity;
- struct CityData *ELink, *FLink, *OtherCity;
- struct RouteData *NextRoute, *NewRoute;
- static unsigned short MiniVal;
- static unsigned short ThisDist[2];
- for (CityScan=City0; CityScan<City9; CityScan++)
- {
- CityScan->WorkList = 0;
- for (Column=0; Column<2; Column++)
- {
- CityScan->MinDist[Column]=9999;
- CityScan->NextCity[Column]=0;
- }
- }
- ELink=Finish;
- MiniVal=0;
- for (Column=0; Column<2; Column++)
- {
- Finish->MinDist[Column]=0;
- ThisDist[Column]=9999;
- }
- SearchCity=Finish;
- while (SearchCity != 0)
- {
- for (Column=0; Column<2; Column++)
- {
- if (SearchCity->MinDist[Column] < Start->MinDist[Column])
- {
- /* if (Column==0)
- * printf("Scanning map at range: %d\n",SearchCity->MinDist[0]); */
- MiniVal=SearchCity->MinDist[Column];
- NextRoute=SearchCity->RoadList;
- NextCol=SearchCity->Colum;
- while (NextRoute != 0)
- {
- OtherCity=NextRoute->CityNum[1-NextCol];
- Travel=MiniVal+NextRoute->Dist[Column];
- if (OtherCity->MinDist[Column] > Travel)
- /* found a new shortest path */
- {
- OtherCity->MinDist[Column]=Travel;
- OtherCity->NextCity[Column]=SearchCity;
- if (OtherCity->WorkList == 0 && ELink!=OtherCity)
- {
- BLink=SearchCity;
- FLink=SearchCity->WorkList;
- while (FLink!=0 && Travel>FLink->MinDist[Column])
- {
- BLink=FLink;
- FLink=BLink->WorkList;
- }
- BLink->WorkList=OtherCity;
- OtherCity->WorkList=FLink;
- if (FLink==0) ELink=OtherCity;
- } /* build new Worklist */
- } /* shorter total distance */
- if (Travel < ThisDist[Column]) ThisDist[Column]=Travel;
- NewRoute=NextRoute->RLink[NextCol];
- NewCol=NextRoute->Colm[NextCol];
- NextRoute=NewRoute;
- NextCol=NewCol;
- } /* Try another route from SearchCity */
- } /* City within target range */
- } /* Next Column */
- BLink=SearchCity->WorkList;
- SearchCity->WorkList=0;
- SearchCity=BLink;
- } /* if SearchCity not zero, go back */
- for (Column=0; Column<2; Column++)
- {
- SearchCity=Start;
- FLink=SearchCity->NextCity[Column];
- while (FLink != 0)
- {
- if (TrailPoint[Column]<TRAILLEN)
- Trail[TrailPoint[Column]++][Column]=FLink;
- SearchCity=FLink;
- FLink=SearchCity->NextCity[Column];
- } /* wend for next FLink */
- } /* next Column */
- }