{Start of file FLYAKITE.PAS *************************************************}
{FLYAKITE - Kite flying program}
{Developed in Apple ][ Pascal and converted to TURBO Pascal 4.0 10/30/88}
(* 13-SEP-81, 1400 HRS *) {Apple ][ date}
{COPYRIGHT (c) 1981-1988 By author: Harry J Smith, Saratoga, CA}
{$I-}
{$R+}
PROGRAM FlyAKite;
USES Printer, Crt, Graph; {Turbo Pascal 4.0 interface}
CONST Revision = 'Last revised: 11/02/88, 0500 hours';
CONST N = 4; NT = 100; EY = 0.005; MaxR = 20;
TYPE
ColorType = 0 .. MaxColors;
DRec = RECORD
CASE INTEGER OF
1: (NR : INTEGER;
HR, OOWR, Fac1R, Fac2R : REAL);
2: (LenR, TR, ZetaR, SAR, FactR, XMR, YMR : REAL);
END;
VAR
Bell : CHAR; {COMMON CONSTANTS}
PiO4, PiO2, Pi, Pi2 : REAL;
T, EMu, Dublu, SA, DPR, Factor, A, OneOW, {COMMON VARIABLES}
S, HP, H, SF, SI, IR,
TXIn, TYIn, Zeta,
RX, Factor1, Factor2,
Scale, XMax, YMax : REAL;
Vector : RECORD
CASE INTEGER OF
1 : (X, Y, TX, TY,
XD, YD, TXD, TYD : REAL);
2 : (XA : PACKED ARRAY[1..4] OF REAL;
XDA : PACKED ARRAY[1..4] OF REAL);
END;
Abort,
Converge : BOOLEAN;
ADat : ARRAY[0..20] OF DRec;
FileName : STRING[20];
PrintName : STRING[8];
OneCh : CHAR; {MAIN PROGRAM VARIABLES}
FDat : FILE OF DRec; {FILES}
OutP : ^TEXT;
Color : ColorType;
Dot2, Dot4,
Device, Mode : INTEGER;
MaxXPix, MaxYPix : WORD;
Palette : PaletteType;
PROCEDURE SavePlot;
VAR
Save : TEXT;
XG, YG,
CBit, NPix : INTEGER;
BEGIN
ASSIGN(Save, 'b:FlyAkite.OUT');
REWRITE(Save); {Text file}
FOR YG:= 0 TO MaxYPix DO BEGIN
WRITE(Save, YG);
CBit:= 0; NPix:= 0;
FOR XG:= 0 TO MaxXPix DO BEGIN
IF GetPixel(XG, YG) = CBit THEN NPix:= NPix + 1
ELSE BEGIN
WRITE(Save, ' ', NPix);
CBit:= (CBit + 1) MOD 2; NPix:= 1;
END
END;
IF NPix <> 0 THEN BEGIN
WRITE(Save, ' ', NPix);
END;
WRITELN(Save);
END;
CLOSE(Save);
END; {SavePlot}
PROCEDURE PrintPlot;
VAR
XG, YG,
Line, Bit, Dot,
Out1, Out2, Out3 : INTEGER;
C1, C2, C3 : CHAR;
BEGIN
WRITELN(Lst);
WRITELN(Lst);
WRITELN(Lst);
FOR Line:= 0 TO MaxYPix DIV 12 DO BEGIN
WRITE(Lst, CHR(27), '*', CHR(39), CHR(0), CHR(5)); {Start graphics mode}
YG:= 12 * Line;
FOR XG:= 0 TO MaxXPix DO BEGIN
Out1:= 0; Out2:= 0; Out3:= 0;
FOR Bit:= 0 TO 3 DO BEGIN
Dot := GetPixel(XG, YG + Bit); IF Dot <> 0 THEN Dot:= 3;
Out1:= 4 * Out1 + Dot;
Dot := GetPixel(XG, YG + Bit + 4); IF Dot <> 0 THEN Dot:= 3;
Out2:= 4 * Out2 + DOT;
Dot := GetPixel(XG, YG + Bit + 8); IF Dot <> 0 THEN Dot:= 3;
Out3:= 4 * Out3 + Dot;
END;
C1:= CHR(Out1); C2:= CHR(Out2); C3:= CHR(Out3);
WRITE(Lst, C1, C2, C3, C1, C2, C3);
END;
WRITE(Lst, CHR(27), 'J', CHR(24), CHR(13)); {24 dot line feed}
END;
WRITELN(Lst);
WRITELN(Lst);
WRITELN(Lst);
END; {PrintPlot}
PROCEDURE MoveToL(X, Y : INTEGER);
BEGIN
MoveTo(X, MaxYPix - Y);
END; {MoveToL}
PROCEDURE LineToL(X, Y : INTEGER);
BEGIN
LineTo(X, MaxYPix - Y);
END; {LineToL}
FUNCTION ForceColor(Color : ColorType) : ColorType;
BEGIN
Color:= Color MOD Palette.Size;
IF Color = 0 THEN Color:= 1;
SetColor(Color);
ForceColor:= Color;
END; {ForceColor}
FUNCTION ATan2(Y, X : REAL) : REAL;
VAR Temp : REAL;
BEGIN
IF X = 0 THEN BEGIN
IF Y > 0 THEN ATan2:= PiO2
ELSE IF Y < 0 THEN ATan2:= -PiO2
ELSE ATan2:= 0;
END
ELSE BEGIN
Temp:= ARCTAN(Y / X);
IF X > 0 THEN ATan2:= Temp
ELSE
IF Y >= 0 THEN ATan2:= Temp + Pi
ELSE ATan2:= Temp - Pi;
END;
END; {ATan2}
PROCEDURE Output2;
VAR R : REAL;
BEGIN
WITH Vector DO BEGIN
R:= SQRT(SQR(X) + SQR(Y));
A:= DPR * ATan2(Y, X);
SA:= DPR * ATan2(TY, TX);
WRITELN(OutP^, S:7:1, X:8:1, Y:8:1, TX:8:2, TY:8:2, T:8:2,
SA:8:2, A:8:2, R:8:1, Factor:8:2);
END;
END; {Output2}
PROCEDURE RHSF; {Evaluate the Right Hand Side Function}
BEGIN
WITH Vector DO BEGIN
T:= SQRT(SQR(TX) + SQR(TY));
XD:= TX / T; YD:= TY / T;
TXD:= -EMu * ABS(YD * SQR(YD));
TYD:= Dublu + EMu * ABS(YD) * YD * XD;
END;
END; {RHSF}
PROCEDURE RKutta(VAR S : REAL; H : REAL); {MUST CALL RHSF BEFORE RKutta}
{Runge-Kutta method of integration of ordinary differential equations}
VAR
EK1, EK2, EK3, XI : ARRAY[1..N] OF REAL;
SR : REAL;
I : INTEGER;
BEGIN
WITH Vector DO BEGIN
SR:= S;
FOR I:= 1 TO N DO BEGIN
XI[I]:= XA[I];
EK1[I]:= H * XDA[I];
XA[I]:= XI[I] + EK1[I] / 2.0;
END;
S:= SR + H / 2.0;
RHSF;
FOR I:= 1 TO N DO BEGIN
EK2[I]:= H * XDA[I];
XA[I]:= XI[I] + EK2[I] / 2.0;
END;
RHSF;
FOR I:= 1 TO N DO BEGIN
EK3[I]:= H * XDA[I];
XA[I]:= XI[I] + EK3[I];
END;
S:= SR + H;
RHSF;
FOR I:= 1 TO N DO BEGIN
XA[I]:= XI[I] +
(EK1[I] + 2.0 * EK2[I] + 2.0 * EK3[I] + H * XDA[I]) / 6.0;
END;
END;
END; {RKutta}
PROCEDURE AIRK(VAR S : REAL; SI, H : REAL); {Advance Integration by RKutta}
LABEL ExitAIRK;
BEGIN
IF SI = S THEN GoTo ExitAIRK;
H:= ABS(H);
IF SI < S THEN H:= -H;
WHILE ABS(SI - S) > ABS(H) DO BEGIN
RKutta(S, H);
RHSF;
END;
H:= SI - S;
IF H <> 0 THEN RKutta(S, H);
S:= SI;
ExitAIRK:
END; {AIRK}
FUNCTION Functn(RX : REAL) : REAL;
BEGIN
Factor:= RX;
EMu:= Dublu * Factor;
S:= 0;
WITH Vector DO BEGIN
X:= 0; Y:= 0;
TX:= TXIN; TY:= TYIN;
END;
RHSF;
AIRK(S, SI, H);
RHSF;
Output2;
Functn:= A - Zeta;
END; {Functn}
PROCEDURE Root(X1, X2, EY : REAL; NT : INTEGER; VAR X : REAL);
LABEL ExitRoot;
VAR
Y, Y1, Y2, P : REAL;
I : INTEGER; Ch : CHAR;
BEGIN
Abort:= FALSE;
Converge:= FALSE;
Y2:= Functn(X2);
X:= X1;
Y:= Functn(X);
FOR I:= 1 TO NT DO BEGIN
IF ABS(Y) > ABS(Y2) THEN BEGIN
X1:= X; Y1:= Y;
END
ELSE BEGIN
X1:= X2; Y1:= Y2;
X2:= X; Y2:= Y;
END;
IF Y1 <> Y2 THEN BEGIN
P:= Y2 / (Y1 - Y2);
IF P > 1.0 THEN P:= 1.0;
END
ELSE
P:= 1.0;
X:= X2 + P * (X2 - X1);
Y:= Functn(X);
IF ABS(Y) <= EY THEN BEGIN
WRITELN(OutP^, 'CONVERGED'); Converge:= TRUE; GoTo ExitRoot;
END;
REPEAT
IF KEYPRESSED THEN BEGIN
Ch:= ReadKey;
IF Ch = '0' THEN BEGIN
WRITELN(OutP^, 'MANUALLY ABORTED BEFORE CONVERGANCE');
Abort:= TRUE; GoTo ExitRoot;
END;
END;
UNTIL NOT KEYPRESSED;
END;
WRITELN('DID NOT CONVERGE IN ', NT, ' ITERATIONS');
ExitRoot:
END; {Root}
PROCEDURE GetCase(N : INTEGER);
LABEL ExitGetCase;
BEGIN
WITH ADat[N] DO BEGIN
SI:= LenR; T:= TR; Zeta:= ZetaR; SA:= SAR; Factor:= FactR;
XMax:= XMR; YMax:= YMR;
END;
WITH ADat[0] DO BEGIN
Factor1:= Fac1R; Factor2:= Fac2R; OneOW:= OOWR; H:= HR;
END;
TYIN:= T * SIN(SA / DPR);
TXIN:= T * COS(SA / DPR);
S:= 0;
WITH Vector DO BEGIN
X:= 0; Y:= 0; TX:= TXIN; TY:= TYIN;
END;
IF OneOW <= 0 THEN GoTo ExitGetCase;
Dublu:= 1.0 / OneOW;
EMu:= Dublu * Factor;
RHSF;
ExitGetCase:
END; {GetCase}
FUNCTION GetReal(LO, HI : REAL) : REAL;
VAR R : REAL; OK : BOOLEAN;
BEGIN
OK:= FALSE;
REPEAT
READLN(R);
IF (IORESULT = 0) AND (R >= LO) AND (R <= HI) THEN OK:= TRUE
ELSE WRITE(Bell);
UNTIL OK;
GetReal:= R;
END; {GetReal}
PROCEDURE Perp(DOTS : INTEGER);
VAR
XP, YP, XL, YL : INTEGER;
R : REAL;
BEGIN
XP:= GetX; YP:= MaxYPix - GetY;
WITH Vector DO BEGIN
R:= SQRT(SQR(TX) + SQR(TY));
XL:= TRUNC(XP + DOTS * -TY / R);
YL:= TRUNC(YP + DOTS * TX / R);
END;
MoveToL(XL, YL);
XL:= XP + XP - XL;
YL:= YP + YP - YL;
LineToL(XL, YL);
MoveToL(XP, YP);
END; {Perp}
PROCEDURE Grid(XZ, YZ : INTEGER; Scale : REAL);
VAR
ScaleT : REAL; N1, N2, N3, N4, I : INTEGER;
BEGIN
WITH Vector DO BEGIN
ScaleT:= 1000.0 * Scale;
N1:= -TRUNC((XZ) / ScaleT);
N2:= TRUNC((MaxXPix - XZ) / ScaleT);
N3:= -TRUNC((YZ) / ScaleT);
N4:= TRUNC((MaxYPix - YZ) / ScaleT);
MoveToL(0, 0);
SetColor(WHITE); TX:= 1; TY:= 0;
FOR I:= N1 TO N2 DO BEGIN
LineToL(TRUNC(I * ScaleT) + XZ, 0); Perp(Dot4);
END;
LineToL(MaxXPix, 0); TX:= 0; TY:= 1;
FOR I:= N3 TO N4 DO BEGIN
LineToL(MaxXPix, TRUNC(I * ScaleT) + YZ); Perp(Dot4);
END;
LineToL(MaxXPix, MaxYPix); TX:= -1; TY:= 0;
FOR I:= N2 DOWNTO N1 DO BEGIN
LineToL(TRUNC(I * ScaleT) + XZ, MaxYPix); Perp(Dot4);
END;
LineToL(0, MaxYPix); TX:= 0; TY:= -1;
FOR I:= N4 DOWNTO N3 DO BEGIN
LineToL(0, TRUNC(I * ScaleT) + YZ); Perp(Dot4);
END;
LineToL(0, 0);
END;
END; {Grid}
PROCEDURE PlotSt;
LABEL ExitPlotSt;
VAR
Ch : CHAR;
MinH, MaxH,
ScaleF, IR, SV,
Scale : REAL;
ScaleX : REAL;
XP, YP,
XZ, YZ, CN : INTEGER;
St : STRING;
PROCEDURE PlotM(VAR S : REAL; SI, H : REAL);
LABEL ExitPlotM;
VAR R, HP : REAL;
PROCEDURE CompH;
BEGIN
WITH Vector DO R:= T / SQRT(SQR(TXD) + SQR(TYD));
HP:= 0.5 * SQRT(ScaleF * R);
IF HP > MaxH THEN HP:= MaxH
ELSE IF HP < MinH THEN H:= MinH;
IF H < 0 THEN HP:= -HP;
END; {CompH}
PROCEDURE Plot1;
BEGIN
WITH Vector DO BEGIN
XP:= ROUND(X * Scale) + XZ;
YP:= ROUND(Y * Scale) + YZ;
END;
LineToL(XP, YP);
END; {Plot1}
BEGIN {PlotM}
IF SI < S THEN H:= -H;
CompH;
WHILE ABS(SI - S) > ABS(HP) DO BEGIN
RKutta(S, HP); RHSF; Plot1; CompH;
IF (XP < 0) OR (YP > MaxYPix) THEN GoTo ExitPlotM;
END;
H:= SI - S;
IF H <> 0 THEN BEGIN
RKutta(S, H); RHSF; Plot1;
END;
S:= SI;
ExitPlotM:
END; {PlotM}
BEGIN {PlotSt}
ClrScr; WRITELN;
WRITELN('Note: Type an "S" after the plot to save it to B:FLYAKITE.OUT');
WRITELN(' Type a "P" after the plot to print it on LQ-2500 printer');
WRITELN;
WRITELN(
'INPUT 1 <= L <= ', ADat[0].NR, ' LINE NUMBER TO PLOT OR 0 TO EXIT');
CN:= TRUNC(GetReal(0, ADat[0].NR));
IF CN = 0 THEN GoTo ExitPlotSt;
GetCase(CN);
Dot2:= Round(MaxYPix / 100.0);
Dot4:= Dot2 + Dot2;
Scale:= 0.9 * MaxYPix / YMax; ScaleX:= 0.9 * MaxXPix / XMax;
IF Scale > ScaleX THEN Scale:= ScaleX;
ScaleF:= TRUNC(1.0 + 1.0 / Scale);
IF ScaleF < 6 THEN ScaleF:= 6;
WRITELN('INPUT SCALE IN FEET/DOT OR 0 IF ', ScaleF:3:1, ' IS OK');
ScaleX:= GetReal(0, 1000000.0);
IF ScaleX <> 0 THEN ScaleF:= ScaleX;
Scale:= 1.0 / ScaleF;
MinH:= ScaleF; MaxH:= H;
XZ:= ROUND((MaxXPix - XMax * Scale) / 2.0);
YZ:= ROUND((MaxYPix - YMax * Scale) / 2.0);
WRITELN('INPUT 0.1 <= X <= ', MaxXPix,
' DOT POSITION TO PLOT X=0 OR 0 IF ', XZ, ' IS OK');
IR:= GetReal(0, MaxXPix);
IF IR <> 0 THEN XZ:= ROUND(IR);
WRITELN('INPUT 0.1 <= Y <= ', MaxYPix,
' DOT POSITION TO PLOT Y=0 OR 0 IF ', YZ, ' IS OK');
IR:= GetReal(0, MaxYPix);
IF IR <> 0 THEN YZ:= ROUND(IR);
SetGraphMode(Mode);
SetBkColor(Black);
Color:= ForceColor(White);
MoveToL(XZ, YZ);
Perp(Dot4);
WHILE SI > S+1000.0 DO BEGIN
PlotM(S, S+1000.0, H); Perp(Dot2);
END;
SV:= S+1000.0;
PlotM(S, SI, H); Perp(Dot4);
PlotM(S, SV, H); Perp(Dot2);
REPEAT
PlotM(S, S+1000.0, H);
IF (XP > -1) AND (YP <= MaxYPix) THEN Perp(Dot2);
UNTIL (XP < 0) OR (YP > MaxYPix);
GetCase(CN); MoveToL(XZ, YZ); SetColor(WHITE);
REPEAT
PlotM(S, S - 1000.0, H);
IF (XP > -1) AND (YP <= MaxYPix) THEN Perp(Dot2);
UNTIL (XP < 0) OR (YP > MaxYPix);
Grid(XZ, YZ, Scale);
Color:= ForceColor(Yellow);
XP:= 3 + Dot4; YP:= 3 + Dot4; MoveTo(XP, YP);
OutText(FileName);
OutText(' Flight # '); Str(CN, St); OutText(St);
YP:= YP + Dot2 + TextHeight('M'); MoveTo(XP, YP);
OutText('Scale = '); Str(ScaleF:1:1, St); OutText(St);
OutText(' Ft/Pixel 1000 Ft/Tic');
YP:= YP + Dot2 + TextHeight('M'); MoveTo(XP, YP);
OutText('X=0 @ '); Str(XZ, St); OutText(St);
OutText(' Y=0 @ '); Str(YZ, St); OutText(St);
OutText(' of '); Str(MaxXPix + 1, St); OutText(St);
OutText('x'); Str(MaxYPix + 1, St); OutText(St);
OutText(' Pixels');
Ch:= ReadKey; Ch:= UpCase(Ch);
IF Ch = 'S' THEN SavePlot;
IF Ch = 'P' THEN PrintPlot;
RestoreCrtMode; {TEXTMODE;}
ExitPlotSt:
END; {PlotSt}
PROCEDURE ClearData;
VAR I : INTEGER;
BEGIN
WITH ADat[0] DO BEGIN
NR:= 1; HR:= 600; OOWR:= 8700.0; Fac1R:= 20.0; Fac2R:= 35.0;
END;
WITH ADat[1] DO BEGIN
LenR:= 0; TR:= 0; ZetaR:= 0; SAR:= 0; FactR:= 0; XMR:= 0; YMR:= 0;
END;
FOR I:= 2 TO MaxR DO
ADat[I]:= ADat[1];
END; {ClearData}
PROCEDURE CkIO(VAR J : INTEGER);
VAR Ch : CHAR;
BEGIN
J:= IORESULT;
IF J <> 0 THEN BEGIN
WRITELN('IORESULT = ', J);
{ CASE J OF
1: WRITELN('BAD BLOCK, PARITY ERROR (CRC)');
3: WRITELN('BAD MODE, ILLEGAL OPERATION');
8: WRITELN('NO ROOM, INSUFFICIENT SPACE');
9: WRITELN('NO UNIT, NO SUCH VOLUMN ON LINE');
10: WRITELN('NO FILE, NO SUCH FILE ON VOLUME');
16: WRITELN('WRITE PROTECT ERROR');
END;
} Ch:= ReadKey;
END;
END; {CkIO}
PROCEDURE Init;
VAR I : INTEGER;
BEGIN
TextBackground(Black);
TextColor(Yellow);
{ Device:= CGA; Mode:= CGAHi; }
Device:= Detect; Mode:= 0;
InitGraph(Device, Mode, '');
MaxXPix:= GetMaxX; MaxYPix:= GetMaxY;
GetPalette(Palette);
IF Palette.Size < 2 THEN Palette.Size:= 2;
RestoreCrtMode;
ClrScr;
WRITELN;
WRITELN('Program FLYAKITE - A kite flying program');
WRITELN(Revision);
WRITELN('COPYRIGHT (c) 1981-1988 By author: Harry J Smith, Saratoga, CA');
WRITELN;
WRITELN('MEMAVAIL = ', MEMAVAIL);
WRITELN;
WRITELN('Device, Mode, MaxX, MaxY = ',
Device, ' ', Mode, ' ', MaxXPix, ' ', MaxYPix);
WRITE('Palette.Size: Colors = ', Palette.Size, ':');
FOR I:= 0 TO Palette.Size - 1 DO
WRITE(' ', Palette.Colors[I]);
WRITELN;
PiO4:= ArcTan(1.0);
PiO2:= 2.0 * PiO4;
Pi:= 2.0 * PiO2;
Pi2:= 2.0 * Pi;
DPR:= 180.0 / Pi;
Bell:= CHR(7);
FileName:= 'NOT-ENTERED-YET';
PrintName:= 'CONSOLE:';
OutP:= @Output;
ClearData;
WRITELN('HIT ANY KEY TO CONTINUE');
OneCh:= ReadKey;
END; {Init}
PROCEDURE ScrHed;
BEGIN
ClrScr;
WRITELN('OUTPUT TOGGLE SET TO ', PrintName,
' FLIGHT FILE NAME IS ', FileName);
WRITELN;
END; {ScrHed}
PROCEDURE Scr1;
BEGIN
ScrHed;
WRITELN('0. QUIT, RETURN TO THE SYSTEM');
WRITELN('1. TOGGLE PRINTER: / CONSOLE:');
WRITELN('2. ENTER / EDIT / UPDATE FLIGHT FILES');
WRITELN('3. COMPUTE WIND FACTORS FOR FLIGHT DATA FILE');
WRITELN('4. PLOT STRING PROFILE ON HIRES SCREEN');
WRITELN('5. SELECT GRAFMODE');
WRITELN('6. SELECT TEXTMODE');
GOTOXY(1, 23);
WRITE('SELECT OPTION ');
END; {Scr1}
PROCEDURE TogglePr;
BEGIN
IF PrintName = 'CONSOLE:'
THEN OutP:= @Lst
ELSE OutP:= @Output;
IF PrintName = 'CONSOLE:'
THEN PrintName:= 'PRINTER:'
ELSE PrintName:= 'CONSOLE:';
END; {TogglePr}
PROCEDURE DBM;
VAR Ch : CHAR;
PROCEDURE ScrDBM;
BEGIN
ScrHed;
WRITELN('0. EXIT ENTER / EDIT / UPDATE');
WRITELN('1. TOGGLE PRINTER: / CONSOLE:');
WRITELN('2. ENTER NAME OF FLIGHT FILE LIKE A:81DEC31A.FLY');
WRITELN('3. LOAD FLIGHT FILE FROM DISK');
WRITELN('4. STORE FLIGHT FILE ONTO DISK');
WRITELN('5. CLEAR ALL FLIGHT DATA IN MAIN MEMORY');
WRITELN('6. ENTER PARAMETERS FOR THIS SET OF FLIGHTS');
WRITELN('7. ENTER FLIGHT DATA');
WRITELN('8. DISPLAY FLIGHT DATA');
GOTOXY(1, 23);
WRITE('SELECT OPTION ');
END; {ScrDBM}
PROCEDURE EnterName;
VAR Ch : CHAR; I : INTEGER;
BEGIN
ScrHed;
WRITELN('INPUT FLIGHT FILE NAME');
READLN(FileName);
FOR I:= 1 TO Length(FileName) DO
FileName[I]:= UpCase(FileName[I]);
END; {EnterName}
PROCEDURE LoadFile;
LABEL ExitLoadFile;
VAR I, J : INTEGER; Ch : CHAR;
BEGIN
REPEAT
ScrHed;
WRITELN('DO YOU WISH TO LOAD FLIGHT FILE FROM DISK? (Y/N)');
Ch:= ReadKey; Ch:= UpCase(Ch);
UNTIL (Ch = 'Y') OR (Ch = 'N');
WRITELN;
IF Ch = 'Y' THEN BEGIN
ClearData;
Assign(FDat, FileName);
RESET(FDat); CkIO(J);
IF J=0 THEN BEGIN
READ(FDat, ADat[0]); CkIO(J);
IF J <> 0 THEN GoTo ExitLoadFile;
FOR I:= 1 TO ADat[0].NR DO BEGIN
READ(FDat, ADat[I]); CkIO(J);
IF J <> 0 THEN GoTo ExitLoadFile;
END;
CLOSE(FDat); CkIO(J);
END;
END;
ExitLoadFile:
END; {LoadFile}
PROCEDURE StoreFile;
LABEL ExitStoreFile;
VAR I, J : INTEGER; Ch : CHAR;
BEGIN
REPEAT
ScrHed;
WRITELN('DO YOU WISH TO STORE FLIGHT FILE ONTO DISK? (Y/N)');
Ch:= ReadKey; Ch:= UpCase(Ch);
UNTIL (Ch = 'Y') OR (Ch = 'N');
WRITELN;
IF Ch = 'Y' THEN BEGIN
Assign(FDat, FileName);
REWRITE(FDat); CkIO(J);
IF J=0 THEN BEGIN
FOR I:= 0 TO ADat[0].NR DO BEGIN
WRITE(FDat, ADat[I]); CkIO(J);
IF J <> 0 THEN GoTo ExitStoreFile;
END;
CLOSE(FDat); CkIO(J);
END;
END;
ExitStoreFile:
END; {StoreFile}
PROCEDURE ClearTest;
VAR Ch : CHAR;
BEGIN
REPEAT
ClrScr;
WRITELN('DO YOU WISH TO CLEAR ALL FLIGHT DATA IN MAIN MEMORY? (Y/N)');
Ch:= ReadKey; Ch:= UpCase(Ch);
UNTIL (Ch = 'Y') OR (Ch = 'N');
IF Ch = 'Y' THEN ClearData;
END; {ClearTest}
PROCEDURE DispData;
VAR CN : INTEGER; Ch : CHAR;
BEGIN
ClrScr;
WRITELN(OutP^); WRITELN(OutP^);
WRITELN(OutP^, 'FLIGHT DATA FILE ', FileName);
WRITELN(OutP^); WRITELN(OutP^, ' FAC1 FAC2 ONEOW H');
WITH ADat[0] DO
WRITELN(OutP^, Fac1R:8:2, Fac2R:8:2, OOWR:8:1, HR:8:1);
WRITELN(OutP^); WRITELN(OutP^,
' LEN T ZETA SA FACTOR XKITE YKITE FLIGHT');
FOR CN:= 1 TO ADat[0].NR DO
WITH ADat[CN] DO
WRITELN(OutP^, LenR:7:1, TR:8:2, ZetaR:8:2, SAR:8:2, FactR:8:2,
XMR:8:1, YMR:8:1, CN:6);
WRITELN(OutP^, 'EOF');
IF PrintName = 'CONSOLE:' THEN Ch:= ReadKey;
END; {DispData}
PROCEDURE EnterHed;
VAR Ch : CHAR;
PROCEDURE ScreH;
BEGIN
ScrHed;
WITH ADat[0] DO BEGIN
WRITELN('0. EXIT ENTERING PAPAMERERS');
WRITELN('1. INPUT INTEGRATION STEP SIZE, H = ',HR:8:1);
WRITELN('2. INPUT LENGTH OF ONE POUND OF STRING, 1/W = ',OOWR:8:1);
WRITELN('3. INPUT LOW GEUSS AT WIND FACTOR, FACTOR1 = ',Fac1R:8:2);
WRITELN('4. INPUT HIGH GUESS AT WIND FACTOR, FACTOR2 = ',Fac2R:8:2);
END;
GOTOXY(1, 23);
WRITE('SELECT OPTION ');
END; {ScreH}
PROCEDURE InH;
BEGIN
WITH ADat[0] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT H, INTEGRATION INTERVAL SIZE IN FEET OF STRING LENGTH');
WRITELN(' OR 0 IF ', HR:3:1, ' IS OK');
IR:= GetReal(0, 10000);
IF IR <> 0 THEN HR:= IR;
END;
END; {InH}
PROCEDURE InOOW;
BEGIN
WITH ADat[0] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT 1/W, LENGTH IN FEET OF ONE POUND OF KITE STRING USED');
WRITELN(' OR 0 IF ', OOWR:3:1, ' IS OK');
IR:= GetReal(0, 100000.0);
IF IR <> 0 THEN OOWR:= IR;
END;
END; {InOOW}
PROCEDURE InFact1;
BEGIN
WITH ADat[0] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT FACTOR1, LOW GEUSS AT WIND FACTOR');
WRITELN(' OR 0 IF ', Fac1R:4:2, ' IS OK');
IR:= GetReal(0, 100000.0);
IF IR <> 0 THEN Fac1R:= IR;
END;
END; {InFact1}
PROCEDURE InFact2;
BEGIN
WITH ADat[0] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT FACTOR2, HIGH GEUSS AT WIND FACTOR');
WRITELN(' OR 0 IF ', Fac2R:4:2, ' IS OK');
IR:= GetReal(0, 100000.0);
IF IR <> 0 THEN Fac2R:= IR;
END;
END; {InFact2}
BEGIN {EnterHed}
REPEAT
ScreH;
Ch:= ReadKey;
CASE Ch OF
'1': InH;
'2': InOOW;
'3': InFact1;
'4': InFact2;
END;
UNTIL Ch = '0';
END; {EnterHed}
PROCEDURE EnterData;
VAR CN : INTEGER; Ch : CHAR;
PROCEDURE ScrDat;
BEGIN
ScrHed;
WRITELN(ADat[0].NR, ' LINES ENTERED, ON LINE ', CN, ' NOW');
WRITELN;
WITH ADat[CN] DO BEGIN
WRITELN('0. EXIT ENTERING FLIGHT DATA');
WRITELN('1. INPUT LENTH OF STRING OUT, LEN = ', LenR:8:1);
WRITELN('2. INPUT TENSION IN STRING, T = ', TR:8:2);
WRITELN('3. INPUT ANGLE TO KITE, ZETA = ', ZetaR:8:2);
WRITELN('4. INPUT ANGLE OF STRING, SAR = ', SAR:8:2);
WRITELN('5. ADD A NEW LINE OF DATA');
WRITELN('6. DELETE A LINE OF DATA');
WRITELN('7. ADVANCE TO NEXT LINE IN CYCLE');
END;
GOTOXY(1, 23);
WRITE('SELECT OPTION ');
END; {ScrDat}
PROCEDURE InLen;
BEGIN
WITH ADat[CN] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT LEN, LENTH OF STRING OUT IN FEET');
WRITELN(' OR 0 IF ', LenR:3:1, ' IS OK FOR LINE ', CN);
IR:= GetReal(0, 100000.0);
IF IR <> 0 THEN LenR:= IR;
END;
END; {InLen}
PROCEDURE InT;
BEGIN
WITH ADat[CN] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT T, TENSION IN STRING AT FLYER IN POUNDS');
WRITELN(' OR 0 IF ', TR:4:2, ' IS OK FOR LINE ', CN);
IR:= GetReal(0, 10000);
IF IR <> 0 THEN TR:= IR;
END;
END; {InT}
PROCEDURE InZeta;
BEGIN
WITH ADat[CN] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT ZETA, ELEVATION ANGLE TO KITE IN DEGREES');
WRITELN(' OR 0 IF ', ZetaR:4:2, ' IS OK FOR LINE ', CN);
IR:= GetReal(-360, 360);
IF IR <> 0 THEN ZetaR:= IR;
IF IR = 360 THEN ZetaR:= 0;
END;
END; {InZeta}
PROCEDURE InSA;
BEGIN
WITH ADat[CN] DO BEGIN
ClrScr;
WRITELN; WRITELN(
'INPUT SA, ANGLE OF STRING AT FLYER IN DEGREES');
WRITELN(' OR 0 IF ', SAR:4:2, ' IS OK FOR LINE ', CN);
IR:= GetReal(-360, 360);
IF IR <> 0 THEN SAR:= IR;
IF IR = 360 THEN SAR:= 0;
END;
END; {InSA}
PROCEDURE AddLine;
BEGIN
WITH ADat[0] DO BEGIN
IF NR < MaxR THEN NR:= NR+1;
CN:= NR;
END;
END; {AddLine}
PROCEDURE DelLine;
VAR I, J : INTEGER;
BEGIN
J:= ADat[0].NR;
IF J > 1 THEN BEGIN
FOR I:= CN TO J - 1 DO
ADat[I]:= ADat[I+1];
WITH ADat[J] DO BEGIN
LenR:= 0; TR:= 0; ZetaR:= 0; SAR:= 0;
FactR:= 0; XMR:= 0; YMR:= 0;
END;
J:= J - 1; ADat[0].NR:= J;
END;
IF CN > J THEN CN:= J;
END; {DelLine}
PROCEDURE AdvLine;
BEGIN
IF CN >= ADat[0].NR THEN CN:= 1
ELSE CN:= CN+1;
END; {AdvLine}
BEGIN {EnterData}
CN:= 1;
IF ADat[0].NR = 0
THEN ADat[0].NR:= 1;
REPEAT
ScrDat;
Ch:= ReadKey;
CASE Ch OF
'1': InLen;
'2': InT;
'3': InZeta;
'4': InSA;
'5': AddLine;
'6': DelLine;
'7': AdvLine;
END;
UNTIL Ch = '0';
END; {EnterData}
BEGIN {DBM}
REPEAT
ScrDBM;
Ch:= ReadKey;
CASE Ch OF
'1': TogglePr;
'2': EnterName;
'3': LoadFile;
'4': StoreFile;
'5': ClearTest;
'6': EnterHed;
'7': EnterData;
'8': DispData;
END;
UNTIL Ch = '0';
END; {DBM}
PROCEDURE CompFact;
VAR CN, CNMax : INTEGER; Ch : CHAR;
BEGIN
ClrScr;
WRITELN('INPUT FIRST FLIGHT NUMBER IN FILE TO PROCESS <= ', ADat[0].NR);
CN:= TRUNC(GetReal(1, ADat[0].NR));
WRITELN('INPUT LAST FLIGHT NUMBER IN FILE TO PROCESS <= ', ADat[0].NR);
CNMax:= TRUNC(GetReal(CN, ADat[0].NR));
WRITELN('TYPE 0 TO ABORT COMPUTING FACTORS');
WRITELN(OutP^); WRITELN(OutP^);
WRITELN(OutP^, 'COMPUTE WIND FACTORS FOR FLIGHT FILE ',
FileName, ' FOR FLIGHT ', CN, ' THRU ', CNMax);
REPEAT
GetCase(CN);
IF( OneOW > 0) AND (T > 0) THEN BEGIN
WRITELN(OutP^); WRITELN(OutP^); WRITELN(OutP^,
' LEN T ZETA SA FAC1 FAC2 ONEOW H FLIGHT');
WRITELN(OutP^, SI:7:1, T:8:2, Zeta:8:2, SA:8:2, Factor1:8:2,
Factor2:8:2, OneOW:8:1, H:8:1, CN:6);
WRITELN(OutP^); WRITELN(OutP^,
' S X Y TX TY T SA ZETA',
' R FACTOR');
Root(Factor1, Factor2, EY, NT, RX);
WITH ADat[CN], Vector DO BEGIN
IF Converge THEN BEGIN
XMR:= X; YMR:= Y; FactR:= Factor;
END ELSE BEGIN
XMR:= 0; YMR:= 0; FactR:= 0;
END;
END;
END;
CN:= CN+1;
UNTIL (CN > CNMax) OR (OneOW <= 0) OR Abort;
IF PrintName = 'CONSOLE:' THEN Ch:= ReadKey;
END;
BEGIN {FlyAKite}
Init;
REPEAT
REPEAT
Scr1;
OneCh:= ReadKey;
CASE OneCh OF
'1': TogglePr;
'2': DBM;
'3': CompFact;
'4': PlotSt;
'5': BEGIN SetGraphMode(Mode); SetBkColor(Black); END;
'6': RestoreCrtMode;
END;
UNTIL OneCh = '0';
REPEAT
ClrScr;
WRITELN('DO YOU WISH TO RETURN TO THE SYSTEM? (Y/N)');
OneCh:= ReadKey; OneCh:= UpCase(OneCh);
UNTIL (OneCh = 'Y') OR (OneCh = 'N');
UNTIL OneCh = 'Y';
ClrScr;
END. {FlyAKite}
Return to FlyAKite Program
Return to Harry's Home Page