'         "TRACKER8"       Satellite tracking program with graphics
'         ---------
'
'Version 1.03 : Last mod 7th May 1990 by ACH
'
'(C) 1988 Mr J R Miller G3RUH
'(C) 1988 Mr A C Hewat  G8NTH
'
'V 1.00: First version ; original concept with limited graphics.
'V 1.01: Multi satellite display and better graphics.
'V 1.02: Most of the bugs fixed!
'V 1.03: Minor changes to itteration routine. Display changed.

'Saderial Time  (Not for this program, the only place I could find to
'1988 0.27469296                       put it so it wont get lost!)
'1989 0.27676777
'1990 0.27610467
'1991 0.27544157
'1992 0.27477847
'1993 0.27685328
'1994 0.27619018
'1995 0.27552708
'1996 0.27486399
'1997 0.27693880
'1998 0.27627570
'1999 0.27561260

DEFDBL a-z
CLEAR,80000&,8000&
DIM C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13(16),SatName$(16),stepSize(16),ObjectShape$(16)
DIM days&(12)

Main:
predictionTime = 0
echo = 0              
lastChoise = 1
menuItem = 1
oldSatellite = 1
oldChoise1 = 1
oldChoise2 = 1
GOSUB ScreenSetup
GOSUB Ephemeris
GOSUB Constants
GOSUB TodayDate
FOR satellite = 1 TO 10
 GOSUB ObjectShape
NEXT satellite
OPEN "scrn:" FOR OUTPUT AS #2
OPEN "com1:1200,n,7,2" FOR OUTPUT AS #4
LOCATE 27,1: PRINT SPACE$(78): PRINT SPACE$(78): PRINT SPACE$(78): PRINT SPACE$(78);
LOCATE 28,1
PRINT "Satellite  Lat  Long  Height   MA  EL   AZ   Range       Mode  Squint  Orbit";
                                                                          
Quit = -1
realTimeFlag = -1
WHILE Quit
    FOR satellite = 1 TO 10
      GOSUB SatelliteConstants 
      GOSUB DisplayTimePos
      GOSUB CalcthenDisplay
      GOSUB DisplaySatInfo
      IF echo = 1 THEN GOSUB SerialEcho
    NEXT satellite
WEND

MENU OFF: MOUSE OFF: TIMER OFF
WINDOW CLOSE 2: WINDOW CLOSE 3
SCREEN CLOSE 2
CLOSE #2
MENU RESET 
CLS
STOP

DisplayTimePos:
csrY = CSRLIN: csrX = POS(0):LOCATE 26,70
PRINT LEFT$(TIME$,5);" UTC";
LOCATE csrY,csrX
RETURN

CalcthenDisplay:
GOSUB TimeNow
TN = DY + (hour+minutes/60)/24
GOSUB SatVec
GOSUB RangeVec
GOSUB SunVec
GOSUB Satpos
LOCATE 27,1: PRINT "                                                                        ";
RETURN
 
DisplaySatInfo:  
satLat1 = CINT(satLat1): satLong1 = CINT(satLong1): ssrr = FNRN(ssrr-RE): SQ = FNRN(SQ)
EL = CINT(EL): AZ = CINT(AZ): R = FNRN(R): m = INT(m*128/pi): ILL = FNRN(100*ILL)
IF satellite = 1 THEN 
  mode$ = "B"
ELSEIF satellite = 3  THEN
  IF m > 59 AND m < 165 THEN mode$ = "B"
  IF m > 164 AND m < 195 THEN mode$ = "JL"
  IF m > 194 AND m < 200 THEN mode$ = "S"
  IF m > 199 AND m < 205 THEN mode$ = "BS"
  IF m > 204 AND m < 240 THEN mode$ = "B"
  IF m < 60 OR m > 239 THEN mode$ = "B Omi"
ELSE 
  mode$ = "     "
END IF
LOCATE 29,1
PRINT SatName$(satellite);TAB(12);satLat1;TAB(17);satLong1;TAB(23);
PRINT USING "#####";ssrr;
PRINT TAB(31) USING "###";m;
PRINT " ";
 IF EL > -3 THEN 
   PRINT TAB(35);EL;TAB(40);AZ;TAB(46);
   PRINT USING "#####";R;
'  PRINT TAB(52);RR;
   PRINT TAB(59);mode$;
   PRINT TAB(65);SQ;
 ELSE 
   PRINT TAB(35)"                                   ";
 END IF
PRINT TAB(72) USING "#####";RN;
RETURN

SerialEcho:
PRINT #4,USING "\      \";SatName$(satellite);
PRINT #4,"  MA ";
PRINT #4,USING "###";m;
PRINT #4,"  EL ";
PRINT #4,USING "###";EL;
PRINT #4,"  AZ ";
PRINT #4,USING "###";AZ;
PRINT #4,"  Mode ";
PRINT #4,USING "\   \";mode$;
PRINT #4,"  Rate ";
PRINT #4,USING "###";RR;
PRINT #4,"  Squint ";
PRINT #4,USING "###";SQ
PRINT #4,CHR$(10)
RETURN

CheckMenu:
menuId = MENU(0)
menuItem = MENU(1)
ON menuId GOTO Project,SatelliteChoise,Predictions,Display
RETURN

Project:
MENU 1,lastChoise,1
IF menuItem = 3 AND echo = 1 THEN Jump
MENU 1,menuItem,2
Jump:
IF menuItem = 3 THEN GOSUB EchoSet
IF menuItem = 4 THEN Quit = 0
lastChoise = menuItem
RETURN

SatelliteChoise:
MENU 2,oldSatellite,1
whichSatellite = menuItem
MENU 2,whichSatellite,2
oldSatellite = whichSatellite
RETURN

Predictions:
MENU 3,oldChoise1,1
choise1 = menuItem
MENU 3,choise1,2
IF choise1 = 1 THEN predictionTime = 0
IF choise1 = 2 THEN predictionTime = 60
IF choise1 = 3 THEN predictionTime = 180
IF choise1 = 4 THEN predictionTime = 360
IF choise1 = 5 THEN predictionTime = 720
IF choise1 = 6 THEN predictionTime = 1440
IF choise1 = 7 THEN predictionTime = 2880
IF choise1 = 8 THEN predictionTime = 10080
oldChoise1 = choise1
RETURN

Display:
MENU 4,oldChoise2,1
choise2 = menuItem
IF choise2 = 1 THEN 
  satellite = whichSatellite
  GOSUB SatelliteConstants
  LOCATE 27,26
  PRINT "    ";
  GOSUB TimeNow
  dayNo = DY + (hour+minutes/60)/24
  starMinutes = minutes-stepSize(satellite): starHour = hour
  FOR min = 0 TO predictionTime STEP stepSize(satellite)
   TN = dayNo + (min/60)/24
   starMinutes = starMinutes + stepSize(satellite)
   IF starMinutes > 59 THEN 
     starHour = starHour + 1 
     starMinutes = starMinutes - 60
   END IF
   IF starHour > 23 THEN starHour = 0
   GOSUB SatVec
   GOSUB RangeVec
   GOSUB SunVec
   GOSUB Satpos
   LOCATE 27,1: PRINT "Prediction time = ";
   clockHour = INT(starHour+.001)
   clockMin = INT(starMinutes+.1)
   clock$ = RIGHT$(STR$(10000+clockHour*100+clockMin),4)
   PRINT clock$;
   GOSUB DisplaySatInfo
  NEXT min
  LOCATE 27,26
  PRINT "End";
END IF
IF choise2 = 2 THEN 
  saveId = WINDOW(1)
  WINDOW 3,"Prediction",(20,0)-(620,225),8,2
  TIMER OFF
  path = 2
  GOSUB DataOutput
  PRINT #path, "CR to continue"
  INPUT"",dummy
  WINDOW saveId
END IF
IF choise2 = 3 THEN
  path = 3
  LOCATE 27,1: PRINT "Calculating";
  OPEN "Prt:" FOR OUTPUT AS #3
  GOSUB DataOutput
  CLOSE #3
END IF
IF choise2 = 4 THEN
  path = 4
  GOSUB DataOutput
END IF  
predictionTime = 0
MENU 3,oldChoise1,1
MENU 3,1,2 
oldChoise1 = 1
oldChoise2 = choise2
TIMER ON 
RETURN

DataOutput:
satellite = whichSatellite
GOSUB SatelliteConstants
IF choise2 = 4 THEN PRINT #path,CHR$(10)
PRINT #path, SatName$(satellite),DATE$
IF choise2 = 4 THEN PRINT #path,CHR$(10)
PRINT #path,"Date         Range     EL      ";
PRINT #path,"AZ    Range rate   Squint   MA   Mode  Orbit"
IF choise2 = 4 THEN PRINT #path,CHR$(10)
PRINT #path,"DDD.HHMM     km       deg      ";
PRINT #path,"deg     km/sec      deg"
IF choise2 = 4 THEN PRINT #path,CHR$(10)
FOR i = 1 TO 79
  PRINT #path,"-";
NEXT i
'IF choise2 = 4 THEN PRINT #path,CHR$(10)
PRINT
GOSUB TodayDate
GOSUB TimeNow
dayNo = DY + (hour+minutes/60)/24
starMinutes = minutes-stepSize(satellite): starHour = hour
FOR min = 0 TO predictionTime STEP stepSize(satellite)
  TN = dayNo + (min/60)/24
  starMinutes = starMinutes + stepSize(satellite)
  starDay = INT(TN)
  remander = TN - starDay
  starHour = INT(remander*24+.001)
  remander = (remander*24)-starHour
  starMinutes = INT(remander*60+.1)
  dat$ = STR$(starDay) + "." '+ STR$(starHour) + ":" + STR$(starMinutes)
  clock$ = RIGHT$(STR$(10000+starHour*100+starMinutes),4)
  GOSUB SatVec
  GOSUB RangeVec
  IF EL < 0 THEN LT = 0: GOTO Skip
  IF LT = 0 THEN PRINT #path,CHR$(10)
  RR = R
  TN = TN+1/86400&
  GOSUB SatVec
  GOSUB RangeVec
  GOSUB SunVec
  RR = R - RR: m = INT(m*128/pi)
  IF satellite = 3 THEN
      IF m > 59 AND m < 165 THEN mode$ = "B"
      IF m > 164 AND m < 195 THEN mode$ = "JL"
      IF m > 194 AND m < 200 THEN mode$ = "S"
      IF m > 199 AND m < 205 THEN mode$ = "BS"
      IF m > 204 AND m < 240 THEN mode$ = "B"
      IF m < 60 OR m > 239 THEN mode$ = "B Omi"
  ELSEIF satellite = 1 THEN
    mode$ = "B"
  ELSE 
    mode$ = "     "
  END IF
  EL = CINT(EL): AZ = CINT(AZ): R = FNRN(R): RR = FNRN(RR*10)/10: SQ = FNRN(SQ)
  PRINT #path,dat$;clock$;TAB(13);R;TAB(23);EL;TAB(30);AZ;TAB(42);RR;TAB(52);SQ;TAB(59);m;TAB(65);mode$;TAB(72);RN
  IF choise2 = 4 THEN PRINT #path,CHR$(10)
  LT = 1 
  Skip:
NEXT min
PRINT #path, :IF choise2 = 4 THEN PRINT #path,CHR$(10)
PRINT #path, "End"
IF choise2 = 3 THEN PRINT #path,CHR$(13)
IF choise2 = 4 THEN PRINT #path,CHR$(10)
RETURN

EchoSet:
IF echo = 0 THEN echo = 1 ELSE echo = 0
RETURN

SatelliteConstants:
YE = C1(satellite)         'Epoch year
TE = C2(satellite)         'Epoch time
IN = C3(satellite)         'Inclination
RA = C4(satellite)         'R.A.A.N.
EC = C5(satellite)         'Eccentricity
WP = C6(satellite)         'Arg of perigee
MA = C7(satellite)         'Mean anomaly
MM = C8(satellite)         'Mean motion
M2 = C9(satellite)         'Decay rate
RV = C10(satellite)        'Epoch rev
a  = C11(satellite)        'Semi-major axis.  0 if not known
ALAT = C12(satellite)      'Sat att, deg.  0 = in plain, + = below
ALON = C13(satellite)      'Sat att, deg CCW from SMA dir. 180 = Normal

IF a = 0 THEN a = (8681668.016000001#/MM)^(2/3)

RA = RAD*RA
MA = RAD*MA
IN = RAD*IN
MM = MM*2*pi
WP = RAD*WP
M2 = M2*2*pi
ALAT = RAD*ALAT
ALON = RAD*ALON
                                  
B = a*SQR(1-EC*EC)               
SI = SIN(IN): CI = COS(IN)
PC = RE*a/(B*B): PC = 1.5*J2*PC*PC*MM  
QD = -PC*CI                      
WD = PC*(5*CI*CI-1)/2      
DC = (M2/MM)/3       
              
TEG = FNDO(YE)-FNDO(YG) + TE  
GHAE = RAD*GO + TEG*WE   
MRSE = RAD*GO + TEG*WW + pi  
MASE = RAD*(MASO + MASD*TEG) 
RETURN


SatVec:
T = (FNDO(YR)-FNDO(YE)) + (TN-TE) 
DT = DC*T/2   
KD = 1-4*DT  
KDP = 1+7*DT    
m = MA + MM*T*(1+3*DT) 
DR = INT(m/(2*pi)) 
m = m - DR*2*pi     
RN = RV + DR   

EA = m
Loop:
  C = COS(EA)
  s = SIN(EA)
  DNOM = 1-EC*C
  DE = (EA - EC*s - m)/DNOM    
  EA = EA - DE       
IF ABS(DE) > .002 THEN GOTO Loop   

C = COS(EA)
s = SIN(EA)
RGC = a*(1-EC*C)*KD

SX = a*(C-EC)*KD:  TA = -COS(ALAT):   XA = TA*COS(ALON)  
SY = B*s*KD:    YA = TA*SIN(ALON):  ZA = -SIN(ALAT)
W = WP + WD*T*KDP:  C = COS(W):   s = SIN(W)
X = SX*C - SY*s:    TA = XA:      XA = TA*C - YA*s
Y = SX*s + SY*C:                  YA = TA*s + YA*C
z = Y*SI: TA = ZA: ZA = YA*SI+TA*CI: ANTZ = ZA
Y = Y*CI:          YA = YA*CI-TA*SI: ANTY = YA
                                     ANTX = XA

RAAN = RA + QD*T*KDP
GHAA = GHAE + WE*T   
Q = RAAN - GHAA               
C = COS(Q): s = SIN(Q)
SX = X*C - Y*s:    TA = XA:     XA = TA*C - YA*s
SY = X*s + Y*C:                 YA = TA*s + YA*C
SZ = z

C = COS(RAAN): s = SIN(RAAN)
SATX = X*C - Y*s:   TA = ANTX:  ANTX = TA*C - ANTY*s
SATY = X*s + Y*C:               ANTY = TA*s + ANTY*C
SATZ = z
NMX = s*SI: NMY = -C*SI: NMZ = CI
RETURN

SunVec:
MAS = MASE + RAD*(MASD*T)  
TAS = MRSE + WW*T + EQC1*SIN(MAS) + EQC2*SIN(2*MAS) + EQC3*SIN(3*MAS)
C = COS(TAS):  s = SIN(TAS)     
SUNX = C:  SUNY = s*CNS:  SUNZ = s*SNS   

CSA = ANTX*SUNX + ANTY*SUNY + ANTZ*SUNZ  
ILL = SQR(1-CSA*CSA)   
SATX = SATX/RGC:  SATY = SATY/RGC:  SATZ = SATZ/RGC 
CUA = -(SATX*SUNX + SATY*SUNY + SATZ*SUNZ) 
UMD = RGC*SQR(1-CUA*CUA)/RE    
SEL = (SUNX*NMX + SUNY*NMY + SUNZ*NMZ) 
SEL = ATN(SEL/SQR(-SEL*SEL+1))
IF CUA >= 0 THEN ECL$ = "    +" ELSE ECL$ = "    -"
IF UMD <= 1 AND CUA >= 0 THEN ECL$ = "   ECL"
RETURN

RangeVec:
RX = SX - OX:  RY = SY - OY:  RZ = SZ - OZ  
R = SQR(RX*RX + RY*RY + RZ*RZ)   
RX = RX/R: RY = RY/R:  RZ = RZ/R   
U = RX*UX + RY*UY + RZ*UZ   
E = RX*EX + RY*EY + RZ*EZ  
N = RX*NX + RY*NY + RZ*NZ   
AZ = DEG*(ATN(E/N))       
IF N < 0 THEN AZ = AZ + 180              
IF AZ < 0 THEN AZ = AZ + 360
EL = DEG*(ATN(U/SQR(-U*U+1)))
srr = SQR(SX*SX+SY*SY)     
ssrr = SQR(SX*SX+SY*SY+SZ*SZ)    
szrr = SZ/ssrr: syr = SY/srr
satLat1 = DEG*(ATN(szrr/SQR(-szrr*szrr+1))) 
satLong1 = DEG*(ATN(syr/SQR(-syr*syr+1))) 
SQ =  -(XA*RX + YA*RY + ZA*RZ) 
SQ = DEG*(-ATN(SQ/SQR(-SQ*SQ+1))+1.5708)
RETURN

Satpos:
IF SX < 0 AND SY > 0 THEN satLong1 = 180 - satLong1 
IF SX < 0 AND SY < 0 THEN satLong1 = -(180+satLong1)
satPsnX = 1.75*satLong1+309       
satPsnY = 117-1.33*satLat1
satPsnX = CINT(satPsnX)
satPsnY = CINT(satPsnY)
OBJECT.OFF satellite
IF predictionTime > 0 THEN IF satLat1 >= -60 THEN PSET(satPsnX+5,satPsnY+5),3
OBJECT.X satellite,satPsnX: OBJECT.Y satellite,satPsnY
IF satLat1 >= -60 THEN OBJECT.ON satellite
RETURN

TodayDate:
day = VAL(MID$(DATE$,4,2))
month = VAL(LEFT$(DATE$,2))
YR = VAL(RIGHT$(DATE$,4))  
'DY = INT(YR/4)-INT((YR-1)/4)+212+day+(SGN(month-8)*(INT(.5+(ABS((month-8)*30.5)))))
DY = day+days&(month): IF month > 2 THEN DY = DY + (INT(YR/4)-INT((YR-1)/4))
RETURN

TimeNow:
hour = VAL(LEFT$(TIME$,2))
minutes = VAL(MID$(TIME$,4,2))
RETURN


ScreenSetup:
LOCATE 10,20
PRINT "Setting up map display and arrays, please wait!"
GOSUB MainPicture
ON MENU GOSUB CheckMenu: MENU ON

MENU 1,0,1,"Project "
MENU 1,1,2,"  Map Display "
MENU 1,2,1,"              "
MENU 1,3,1,"  Serial Echo "
MENU 1,4,1,"  Quit        "
MENU 2,0,1,"Satellite "
MENU 2,1,1,"  OSCAR-10s "
MENU 2,2,1,"  OSCAR-11  "
MENU 2,3,1,"  OSCAR-13s "
MENU 2,4,1,"  OSCAR-14  "
MENU 2,5,1,"  OSCAR-15  "
MENU 2,6,1,"  OSCAR-16  "
MENU 2,7,1,"  OSCAR-17  "
MENU 2,8,1,"  OSCAR-18  "
MENU 2,9,1,"  OSCAR-19  "
MENU 2,10,1,"  OSCAR-20  "
MENU 2,11,1,"  RS-10/11  "
MENU 3,0,1,"Predictions"
MENU 3,1,2,"  Real Time "
MENU 3,2,1,"  One hour  "
MENU 3,3,1,"  3 hours   "
MENU 3,4,1,"  6 hours  "
MENU 3,5,1,"  12 hours  "
MENU 3,6,1,"  24 hours  "
MENU 3,7,1,"  48 hours  "
MENU 3,8,1,"  7 days    "
MENU 4,0,1,"Display "
MENU 4,1,1,"  Screen, Map  "
MENU 4,2,1,"  Screen, Text "
MENU 4,3,1,"  Printer      "
MENU 4,4,1,"  Serial       "
RETURN

ObjectShape:
saveId = WINDOW(1)
WINDOW 2
OPEN objShape$(satellite) FOR INPUT AS satellite
OBJECT.SHAPE satellite,INPUT$(LOF(satellite),satellite)
CLOSE satellite
OBJECT.CLIP (0,0)-(631,199)
WINDOW saveId
RETURN
 
Constants:
days&(0)=0:days&(1)=0:days&(2)=31:days&(3)=59:days&(4)=90:days&(5)=120:days&(6)=151
days&(7)=181:days&(8)=212:days&(9)=243:days&(10)=273:days&(11)=304:days&(12)=334
LA =  51.268333#           ' Latitude of QTH, + north, - south
LO = -.563333              ' Longitude of QTH, + deg east, - deg west
HT = 35                    ' Height of QTH above mean sea level
pi = 3.141592654#
DEG = 180/pi                           
RAD = 1/DEG               
DEF FNRN(X) = INT(X+.5)
LA = RAD*LA
LO = RAD*LO
HT = HT/1000
CL = COS(LA)
SL = SIN(LA)
CO = COS(LO)
SO = SIN(LO)

RE = 6378.14
FL = 1/298.256      
RP = RE*(1-FL)
XX = RE*RE
ZZ = RP*RP
D = SQR(XX*CL*CL + ZZ*SL*SL)
RX = XX/D + HT
RZ = ZZ/D + HT

UX = CL*CO:       EX = -SO:       NX = -SL*CO
UY = CL*SO:       EY = CO:        NY = -SL*SO
UZ = SL:          EZ = 0:         NZ = CL
OX = RX*UX:       OY = RX*UY:     OZ = RZ*UZ

YG = 1988:    GO = 98.8897
MASO = 356.1611:   MASD = .9856002671#
INS = RAD*23.4408:  CNS = COS(INS):   SNS = SIN(INS)
EQC1 = .03342715297#:  EQC2 = .00034917#:  EQC3 = .00000506#

YM = 365.25
YT = 365.2421938#
DEF FNDO(Y) = INT((Y-1)*YM)
WW = 2*pi/YT
WE = 2*pi + WW
J2 = .00108263#
RETURN

Ephemeris:

SatName$(1)="OSCAR 10s ": SatName$(2)="OSCAR 11  "
stepSize(1)=20:           stepSize(2)=5
objShape$(1)="oscar10":   objShape$(2)="oscar11"
C1(1)=1989:               C1(2)=1990
C2(1)=330.318#:           C2(2)=86.14190031#
C3(1)=25.9:               C3(2)=97.963
C4(1)=232:                C4(2)=141.366
C5(1)=.6:                 C5(2)=.0012026
C6(1)=96:                 C6(2)=141.7015
C7(1)=331:                C7(2)=218.5388
C8(1)=2.0588#:            C8(2)=14.65066797#:      ' AO 10 ALAT,ALONG
C9(1)=0:                  C9(2)=.00002602#:        '
C10(1)=4855:              C10(2)=32395:            ' Jan     Apr
C11(1)=0:                 C11(2)=0:                '
C12(1)=-11:               C12(2)=0:                '-17     -11
C13(1)=28:                C13(2)=180:              ' 38      28

SatName$(3)="OSCAR 13s ": SatName$(4)="OSCAR 14  "
stepSize(3)=20:           stepSize(4)=5
objShape$(3)="oscar13":   objShape$(4)="oscar14"
C1(3)=1990:               C1(4)=1990
C2(3)=28.47497#:          C2(4)=32.22728814#
C3(3)=57.04:              C3(4)=98.7119
C4(3)=171.28:             C4(4)=108.6771
C5(3)=.6886:              C5(4)=.0011164
C6(3)=220.03964#:         C6(4)=187.8659
C7(3)=0:                  C7(4)=172.2355
C8(3)=2.09699529#:        C8(4)=14.2847692#
C9(3)=0:                  C9(4)=.00000487#
C10(3)=1244:              C10(4)=145
C11(3)=25783:             C11(4)=0
C12(3)=2.9:               C12(4)=0
C13(3)=207.1:             C13(4)=180

SatName$(5)="OSCAR 15  ": SatName$(6)="OSCAR 16  "
stepSize(5)=5:            stepSize(6)=5
objShape$(5)="oscar15":   objShape$(6)="oscar16"
C1(5)=1990:               C1(6)=1990
C2(5)=39.65469092#:       C2(6)=34.60805519#
C3(5)=98.7132:            C3(6)=98.7153
C4(5)=116.0954:           C4(6)=111.0642
C5(5)=.0010392#:          C5(6)=.0011537
C6(5)=165.098:            C6(6)=181.1074
C7(5)=195.0505:           C7(6)=179.0106
C8(5)=14.28262878#:       C8(6)=14.28568377#
C9(5)=.00000474#:         C9(6)=.00000853#
C10(5)=251:               C10(6)=179
C11(5)=0:                 C11(6)=0
C12(5)=0:                 C12(6)=0
C13(5)=180:               C13(6)=180

SatName$(7)="OSCAR 17  ": SatName$(8)="OSCAR 18  "
stepSize(7)=5:            stepSize(8)=5
objShape$(7)="oscar17":   objShape$(8)="oscar18"
C1(7)=1990:               C1(8)=1990
C2(7)=29.63506009#:       C2(8)=36.28755853#
C3(7)=98.7166:            C3(8)=98.7153
C4(7)=106.0985:           C4(8)=112.745
C5(7)=.0011558:           C5(8)=.0012351
C6(7)=194.931:            C6(8)=176.1527
C7(7)=165.2835:           C7(8)=183.9742
C8(7)=14.2859#:           C8(8)=14.28715751#
C9(7)=.00000887#:         C9(8)=.00000649#
C10(7)=108:               C10(8)=203
C11(7)=0:                 C11(8)=0
C12(7)=0:                 C12(8)=0
C13(7)=180:               C13(8)=180

SatName$(9)="OSCAR 19  ": SatName$(10)="OSCAR 20  "
stepSize(9)=5:            stepSize(10)=5
objShape$(9)="oscar19":   objShape$(10)="oscar20"
C1(9)=1990:               C1(10)=1990
C2(9)=30.68451259#:       C2(10)=85.20385752#
C3(9)=98.7165:            C3(10)=99.052
C4(9)=107.1491:           C4(10)=147.3503
C5(9)=.0012456:           C5(10)=.0540825
C6(9)=193.4736:           C6(10)=236.3713
C7(9)=166.6115:           C7(10)=118.4676
C8(9)=14.28775079#:       C8(10)=12.83121017#
C9(9)=.00000738#:         C9(10)=9.59999999999D-07
C10(9)=123:               C10(10)=610
C11(9)=0:                 C11(10)=0
C12(9)=0:                 C12(10)=0
C13(9)=180:               C13(10)=180
RETURN

MainPicture:

DIM bPlane&(5), cTabWork%(32), cTabSave%(32)
DECLARE FUNCTION xOpen&  LIBRARY
DECLARE FUNCTION xRead&  LIBRARY
DECLARE FUNCTION xWrite& LIBRARY
DECLARE FUNCTION AllocMem&() LIBRARY
LIBRARY "dos.library"
LIBRARY "exec.library"
LIBRARY "graphics.library"

GetNames:
ACBMname$  = "World6"   ' World1 of political map
loadError$ = ""
GOSUB LoadACBM
IF loadError$ <> "" THEN GOTO Mcleanup

Mcleanup:
Mcleanup2:
LIBRARY CLOSE
IF loadError$ <> "" THEN PRINT loadError$
RETURN   

LoadACBM:
f$ = ACBMname$
fHandle& = 0
mybuf& = 0
foundBMHD = 0
foundCMAP = 0
foundCAMG = 0
foundCCRT = 0
foundABIT = 0
filename$ = f$ + CHR$(0)
fHandle& = xOpen&(SADD(filename$),1005)
IF fHandle& = 0 THEN
   loadError$ = "Can't open/find pic file"
   GOTO Lcleanup
END IF
ClearPublic& = 65537&
mybufsize& = 360
mybuf& = AllocMem&(mybufsize&,ClearPublic&)
IF mybuf& = 0 THEN
   loadError$ = "Can't alloc buffer"
   GOTO Lcleanup
END IF
inbuf& = mybuf&
cbuf& = mybuf& + 120
ctab& = mybuf& + 240
rLen& = xRead&(fHandle&,inbuf&,12)
tt$ = ""
FOR kk = 8 TO 11
   tt% = PEEK(inbuf& + kk)
   tt$ = tt$ + CHR$(tt%)
NEXT
IF tt$ <> "ACBM" THEN 
   loadError$ = "Not an ACBM pic file"
   GOTO Lcleanup
END IF

ChunkLoop: 
 rLen& = xRead&(fHandle&,inbuf&,8)
 icLen& = PEEKL(inbuf& + 4)
 tt$ = ""
 FOR kk = 0 TO 3
    tt% = PEEK(inbuf& + kk)
    tt$ = tt$ + CHR$(tt%)
 NEXT       
IF tt$ = "BMHD" THEN  
   foundBMHD = 1
   rLen& = xRead&(fHandle&,inbuf&,icLen&)
   iWidth%  = PEEKW(inbuf&)
   iHeight% = PEEKW(inbuf& + 2)
   iDepth%  = PEEK(inbuf& + 8)  
   iCompr%  = PEEK(inbuf& + 10)
   scrWidth%  = PEEKW(inbuf& + 16)
   scrHeight% = PEEKW(inbuf& + 18)   
   iRowBytes% = iWidth% /8
   scrRowBytes% = scrWidth% / 8
   nColors%  = 2^(iDepth%)
   AvailRam& = FRE(-1)
   NeededRam& = ((scrWidth%/8)*scrHeight%*(iDepth%+1))+5000
   IF AvailRam& < NeededRam& THEN
      loadError$ = "Not enough free ram."
      GOTO Lcleanup
   END IF
   kk = 1
   IF scrWidth% > 320 THEN kk = kk + 1
   IF scrHeight% > 320  THEN kk = kk + 2
   SCREEN 2,scrWidth%,scrHeight%,iDepth%,kk
   WINDOW 2,"Map Display",,16,2
   WINDOW OUTPUT 2
   GOSUB GetScrAddrs
   CALL LoadRGB4&(sViewPort&,ctab&,nColors%)
ELSEIF tt$ = "CMAP" THEN 
   foundCMAP = 1
   rLen& = xRead&(fHandle&,cbuf&,icLen&)
   ' Build Color Table
   FOR kk = 0 TO nColors% - 1
      red% = PEEK(cbuf&+(kk*3))
      gre% = PEEK(cbuf&+(kk*3)+1)
      blu% = PEEK(cbuf&+(kk*3)+2)
      regTemp% = (red%*16)+(gre%)+(blu%/16)
      POKEW(ctab&+(2*kk)),regTemp%
   NEXT
ELSEIF tt$ = "ABIT" THEN 
   foundABIT = 1    
   plSize& = (scrWidth%/8) * scrHeight%
   FOR pp = 0 TO iDepth% -1
      rLen& = xRead&(fHandle&,bPlane&(pp),plSize&)   
   NEXT
ELSE 
   FOR kk = 1 TO icLen&
      rLen& = xRead&(fHandle&,inbuf&,1)
   NEXT
   IF (icLen& OR 1) = icLen& THEN  
      rLen& = xRead&(fHandle&,inbuf&,1)
   END IF     
END IF
IF foundBMHD AND foundCMAP AND foundABIT THEN
   GOTO GoodLoad
END IF
IF rLen& > 0 THEN GOTO ChunkLoop
IF rLen& < 0 THEN  'Read error
   loadError$ = "Read error"
   GOTO Lcleanup
END IF   
IF (foundBMHD=0) OR (foundABIT=0) OR (foundCMAP=0) THEN
   loadError$ = "Needed ILBM chunks not found"
   GOTO Lcleanup
END IF

GoodLoad:
loadError$ =""
IF foundCMAP THEN 
   CALL LoadRGB4&(sViewPort&,ctab&,nColors%)
END IF

Lcleanup:
IF fHandle& <> 0 THEN CALL xClose&(fHandle&)
IF mybuf& <> 0 THEN CALL FreeMem&(mybuf&,mybufsize&)
ERASE bPlane&,cTabWork%,cTabSave%

RETURN

GetScrAddrs: 
   sWindow&   = WINDOW(7)
   sScreen&   = PEEKL(sWindow& + 46)
   sViewPort& = sScreen& + 44
   sRastPort& = sScreen& + 84
   sColorMap& = PEEKL(sViewPort& + 4)
   colorTab&  = PEEKL(sColorMap& + 4)
   sBitMap&   = PEEKL(sRastPort& + 4)
   ' Get screen parameters
   scrWidth%  = PEEKW(sScreen& + 12)
   scrHeight% = PEEKW(sScreen& + 14)
   scrDepth%  = PEEK(sBitMap& + 5)
   nColors%   = 2^scrDepth%
   ' Get addresses of Bit Planes 
   FOR kk = 0 TO scrDepth% - 1
      bPlane&(kk) = PEEKL(sBitMap&+8+(kk*4))
   NEXT
RETURN
