diff --git a/demo/pascal/Demo.pas b/demo/pascal/Demo.pas
new file mode 100644
index 00000000..2d3411c4
--- /dev/null
+++ b/demo/pascal/Demo.pas
@@ -0,0 +1,126 @@
+program Demo;
+
+{$mode objfpc}{$H+}
+
+uses
+ Classes,
+ SysUtils,
+ Astronomy;
+
+const
+ Months: array[1..12] of string = (
+ 'January', 'February', 'March', 'April',
+ 'May', 'June', 'July', 'August',
+ 'September', 'October', 'November', 'December');
+
+ // Observer site: Slovakia/Bratislava
+ Latitude: Double = 48.143889;
+ Longitude: Double = 17.109722;
+ Elevation: Double = 124;
+
+ // ICRS equatorial coordinates of the star HD1 (Henry Draper catalog, star #1)
+ RA_ICRS: Double = 1.2961219444444443; // degrees
+ DE_ICRS: Double = 67.84007388888888; // degrees
+
+var
+ at1: AstroTime;
+ st1: Double;
+ ptr: PAstroTime;
+ mph: AstroAngleResult;
+ MoonPhase: string;
+ lap: AstroApsis;
+ sss: AstroSeasons;
+ obs: AstroObserver;
+ coo: AstroEquatorial;
+
+function ToDateString(Event: AstroTime): string;
+var
+ t: AstroUTC;
+begin
+ t := Astronomy_UtcFromTime(Event);
+ ToDateString := '' + IntToStr(t.Year) + '. ' + Months[t.Month] + '. ' + IntToStr(t.Day) + '. ';
+end;
+
+BEGIN
+ at1 := Astronomy_MakeTime(2025, 1, 20, 22, 20, 0.5);
+ WriteLn('Astro time for 2025-Jan-20 at 22:20:30 -> ', at1.UT:20:6, #10#13);
+
+ // Define an observer site
+ obs.Latitude := Latitude;
+ obs.Longitude := Longitude;
+ obs.Height := Elevation;
+
+ at1 := Astronomy_CurrentTime();
+ WriteLn('Current astro time: ', at1.UT:20:6, #10#13);
+
+ WriteLn('Body name: ', Astronomy_BodyName(AstroBody.BODY_SUN), #10#13);
+
+ WriteLn('Body code for "Earth": [', Astronomy_BodyCode(PChar('Earth')), ']', #10#13);
+
+ // Calculate Greenwich sidereal time using current time
+ ptr := New(PAstroTime);
+ ptr^.UT := at1.UT;
+ ptr^.TT := at1.TT;
+ ptr^.ST := 0 / 0; // gives NaN, must be set, otherwise GAST calculation doesn't work
+ st1 := Astronomy_SiderealTime(ptr);
+ WriteLn('Greenwich apparent sidereal time: ', st1:20:6, ' hours', #10#13);
+
+ // Get the current moon phase
+ mph := Astronomy_MoonPhase(at1);
+ if mph.Status <> AstroStatus.ASTRO_SUCCESS then
+ WriteLn('An error occured during the Moon phase calculation!')
+ else begin
+ if (mph.Angle = 0) or (mph.Angle = 360) then MoonPhase := 'New Moon';
+ if (mph.Angle > 0) and (mph.Angle < 90) then MoonPhase := 'Waxing Crescent';
+ if mph.Angle = 90 then MoonPhase := 'First quarter';
+ if (mph.Angle > 90) and (mph.Angle < 180) then MoonPhase := 'Waxing Gibbous';
+ if mph.Angle = 180 then MoonPhase := 'Full Moon';
+ if (mph.Angle > 180) and (mph.Angle < 270) then MoonPhase := 'Waning Gibbous';
+ if mph.Angle = 270 then MoonPhase := 'Last quarter';
+ if (mph.Angle > 270) and (mph.Angle < 360) then MoonPhase := 'Waning Crescent';
+ WriteLn('Current Moon phase: ' + MoonPhase + #10#13);
+ end;
+
+ // Search for the first lunar apsis event since now
+ lap := Astronomy_SearchLunarApsis(at1);
+ if lap.Status <> AstroStatus.ASTRO_SUCCESS then
+ WriteLn('An error occured during the Moon apsis calculation!')
+ else
+ WriteLn('Next Lunar ', lap.Kind, ' occurs at ', ToDateString(lap.Time), ' at the distance of ', lap.DistKM:12:3, ' km from Earth.');
+
+ // Search for next lunar apsis event
+ lap := Astronomy_NextLunarApsis(lap);
+ if lap.Status <> AstroStatus.ASTRO_SUCCESS then
+ WriteLn('An error occured during the Moon apsis calculation!')
+ else
+ WriteLn('Next Lunar ', lap.Kind, ' occurs at ', ToDateString(lap.Time), ' at the distance of ', lap.DistKM:12:3, ' km from Earth.', #10#13);
+
+ // Search for seasons in 2025
+ sss := Astronomy_Seasons(2025);
+ if sss.Status <> AstroStatus.ASTRO_SUCCESS then
+ WriteLn('An error occured during the 2025 seasons calculation!')
+ else begin
+ WriteLn('2025 march equinox occurs at: ', ToDateString(sss.MarEquinox));
+ WriteLn('2025 june solstice occurs at: ', ToDateString(sss.JunSolstice));
+ WriteLn('2025 sept equinox occurs at: ', ToDateString(sss.SepEquinox));
+ WriteLn('2025 dec solstice occurs at: ', ToDateString(sss.DecSolstice), #10#13);
+ end;
+
+ // Find equatorial coordinates of date for the star HD1 as seen from Slovakia/Bratislava
+ if Astronomy_DefineStar(AstroBody.BODY_STAR1, RA_ICRS / 15.0, DE_ICRS, 1000.0) <> AstroStatus.ASTRO_SUCCESS then
+ WriteLn('An error occured during defining a custom star!')
+ else begin
+ coo := Astronomy_Equator(AstroBody.BODY_STAR1, ptr, obs, AstroEquatorDate.EQUATOR_OF_DATE, AstroAberration.NO_ABERRATION);
+ if coo.Status <> AstroStatus.ASTRO_SUCCESS then
+ WriteLn('An error occured during the coordinate conversion!')
+ else begin
+ WriteLn('Equatorial coordinates of the HD1 star at ', ToDateString(at1));
+ WriteLn('Right ascension: ', coo.RA:12:3, ' hours');
+ WriteLn('Declination: ', coo.Dec:12:3, ' degrees');
+ end;
+ end;
+
+ // Release the dynamically allocated object used in the previous calculations
+ Dispose(ptr);
+END.
+
diff --git a/demo/pascal/README.md b/demo/pascal/README.md
new file mode 100644
index 00000000..0bd584c7
--- /dev/null
+++ b/demo/pascal/README.md
@@ -0,0 +1,13 @@
+# Astronomy Engine examples in Pascal
+---
+### [Various](Demo.pas)
+The demo program shows following astronomy calculations:
+- Setting up the observer site
+- Creating `AstroTime` object for a fixed date/time
+- Creating `AstroTime` object for the `now` moment for later calcualtions
+- Calculating and displaying the current Moon phase
+- Calculating upcoming lunar apsis events
+- Calculating the equinox and solstice events for the year 2025
+- Calculating the equatorial coordinates of date for the star HD1 from Henry Draper catalog for the current observer site
+
+To execute this demo (after build) you will also need the `Astronomy.dll` binary built from Astronomy Engine C/C++ project!
diff --git a/source/c/Astronomy.sln b/source/c/Astronomy.sln
new file mode 100644
index 00000000..1ddd368f
--- /dev/null
+++ b/source/c/Astronomy.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.12.35527.113 d17.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Astronomy", "Astronomy.vcxproj", "{E5211E34-82B2-4995-80C3-AAB72E89C6CF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x64.ActiveCfg = Debug|x64
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x64.Build.0 = Debug|x64
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x86.ActiveCfg = Debug|Win32
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Debug|x86.Build.0 = Debug|Win32
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x64.ActiveCfg = Release|x64
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x64.Build.0 = Release|x64
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x86.ActiveCfg = Release|Win32
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/source/c/Astronomy.vcxproj b/source/c/Astronomy.vcxproj
new file mode 100644
index 00000000..4523e959
--- /dev/null
+++ b/source/c/Astronomy.vcxproj
@@ -0,0 +1,137 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 17.0
+ {E5211E34-82B2-4995-80C3-AAB72E89C6CF}
+ Win32Proj
+ 10.0
+
+
+
+ DynamicLibrary
+ true
+ v143
+
+
+ DynamicLibrary
+ false
+ v143
+
+
+ DynamicLibrary
+ true
+ v143
+
+
+ DynamicLibrary
+ false
+ v143
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions)
+ Level3
+
+
+ true
+ Windows
+
+
+
+
+ _DEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions)
+ Level3
+ stdcpp17
+ stdc17
+ false
+
+
+ true
+ Windows
+
+
+
+
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions)
+ Level3
+
+
+ true
+ Windows
+ true
+ true
+
+
+
+
+ NDEBUG;_WINDOWS;_USRDLL;ASTRONOMY_EXPORTS;%(PreprocessorDefinitions)
+ Level3
+ stdcpp17
+ stdc17
+ false
+
+
+ true
+ Windows
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/c/README.Windows.md b/source/c/README.Windows.md
new file mode 100644
index 00000000..70e4ec6f
--- /dev/null
+++ b/source/c/README.Windows.md
@@ -0,0 +1,13 @@
+# Astronomy Engine (C/C++) for Windows platform
+
+We include the project file (.vcxproj) and solution file (.sln) so that you can easily build the Astronomy Engine on the Windows platform using Visual Studio.
+
+## Build
+
+Open and build the `Astronomy.sln` file in Visual Studio (2022 and newer).
+Please note that the `Desktop development with C++` workload is required to build the Astronomy Engine in Visual Studio.
+A dynamic link library file `Astronomy.dll` is created on a successful build as an output.
+
+## Language bindings possibility
+
+The Astronomy Engine (C/C++) project is built in a way that allows to create [language binding](https://en.wikipedia.org/wiki/Language_binding) for other programming languages that support _external functions_. This way one can call C/C++ functions from Pascal language for example.
diff --git a/source/c/astronomy.h b/source/c/astronomy.h
index 9c73a196..25ca75c9 100644
--- a/source/c/astronomy.h
+++ b/source/c/astronomy.h
@@ -30,6 +30,13 @@
#include /* for size_t */
+#ifdef _WIN32
+#pragma pack(1)
+#define _PREFIX __declspec(dllexport)
+#else
+#define _PREFIX
+#endif // _WIN32
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -642,10 +649,10 @@ typedef astro_func_result_t (* astro_search_func_t) (void *context, astro_time_t
*/
typedef double (* astro_deltat_func) (double ut);
-double Astronomy_DeltaT_EspenakMeeus(double ut);
-double Astronomy_DeltaT_JplHorizons(double ut);
+_PREFIX double Astronomy_DeltaT_EspenakMeeus(double ut);
+_PREFIX double Astronomy_DeltaT_JplHorizons(double ut);
-void Astronomy_SetDeltaTFunction(astro_deltat_func func);
+_PREFIX void Astronomy_SetDeltaTFunction(astro_deltat_func func);
/**
* @brief Indicates whether a body (especially Mercury or Venus) is best seen in the morning or evening.
@@ -1158,45 +1165,45 @@ typedef struct astro_grav_sim_s astro_grav_sim_t;
/*---------- functions ----------*/
-void Astronomy_Reset(void);
-double Astronomy_VectorLength(astro_vector_t vector);
-astro_angle_result_t Astronomy_AngleBetween(astro_vector_t a, astro_vector_t b);
-const char *Astronomy_BodyName(astro_body_t body);
-astro_body_t Astronomy_BodyCode(const char *name);
-astro_observer_t Astronomy_MakeObserver(double latitude, double longitude, double height);
+_PREFIX void Astronomy_Reset(void);
+_PREFIX double Astronomy_VectorLength(astro_vector_t vector);
+_PREFIX astro_angle_result_t Astronomy_AngleBetween(astro_vector_t a, astro_vector_t b);
+_PREFIX const char *Astronomy_BodyName(astro_body_t body);
+_PREFIX astro_body_t Astronomy_BodyCode(const char *name);
+_PREFIX astro_observer_t Astronomy_MakeObserver(double latitude, double longitude, double height);
#if !defined(ASTRONOMY_ENGINE_NO_CURRENT_TIME)
-astro_time_t Astronomy_CurrentTime(void);
+_PREFIX astro_time_t Astronomy_CurrentTime(void);
#endif
-astro_time_t Astronomy_MakeTime(int year, int month, int day, int hour, int minute, double second);
-astro_time_t Astronomy_TimeFromUtc(astro_utc_t utc);
-astro_utc_t Astronomy_UtcFromTime(astro_time_t time);
-astro_status_t Astronomy_FormatTime(astro_time_t time, astro_time_format_t format, char *text, size_t size);
-astro_time_t Astronomy_TimeFromDays(double ut);
-astro_time_t Astronomy_TerrestrialTime(double tt);
-astro_time_t Astronomy_AddDays(astro_time_t time, double days);
-double Astronomy_SiderealTime(astro_time_t *time);
-astro_func_result_t Astronomy_HelioDistance(astro_body_t body, astro_time_t time);
-astro_vector_t Astronomy_HelioVector(astro_body_t body, astro_time_t time);
-astro_vector_t Astronomy_GeoVector(astro_body_t body, astro_time_t time, astro_aberration_t aberration);
-astro_vector_t Astronomy_GeoMoon(astro_time_t time);
-astro_spherical_t Astronomy_EclipticGeoMoon(astro_time_t time);
-astro_state_vector_t Astronomy_GeoMoonState(astro_time_t time);
-astro_state_vector_t Astronomy_GeoEmbState(astro_time_t time);
-astro_libration_t Astronomy_Libration(astro_time_t time);
-astro_state_vector_t Astronomy_BaryState(astro_body_t body, astro_time_t time);
-astro_state_vector_t Astronomy_HelioState(astro_body_t body, astro_time_t time);
-
-double Astronomy_MassProduct(astro_body_t body);
-double Astronomy_PlanetOrbitalPeriod(astro_body_t body);
-
-astro_state_vector_t Astronomy_LagrangePoint(
+_PREFIX astro_time_t Astronomy_MakeTime(int year, int month, int day, int hour, int minute, double second);
+_PREFIX astro_time_t Astronomy_TimeFromUtc(astro_utc_t utc);
+_PREFIX astro_utc_t Astronomy_UtcFromTime(astro_time_t time);
+_PREFIX astro_status_t Astronomy_FormatTime(astro_time_t time, astro_time_format_t format, char *text, size_t size);
+_PREFIX astro_time_t Astronomy_TimeFromDays(double ut);
+_PREFIX astro_time_t Astronomy_TerrestrialTime(double tt);
+_PREFIX astro_time_t Astronomy_AddDays(astro_time_t time, double days);
+_PREFIX double Astronomy_SiderealTime(astro_time_t *time);
+_PREFIX astro_func_result_t Astronomy_HelioDistance(astro_body_t body, astro_time_t time);
+_PREFIX astro_vector_t Astronomy_HelioVector(astro_body_t body, astro_time_t time);
+_PREFIX astro_vector_t Astronomy_GeoVector(astro_body_t body, astro_time_t time, astro_aberration_t aberration);
+_PREFIX astro_vector_t Astronomy_GeoMoon(astro_time_t time);
+_PREFIX astro_spherical_t Astronomy_EclipticGeoMoon(astro_time_t time);
+_PREFIX astro_state_vector_t Astronomy_GeoMoonState(astro_time_t time);
+_PREFIX astro_state_vector_t Astronomy_GeoEmbState(astro_time_t time);
+_PREFIX astro_libration_t Astronomy_Libration(astro_time_t time);
+_PREFIX astro_state_vector_t Astronomy_BaryState(astro_body_t body, astro_time_t time);
+_PREFIX astro_state_vector_t Astronomy_HelioState(astro_body_t body, astro_time_t time);
+
+_PREFIX double Astronomy_MassProduct(astro_body_t body);
+_PREFIX double Astronomy_PlanetOrbitalPeriod(astro_body_t body);
+
+_PREFIX astro_state_vector_t Astronomy_LagrangePoint(
int point,
astro_time_t time,
astro_body_t major_body,
astro_body_t minor_body
);
-astro_state_vector_t Astronomy_LagrangePointFast(
+_PREFIX astro_state_vector_t Astronomy_LagrangePointFast(
int point,
astro_state_vector_t major_state,
double major_mass,
@@ -1204,9 +1211,9 @@ astro_state_vector_t Astronomy_LagrangePointFast(
double minor_mass
);
-astro_jupiter_moons_t Astronomy_JupiterMoons(astro_time_t time);
+_PREFIX astro_jupiter_moons_t Astronomy_JupiterMoons(astro_time_t time);
-astro_equatorial_t Astronomy_Equator(
+_PREFIX astro_equatorial_t Astronomy_Equator(
astro_body_t body,
astro_time_t *time,
astro_observer_t observer,
@@ -1214,79 +1221,79 @@ astro_equatorial_t Astronomy_Equator(
astro_aberration_t aberration
);
-astro_vector_t Astronomy_ObserverVector(
+_PREFIX astro_vector_t Astronomy_ObserverVector(
astro_time_t *time,
astro_observer_t observer,
astro_equator_date_t equdate
);
-astro_state_vector_t Astronomy_ObserverState(
+_PREFIX astro_state_vector_t Astronomy_ObserverState(
astro_time_t *time,
astro_observer_t observer,
astro_equator_date_t equdate
);
-astro_observer_t Astronomy_VectorObserver(astro_vector_t *vector, astro_equator_date_t equdate);
+_PREFIX astro_observer_t Astronomy_VectorObserver(astro_vector_t *vector, astro_equator_date_t equdate);
-double Astronomy_ObserverGravity(double latitude, double height);
+_PREFIX double Astronomy_ObserverGravity(double latitude, double height);
-astro_ecliptic_t Astronomy_SunPosition(astro_time_t time);
-astro_ecliptic_t Astronomy_Ecliptic(astro_vector_t eqj);
-astro_angle_result_t Astronomy_EclipticLongitude(astro_body_t body, astro_time_t time);
+_PREFIX astro_ecliptic_t Astronomy_SunPosition(astro_time_t time);
+_PREFIX astro_ecliptic_t Astronomy_Ecliptic(astro_vector_t eqj);
+_PREFIX astro_angle_result_t Astronomy_EclipticLongitude(astro_body_t body, astro_time_t time);
-astro_horizon_t Astronomy_Horizon(
+_PREFIX astro_horizon_t Astronomy_Horizon(
astro_time_t *time,
astro_observer_t observer,
double ra,
double dec,
astro_refraction_t refraction);
-astro_angle_result_t Astronomy_AngleFromSun(astro_body_t body, astro_time_t time);
-astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time);
-astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t startTime);
-astro_angle_result_t Astronomy_PairLongitude(astro_body_t body1, astro_body_t body2, astro_time_t time);
+_PREFIX astro_angle_result_t Astronomy_AngleFromSun(astro_body_t body, astro_time_t time);
+_PREFIX astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time);
+_PREFIX astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t startTime);
+_PREFIX astro_angle_result_t Astronomy_PairLongitude(astro_body_t body1, astro_body_t body2, astro_time_t time);
/** @cond DOXYGEN_SKIP */
/* Provided for backward compatibility. Newer code can use Astronomy_PairLongitude. */
#define Astronomy_LongitudeFromSun(body,time) (Astronomy_PairLongitude((body), BODY_SUN, (time)))
/** @endcond */
-astro_search_result_t Astronomy_SearchRelativeLongitude(astro_body_t body, double targetRelLon, astro_time_t startTime);
-astro_angle_result_t Astronomy_MoonPhase(astro_time_t time);
-astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t startTime, double limitDays);
-astro_moon_quarter_t Astronomy_SearchMoonQuarter(astro_time_t startTime);
-astro_moon_quarter_t Astronomy_NextMoonQuarter(astro_moon_quarter_t mq);
-astro_lunar_eclipse_t Astronomy_SearchLunarEclipse(astro_time_t startTime);
-astro_lunar_eclipse_t Astronomy_NextLunarEclipse(astro_time_t prevEclipseTime);
-astro_global_solar_eclipse_t Astronomy_SearchGlobalSolarEclipse(astro_time_t startTime);
-astro_global_solar_eclipse_t Astronomy_NextGlobalSolarEclipse(astro_time_t prevEclipseTime);
-astro_local_solar_eclipse_t Astronomy_SearchLocalSolarEclipse(astro_time_t startTime, astro_observer_t observer);
-astro_local_solar_eclipse_t Astronomy_NextLocalSolarEclipse(astro_time_t prevEclipseTime, astro_observer_t observer);
-astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTime);
-astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransitTime);
-astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime);
-astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode);
-
-astro_search_result_t Astronomy_Search(
+_PREFIX astro_search_result_t Astronomy_SearchRelativeLongitude(astro_body_t body, double targetRelLon, astro_time_t startTime);
+_PREFIX astro_angle_result_t Astronomy_MoonPhase(astro_time_t time);
+_PREFIX astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t startTime, double limitDays);
+_PREFIX astro_moon_quarter_t Astronomy_SearchMoonQuarter(astro_time_t startTime);
+_PREFIX astro_moon_quarter_t Astronomy_NextMoonQuarter(astro_moon_quarter_t mq);
+_PREFIX astro_lunar_eclipse_t Astronomy_SearchLunarEclipse(astro_time_t startTime);
+_PREFIX astro_lunar_eclipse_t Astronomy_NextLunarEclipse(astro_time_t prevEclipseTime);
+_PREFIX astro_global_solar_eclipse_t Astronomy_SearchGlobalSolarEclipse(astro_time_t startTime);
+_PREFIX astro_global_solar_eclipse_t Astronomy_NextGlobalSolarEclipse(astro_time_t prevEclipseTime);
+_PREFIX astro_local_solar_eclipse_t Astronomy_SearchLocalSolarEclipse(astro_time_t startTime, astro_observer_t observer);
+_PREFIX astro_local_solar_eclipse_t Astronomy_NextLocalSolarEclipse(astro_time_t prevEclipseTime, astro_observer_t observer);
+_PREFIX astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTime);
+_PREFIX astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransitTime);
+_PREFIX astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime);
+_PREFIX astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode);
+
+_PREFIX astro_search_result_t Astronomy_Search(
astro_search_func_t func,
void *context,
astro_time_t t1,
astro_time_t t2,
double dt_tolerance_seconds);
-astro_search_result_t Astronomy_SearchSunLongitude(
+_PREFIX astro_search_result_t Astronomy_SearchSunLongitude(
double targetLon,
astro_time_t startTime,
double limitDays);
-astro_hour_angle_t Astronomy_SearchHourAngleEx(
+_PREFIX astro_hour_angle_t Astronomy_SearchHourAngleEx(
astro_body_t body,
astro_observer_t observer,
double hourAngle,
astro_time_t startTime,
int direction);
-astro_func_result_t Astronomy_HourAngle(
+_PREFIX astro_func_result_t Astronomy_HourAngle(
astro_body_t body,
astro_time_t *time,
astro_observer_t observer);
@@ -1302,7 +1309,7 @@ astro_func_result_t Astronomy_HourAngle(
/** @endcond */
-astro_search_result_t Astronomy_SearchRiseSetEx(
+_PREFIX astro_search_result_t Astronomy_SearchRiseSetEx(
astro_body_t body,
astro_observer_t observer,
astro_direction_t direction,
@@ -1310,7 +1317,7 @@ astro_search_result_t Astronomy_SearchRiseSetEx(
double limitDays,
double metersAboveGround);
-astro_search_result_t Astronomy_SearchAltitude(
+_PREFIX astro_search_result_t Astronomy_SearchAltitude(
astro_body_t body,
astro_observer_t observer,
astro_direction_t direction,
@@ -1318,55 +1325,55 @@ astro_search_result_t Astronomy_SearchAltitude(
double limitDays,
double altitude);
-astro_atmosphere_t Astronomy_Atmosphere(double elevationMeters);
-
-astro_axis_t Astronomy_RotationAxis(astro_body_t body, astro_time_t *time);
-
-astro_seasons_t Astronomy_Seasons(int year);
-astro_illum_t Astronomy_Illumination(astro_body_t body, astro_time_t time);
-astro_illum_t Astronomy_SearchPeakMagnitude(astro_body_t body, astro_time_t startTime);
-astro_apsis_t Astronomy_SearchLunarApsis(astro_time_t startTime);
-astro_apsis_t Astronomy_NextLunarApsis(astro_apsis_t apsis);
-astro_apsis_t Astronomy_SearchPlanetApsis(astro_body_t body, astro_time_t startTime);
-astro_apsis_t Astronomy_NextPlanetApsis(astro_body_t body, astro_apsis_t apsis);
-
-astro_rotation_t Astronomy_IdentityMatrix(void);
-astro_rotation_t Astronomy_InverseRotation(astro_rotation_t rotation);
-astro_rotation_t Astronomy_CombineRotation(astro_rotation_t a, astro_rotation_t b);
-astro_rotation_t Astronomy_Pivot(astro_rotation_t rotation, int axis, double angle);
-astro_vector_t Astronomy_VectorFromSphere(astro_spherical_t sphere, astro_time_t time);
-astro_spherical_t Astronomy_SphereFromVector(astro_vector_t vector);
-astro_equatorial_t Astronomy_EquatorFromVector(astro_vector_t vector);
-astro_vector_t Astronomy_VectorFromHorizon(astro_spherical_t sphere, astro_time_t time, astro_refraction_t refraction);
-astro_spherical_t Astronomy_HorizonFromVector(astro_vector_t vector, astro_refraction_t refraction);
-astro_vector_t Astronomy_RotateVector(astro_rotation_t rotation, astro_vector_t vector);
-astro_state_vector_t Astronomy_RotateState(astro_rotation_t rotation, astro_state_vector_t state);
-
-astro_rotation_t Astronomy_Rotation_EQD_EQJ(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_EQD_ECL(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_EQD_ECT(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_EQD_HOR(astro_time_t *time, astro_observer_t observer);
-astro_rotation_t Astronomy_Rotation_EQJ_EQD(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_EQJ_ECT(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_EQJ_ECL(void);
-astro_rotation_t Astronomy_Rotation_EQJ_HOR(astro_time_t *time, astro_observer_t observer);
-astro_rotation_t Astronomy_Rotation_ECL_EQD(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_ECL_EQJ(void);
-astro_rotation_t Astronomy_Rotation_ECL_HOR(astro_time_t *time, astro_observer_t observer);
-astro_rotation_t Astronomy_Rotation_ECT_EQJ(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_ECT_EQD(astro_time_t *time);
-astro_rotation_t Astronomy_Rotation_HOR_EQD(astro_time_t *time, astro_observer_t observer);
-astro_rotation_t Astronomy_Rotation_HOR_EQJ(astro_time_t *time, astro_observer_t observer);
-astro_rotation_t Astronomy_Rotation_HOR_ECL(astro_time_t *time, astro_observer_t observer);
-astro_rotation_t Astronomy_Rotation_EQJ_GAL(void);
-astro_rotation_t Astronomy_Rotation_GAL_EQJ(void);
-
-double Astronomy_Refraction(astro_refraction_t refraction, double altitude);
-double Astronomy_InverseRefraction(astro_refraction_t refraction, double bent_altitude);
-
-astro_constellation_t Astronomy_Constellation(double ra, double dec);
-
-astro_status_t Astronomy_GravSimInit(
+_PREFIX astro_atmosphere_t Astronomy_Atmosphere(double elevationMeters);
+
+_PREFIX astro_axis_t Astronomy_RotationAxis(astro_body_t body, astro_time_t *time);
+
+_PREFIX astro_seasons_t Astronomy_Seasons(int year);
+_PREFIX astro_illum_t Astronomy_Illumination(astro_body_t body, astro_time_t time);
+_PREFIX astro_illum_t Astronomy_SearchPeakMagnitude(astro_body_t body, astro_time_t startTime);
+_PREFIX astro_apsis_t Astronomy_SearchLunarApsis(astro_time_t startTime);
+_PREFIX astro_apsis_t Astronomy_NextLunarApsis(astro_apsis_t apsis);
+_PREFIX astro_apsis_t Astronomy_SearchPlanetApsis(astro_body_t body, astro_time_t startTime);
+_PREFIX astro_apsis_t Astronomy_NextPlanetApsis(astro_body_t body, astro_apsis_t apsis);
+
+_PREFIX astro_rotation_t Astronomy_IdentityMatrix(void);
+_PREFIX astro_rotation_t Astronomy_InverseRotation(astro_rotation_t rotation);
+_PREFIX astro_rotation_t Astronomy_CombineRotation(astro_rotation_t a, astro_rotation_t b);
+_PREFIX astro_rotation_t Astronomy_Pivot(astro_rotation_t rotation, int axis, double angle);
+_PREFIX astro_vector_t Astronomy_VectorFromSphere(astro_spherical_t sphere, astro_time_t time);
+_PREFIX astro_spherical_t Astronomy_SphereFromVector(astro_vector_t vector);
+_PREFIX astro_equatorial_t Astronomy_EquatorFromVector(astro_vector_t vector);
+_PREFIX astro_vector_t Astronomy_VectorFromHorizon(astro_spherical_t sphere, astro_time_t time, astro_refraction_t refraction);
+_PREFIX astro_spherical_t Astronomy_HorizonFromVector(astro_vector_t vector, astro_refraction_t refraction);
+_PREFIX astro_vector_t Astronomy_RotateVector(astro_rotation_t rotation, astro_vector_t vector);
+_PREFIX astro_state_vector_t Astronomy_RotateState(astro_rotation_t rotation, astro_state_vector_t state);
+
+_PREFIX astro_rotation_t Astronomy_Rotation_EQD_EQJ(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQD_ECL(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQD_ECT(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQD_HOR(astro_time_t *time, astro_observer_t observer);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_EQD(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_ECT(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_ECL(void);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_HOR(astro_time_t *time, astro_observer_t observer);
+_PREFIX astro_rotation_t Astronomy_Rotation_ECL_EQD(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_ECL_EQJ(void);
+_PREFIX astro_rotation_t Astronomy_Rotation_ECL_HOR(astro_time_t *time, astro_observer_t observer);
+_PREFIX astro_rotation_t Astronomy_Rotation_ECT_EQJ(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_ECT_EQD(astro_time_t *time);
+_PREFIX astro_rotation_t Astronomy_Rotation_HOR_EQD(astro_time_t *time, astro_observer_t observer);
+_PREFIX astro_rotation_t Astronomy_Rotation_HOR_EQJ(astro_time_t *time, astro_observer_t observer);
+_PREFIX astro_rotation_t Astronomy_Rotation_HOR_ECL(astro_time_t *time, astro_observer_t observer);
+_PREFIX astro_rotation_t Astronomy_Rotation_EQJ_GAL(void);
+_PREFIX astro_rotation_t Astronomy_Rotation_GAL_EQJ(void);
+
+_PREFIX double Astronomy_Refraction(astro_refraction_t refraction, double altitude);
+_PREFIX double Astronomy_InverseRefraction(astro_refraction_t refraction, double bent_altitude);
+
+_PREFIX astro_constellation_t Astronomy_Constellation(double ra, double dec);
+
+_PREFIX astro_status_t Astronomy_GravSimInit(
astro_grav_sim_t **simOut,
astro_body_t originBody,
astro_time_t time,
@@ -1374,23 +1381,23 @@ astro_status_t Astronomy_GravSimInit(
const astro_state_vector_t *bodyStateArray
);
-astro_status_t Astronomy_GravSimUpdate(
+_PREFIX astro_status_t Astronomy_GravSimUpdate(
astro_grav_sim_t *sim,
astro_time_t time,
int numBodies,
astro_state_vector_t *bodyStateArray
);
-astro_state_vector_t Astronomy_GravSimBodyState(
+_PREFIX astro_state_vector_t Astronomy_GravSimBodyState(
astro_grav_sim_t *sim,
astro_body_t body
);
-astro_time_t Astronomy_GravSimTime(const astro_grav_sim_t *sim);
-int Astronomy_GravSimNumBodies(const astro_grav_sim_t *sim);
-astro_body_t Astronomy_GravSimOrigin(const astro_grav_sim_t *sim);
-void Astronomy_GravSimSwap(astro_grav_sim_t *sim);
-void Astronomy_GravSimFree(astro_grav_sim_t *sim);
+_PREFIX astro_time_t Astronomy_GravSimTime(const astro_grav_sim_t *sim);
+_PREFIX int Astronomy_GravSimNumBodies(const astro_grav_sim_t *sim);
+_PREFIX astro_body_t Astronomy_GravSimOrigin(const astro_grav_sim_t *sim);
+_PREFIX void Astronomy_GravSimSwap(astro_grav_sim_t *sim);
+_PREFIX void Astronomy_GravSimFree(astro_grav_sim_t *sim);
/**
* @brief A function for which to solve a light-travel time problem.
@@ -1404,20 +1411,20 @@ void Astronomy_GravSimFree(astro_grav_sim_t *sim);
*/
typedef astro_vector_t (* astro_position_func_t) (void *context, astro_time_t time);
-astro_vector_t Astronomy_CorrectLightTravel(
+_PREFIX astro_vector_t Astronomy_CorrectLightTravel(
void *context,
astro_position_func_t func,
astro_time_t time
);
-astro_vector_t Astronomy_BackdatePosition(
+_PREFIX astro_vector_t Astronomy_BackdatePosition(
astro_time_t time,
astro_body_t observerBody,
astro_body_t targetBody,
astro_aberration_t aberration
);
-astro_status_t Astronomy_DefineStar(
+_PREFIX astro_status_t Astronomy_DefineStar(
astro_body_t body,
double ra,
double dec,
diff --git a/source/pascal/Astronomy.pas b/source/pascal/Astronomy.pas
new file mode 100644
index 00000000..36ce0083
--- /dev/null
+++ b/source/pascal/Astronomy.pas
@@ -0,0 +1,802 @@
+unit Astronomy;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes
+ { you can add units after this };
+
+const
+ LibraryName = 'astronomy'; // should refer the astronomy.dll file
+
+ C_AUDAY : Double = 173.1446326846693;
+ KM_PER_AU : Double = 1.4959787069098932e+8;
+ AU_PER_LY : Double = 63241.07708807546;
+ DEG2RAD : Double = 0.017453292519943296;
+ HOUR2RAD : Double = 0.2617993877991494365;
+ RAD2DEG : Double = 57.295779513082321;
+ RAD2HOUR : Double = 3.819718634205488;
+ SUN_RADIUS_KM : Double = 695700.0;
+ MERCURY_EQUATORIAL_RADIUS_KM : Double = 2440.5;
+ MERCURY_POLAR_RADIUS_KM : Double = 2438.3;
+ VENUS_RADIUS_KM : Double = 6051.8;
+ EARTH_EQUATORIAL_RADIUS_KM : Double = 6378.1366;
+ EARTH_FLATTENING : Double = 0.996647180302104;
+ EARTH_POLAR_RADIUS_KM : Double = 6378.1366 * 0.996647180302104;
+ MOON_EQUATORIAL_RADIUS_KM : Double = 1738.1;
+ MOON_POLAR_RADIUS_KM : Double = 1736.0;
+ MARS_EQUATORIAL_RADIUS_KM : Double = 3396.2;
+ MARS_POLAR_RADIUS_KM : Double = 3376.2;
+ JUPITER_EQUATORIAL_RADIUS_KM : Double = 71492.0;
+ JUPITER_POLAR_RADIUS_KM : Double = 66854.0;
+ JUPITER_MEAN_RADIUS_KM : Double = 69911.0;
+ IO_RADIUS_KM : Double = 1821.6;
+ EUROPA_RADIUS_KM : Double = 1560.8;
+ GANYMEDE_RADIUS_KM : Double = 2631.2;
+ CALLISTO_RADIUS_KM : Double = 2410.3;
+ SATURN_EQUATORIAL_RADIUS_KM : Double = 60268.0;
+ SATURN_POLAR_RADIUS_KM : Double = 54364.0;
+ URANUS_EQUATORIAL_RADIUS_KM : Double = 25559.0;
+ URANUS_POLAR_RADIUS_KM : Double = 24973.0;
+ NEPTUNE_EQUATORIAL_RADIUS_KM : Double = 24764.0;
+ NEPTUNE_POLAR_RADIUS_KM : Double = 24341.0;
+ PLUTO_RADIUS_KM : Double = 1188.3;
+
+type
+ // Status of the last operation.
+ AstroStatus = (
+ ASTRO_SUCCESS = 0, // The operation was successful.
+ ASTRO_NOT_INITIALIZED = 1, // A placeholder that can be used for data that is not yet initialized.
+ ASTRO_INVALID_BODY = 2, // The celestial body was not valid. Different sets of bodies are supported depending on the function.
+ ASTRO_NO_CONVERGE = 3, // A numeric solver failed to converge. This should not happen unless there is a bug in Astronomy Engine.
+ ASTRO_BAD_TIME = 4, // The provided date/time is outside the range allowed by this function.
+ ASTRO_BAD_VECTOR = 5, // Vector magnitude is too small to be normalized into a unit vector.
+ ASTRO_SEARCH_FAILURE = 6, // Search was not able to find an ascending root crossing of the function in the specified time interval.
+ ASTRO_EARTH_NOT_ALLOWED = 7, // The Earth cannot be treated as a celestial body seen from an observer on the Earth itself.
+ ASTRO_NO_MOON_QUARTER = 8, // No lunar quarter occurs inside the specified time range.
+ ASTRO_WRONG_MOON_QUARTER = 9, // Internal error: Astronomy_NextMoonQuarter found the wrong moon quarter.
+ ASTRO_INTERNAL_ERROR = 10, // A self-check failed inside the code somewhere, indicating a bug needs to be fixed.
+ ASTRO_INVALID_PARAMETER = 11, // A parameter value passed to a function was not valid.
+ ASTRO_FAIL_APSIS = 12, // Special-case logic for finding Neptune/Pluto apsis failed.
+ ASTRO_BUFFER_TOO_SMALL = 13, // A provided buffer's size is too small to receive the requested data.
+ ASTRO_OUT_OF_MEMORY = 14, // An attempt to allocate memory failed.
+ ASTRO_INCONSISTENT_TIMES = 15 // The provided initial state vectors did not have matching times.
+ );
+
+ // A celestial body.
+ AstroBody = (
+ BODY_INVALID = -1, // An invalid or undefined celestial body.
+ BODY_MERCURY = 0, // Mercury
+ BODY_VENUS = 1, // Venus
+ BODY_EARTH = 2, // Earth
+ BODY_MARS = 3, // Mars
+ BODY_JUPITER = 4, // Jupiter
+ BODY_SATURN = 5, // Saturn
+ BODY_URANUS = 6, // Uranus
+ BODY_NEPTUNE = 7, // Neptune
+ BODY_PLUTO = 8, // Pluto
+ BODY_SUN = 9, // Sun
+ BODY_MOON = 10, // Moon
+ BODY_EMB = 11, // Earth/Moon Barycenter
+ BODY_SSB = 12, // Solar System Barycenter
+ BODY_STAR1 = 101, // user-defined star #1
+ BODY_STAR2 = 102, // user-defined star #2
+ BODY_STAR3 = 103, // user-defined star #3
+ BODY_STAR4 = 104, // user-defined star #4
+ BODY_STAR5 = 105, // user-defined star #5
+ BODY_STAR6 = 106, // user-defined star #6
+ BODY_STAR7 = 107, // user-defined star #7
+ BODY_STAR8 = 108 // user-defined star #8
+ );
+
+ // Selects whether to correct for atmospheric refraction, and if so, how.
+ AstroRefraction = (
+ REFRACTION_NONE = 0, // No atmospheric refraction correction (airless).
+ REFRACTION_NORMAL = 1, // Recommended correction for standard atmospheric refraction.
+ REFRACTION_JPLHOR = 2 // Used only for compatibility testing with JPL Horizons online tool.
+ );
+
+ // Indicates whether a body (especially Mercury or Venus) is best seen in the morning or evening.
+ AstroVisibility = (
+ VISIBLE_MORNING = 0, // The body is best visible in the morning, before sunrise.
+ VISIBLE_EVENING = 1 // The body is best visible in the evening, after sunset.
+ );
+
+ // The type of apsis: pericenter (closest approach) or apocenter (farthest distance).
+ AstroApsisKind = (
+ APSIS_PERICENTER = 0, // The body is at its closest approach to the object it orbits.
+ APSIS_APOCENTER = 1, // The body is at its farthest distance from the object it orbits.
+ APSIS_INVALID = 2 // Undefined or invalid apsis.
+ );
+
+ // The different kinds of lunar/solar eclipses.
+ AstroEclipseKind = (
+ ECLIPSE_NONE = 0, // No eclipse found.
+ ECLIPSE_PENUMBRAL = 1, // A penumbral lunar eclipse. (Never used for a solar eclipse.)
+ ECLIPSE_PARTIAL = 2, // A partial lunar/solar eclipse.
+ ECLIPSE_ANNULAR = 3, // An annular solar eclipse. (Never used for a lunar eclipse.)
+ ECLIPSE_TOTAL = 4 // A total lunar/solar eclipse.
+ );
+
+ // Aberration calculation options.
+ AstroAberration = (
+ ABERRATION = 0, // Request correction for aberration.
+ NO_ABERRATION = 1 // Do not correct for aberration.
+ );
+
+ // Selects the date for which the Earth's equator is to be used for representing equatorial coordinates.
+ AstroEquatorDate = (
+ EQUATOR_J2000 = 0, // Represent equatorial coordinates in the J2000 epoch.
+ EQUATOR_OF_DATE = 1 // Represent equatorial coordinates using the Earth's equator at the given date and time.
+ );
+
+ // Selects whether to search for a rise time or a set time.
+ AstroDirection = (
+ DIRECTION_SET = -1, // Search for the time a body finishes sinking below the horizon.
+ DIRECTION_RISE = 1 // Search for the time a body begins to rise above the horizon.
+ );
+
+ // Selects the output format of the function #Astronomy_FormatTime.
+ AstroTimeFormat = (
+ TIME_FORMAT_DAY = 0, // Truncate to UTC calendar date only, e.g. `2020-12-31`. Buffer size must be at least 11 characters.
+ TIME_FORMAT_MINUTE = 1, // Round to nearest UTC minute, e.g. `2020-12-31T15:47Z`. Buffer size must be at least 18 characters.
+ TIME_FORMAT_SECOND = 2, // Round to nearest UTC second, e.g. `2020-12-31T15:47:32Z`. Buffer size must be at least 21 characters.
+ TIME_FORMAT_MILLI = 3 // Round to nearest UTC millisecond, e.g. `2020-12-31T15:47:32.397Z`. Buffer size must be at least 25 characters.
+ );
+
+ // Indicates whether a crossing through the ecliptic plane is ascending or descending.
+ AstroNodeKind = (
+ DESCENDING_NODE = -1, // The body passes through the ecliptic plane from north to south.
+ INVALID_NODE = 0, // Placeholder value for a missing or invalid node.
+ ASCENDING_NODE = 1 // The body passes through the ecliptic plane from south to north.
+ );
+
+ // A date and time used for astronomical calculations.
+ AstroTime = packed record
+ UT: Double; // UT1/UTC number of days since noon on January 1, 2000.
+ TT: Double; // Terrestrial Time days since noon on January 1, 2000.
+ Psi: Double; // For internal use only. Used to optimize Earth tilt calculations.
+ Eps: Double; // For internal use only. Used to optimize Earth tilt calculations.
+ ST: Double; // For internal use only. Lazy-caches sidereal time (Earth rotation).
+ end;
+
+ // Pointer to #AstroTime record.
+ PAstroTime = ^AstroTime;
+
+ // A calendar date and time expressed in UTC.
+ AstroUTC = packed record
+ Year: Int32; // The year value, e.g. 2019.
+ Month: Int32; // The month value: 1=January, 2=February, ..., 12=December.
+ Day: Int32; // The day of the month in the range 1..31.
+ Hour: Int32; // The hour of the day in the range 0..23.
+ Minute: Int32; // The minute of the hour in the range 0..59.
+ Second: Double; // The floating point number of seconds in the range [0,60).
+ end;
+
+ // A 3D Cartesian vector whose components are expressed in Astronomical Units (AU).
+ AstroVector = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ X: Double; // The Cartesian x-coordinate of the vector in AU.
+ Y: Double; // The Cartesian y-coordinate of the vector in AU.
+ Z: Double; // The Cartesian z-coordinate of the vector in AU.
+ T: AstroTime; // The date and time at which this vector is valid.
+ end;
+
+ // Pointer to #AstroVector record
+ PAstroVector = ^AstroVector;
+
+ // A state vector that contains a position (AU) and velocity (AU/day).
+ AstroStateVector = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ X: Double; // The Cartesian position x-coordinate of the vector in AU.
+ Y: Double; // The Cartesian position y-coordinate of the vector in AU.
+ Z: Double; // The Cartesian position z-coordinate of the vector in AU.
+ VX: Double; // The Cartesian velocity x-coordinate of the vector in AU/day.
+ VY: Double; // The Cartesian velocity y-coordinate of the vector in AU/day.
+ VZ: Double; // The Cartesian velocity z-coordinate of the vector in AU/day.
+ T: AstroTime; // The date and time at which this state vector is valid.
+ end;
+
+ // Pointer to `AstroStateVector` record.
+ PAstroStateVector = ^AstroStateVector;
+
+ // Spherical coordinates: latitude, longitude, distance.
+ AstroSpherical = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Lat: Double; // The latitude angle: -90..+90 degrees.
+ Lon: Double; // The longitude angle: 0..360 degrees.
+ Dist: Double; // Distance in AU.
+ end;
+
+ // An angular value expressed in degrees.
+ AstroAngleResult = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Angle: Double; // An angle expressed in degrees.
+ end;
+
+ // The location of an observer on (or near) the surface of the Earth.
+ AstroObserver = packed record
+ Latitude: Double; // Geographic latitude in degrees north (positive) or south (negative) of the equator.
+ Longitude: Double; // Geographic longitude in degrees east (positive) or west (negative) of the prime meridian at Greenwich, England.
+ Height: Double; // The height above (positive) or below (negative) sea level, expressed in meters.
+ end;
+
+ // Equatorial angular and cartesian coordinates.
+ AstroEquatorial = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ RA: Double; // right ascension in sidereal hours.
+ Dec: Double; // declination in degrees
+ Dist: Double; // distance to the celestial body in AU.
+ Vec: AstroVector; // equatorial coordinates in cartesian vector form: x = March equinox, y = June solstice, z = north.
+ end;
+
+ // Ecliptic angular and Cartesian coordinates.
+ AstroEcliptic = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Vec: AstroVector; // Cartesian ecliptic vector: x=equinox, y=90 degrees prograde in ecliptic plane, z=northward perpendicular to ecliptic.
+ ELat: Double; // Latitude in degrees north (positive) or south (negative) of the ecliptic plane.
+ ELon: Double; // Longitude in degrees around the ecliptic plane prograde from the equinox.
+ end;
+
+ // Coordinates of a celestial body as seen by a topocentric observer.
+ AstroHorizon = packed record
+ Azimuth: Double; // Compass direction around the horizon in degrees. 0=North, 90=East, 180=South, 270=West.
+ Altitude: Double; // Angle in degrees above (positive) or below (negative) the observer's horizon.
+ RA: Double; // Right ascension in sidereal hours.
+ Dec: Double; // Declination in degrees.
+ end;
+
+ // Contains a rotation matrix that can be used to transform one coordinate system to another.
+ AstroRotation = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Rot: array[1..3, 1..3] of Double; // A normalized 3x3 rotation matrix.
+ end;
+
+ // Information about idealized atmospheric variables at a given elevation.
+ AstroAtmosphere = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Pressure: Double; // Atmospheric pressure in pascals
+ Temperature: Double; // Atmospheric temperature in kelvins
+ Density: Double; // Atmospheric density relative to sea level
+ end;
+
+ // The result of a search for an astronomical event.
+ AstroSearchResult = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Time: AstroTime; // The time at which a searched-for event occurs.
+ end;
+
+{ The dates and times of changes of season for a given calendar year.
+ Call #Astronomy_Seasons to calculate this data structure for a given year. }
+ AstroSeasons = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ MarEquinox: AstroTime; // The date and time of the March equinox for the specified year.
+ JunSolstice: AstroTime; // The date and time of the June soltice for the specified year.
+ SepEquinox: AstroTime; // The date and time of the September equinox for the specified year.
+ DecSolstice: AstroTime; // The date and time of the December solstice for the specified year.
+ end;
+
+ // A lunar quarter event (new moon, first quarter, full moon, or third quarter) along with its date and time.
+ AstroMoonQuarter = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Quarter: Int32; // 0=new moon, 1=first quarter, 2=full moon, 3=third quarter.
+ Time: AstroTime; // The date and time of the lunar quarter.
+ end;
+
+ // A real value returned by a function whose ascending root is to be found.
+ AstroFuncResult = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Value: Double; // The value returned by a function whose ascending root is to be found.
+ end;
+
+ // Contains information about the visibility of a celestial body at a given date and time.
+ AstroElongation = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Time: AstroTime; // The date and time of the observation.
+ Visibility: AstroVisibility; // Whether the body is best seen in the morning or the evening.
+ Elongation: Double; // The angle in degrees between the body and the Sun, as seen from the Earth.
+ EclipticSeparation: Double; // The difference between the ecliptic longitudes of the body and the Sun, as seen from the Earth.
+ end;
+
+ // Information about a celestial body crossing a specific hour angle.
+ AstroHourAngle = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Time: AstroTime; // The date and time when the body crosses the specified hour angle.
+ Hor: AstroHorizon; // Apparent coordinates of the body at the time it crosses the specified hour angle.
+ end;
+
+ // Information about the brightness and illuminated shape of a celestial body.
+ AstroIllum = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Time: AstroTime; // The date and time of the observation.
+ Mag: Double; // The visual magnitude of the body. Smaller values are brighter.
+ PhaseAngle: Double; // The angle in degrees between the Sun and the Earth, as seen from the body. Indicates the body's phase as seen from the Earth.
+ PhaseFraction: Double; // A value in the range [0.0, 1.0] indicating what fraction of the body's apparent disc is illuminated, as seen from the Earth.
+ HelioDist: Double; // The distance between the Sun and the body at the observation time.
+ RingTilt: Double; // For Saturn, the tilt angle in degrees of its rings as seen from Earth. For all other bodies, 0.
+ end;
+
+ // An apsis event: pericenter (closest approach) or apocenter (farthest distance).
+ AstroApsis = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Time: AstroTime; // The date and time of the apsis.
+ Kind: AstroApsisKind; // Whether this is a pericenter or apocenter event.
+ DistAU: Double; // The distance between the centers of the bodies in astronomical units.
+ DistKM: Double; // The distance between the centers of the bodies in kilometers.
+ end;
+
+ // Information about a lunar eclipse.
+ AstroLunarEclipse = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Kind: AstroEclipseKind; // The type of lunar eclipse found.
+ Obscuration: Double; // The peak fraction of the Moon's apparent disc that is covered by the Earth's umbra.
+ Peak: AstroTime; // The time of the eclipse at its peak.
+ SDPenum: Double; // The semi-duration of the penumbral phase in minutes.
+ SDPartial: Double; // The semi-duration of the partial phase in minutes, or 0.0 if none.
+ SDTotal: Double; // The semi-duration of the total phase in minutes, or 0.0 if none.
+ end;
+
+ // Reports the time and geographic location of the peak of a solar eclipse.
+ AstroGlobalSolarEclipse = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Kind: AstroEclipseKind; // The type of solar eclipse found.
+ Obscuration: Double; // The peak fraction of the Sun's apparent disc area obscured by the Moon (total and annular eclipses only).
+ Peak: AstroTime; // The date and time when the solar eclipse is darkest. This is the instant when the axis of the Moon's shadow cone passes closest to the Earth's center.
+ Distance: Double; // The distance between the Sun/Moon shadow axis and the center of the Earth, in kilometers.
+ Latitude: Double; // The geographic latitude at the center of the peak eclipse shadow.
+ Longitude: Double; // The geographic longitude at the center of the peak eclipse shadow.
+ end;
+
+ // Holds a time and the observed altitude of the Sun at that time.
+ AstroEclipseEvent = packed record
+ Time: AstroTime; // The date and time of the event.
+ Altitude: Double; // The angular altitude of the center of the Sun above/below the horizon, at `time`, corrected for atmospheric refraction and expressed in degrees.
+ end;
+
+ // Information about a solar eclipse as seen by an observer at a given time and geographic location.
+ AstroLocalSolarEclipse = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Kind: AstroEclipseKind; // The type of solar eclipse found: `ECLIPSE_PARTIAL`, `ECLIPSE_ANNULAR`, or `ECLIPSE_TOTAL`.
+ Obscuration: Double; // The fraction of the Sun's apparent disc area obscured by the Moon at the eclipse peak.
+ PartialBegin: AstroEclipseEvent; // The time and Sun altitude at the beginning of the eclipse.
+ TotalBegin: AstroEclipseEvent; // If this is an annular or a total eclipse, the time and Sun altitude when annular/total phase begins; otherwise invalid.
+ Peak: AstroEclipseEvent; // The time and Sun altitude when the eclipse reaches its peak.
+ TotalEnd: AstroEclipseEvent; // If this is an annular or a total eclipse, the time and Sun altitude when annular/total phase ends; otherwise invalid.
+ PartialEnd: AstroEclipseEvent; // The time and Sun altitude at the end of the eclipse.
+ end;
+
+ // Information about a transit of Mercury or Venus, as seen from the Earth.
+ AstroTransit = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Start: AstroTime; // Date and time at the beginning of the transit.
+ Peak: AstroTime; // Date and time of the peak of the transit.
+ Finish: AstroTime; // Date and time at the end of the transit.
+ Separation: Double; // Angular separation in arcminutes between the centers of the Sun and the planet at time `peak`.
+ end;
+
+ // Reports the constellation that a given celestial point lies within.
+ AstroConstellation = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Symbol: PChar; // 3-character mnemonic symbol for the constellation, e.g. "Ori".
+ Name: PChar; // Full name of constellation, e.g. "Orion".
+ RA1875: Double; // Right ascension expressed in B1875 coordinates.
+ Dec1875: Double; // Declination expressed in B1875 coordinates.
+ end;
+
+ // Lunar libration angles, returned by #Astronomy_Libration.
+ AstroLibration = packed record
+ ELat: Double; // Sub-Earth libration ecliptic latitude angle, in degrees.
+ ELon: Double; // Sub-Earth libration ecliptic longitude angle, in degrees.
+ MLat: Double; // Moon's geocentric ecliptic latitude, in degrees.
+ MLon: Double; // Moon's geocentric ecliptic longitude, in degrees.
+ DistKM: Double; // Distance between the centers of the Earth and Moon in kilometers.
+ DiamDeg: Double; // The apparent angular diameter of the Moon, in degrees, as seen from the center of the Earth.
+ end;
+
+ // Information about a body's rotation axis at a given time.
+ AstroAxis = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ RA: Double; // The J2000 right ascension of the body's north pole direction, in sidereal hours.
+ Dec: Double; // The J2000 declination of the body's north pole direction, in degrees.
+ Spin: Double; // Rotation angle of the body's prime meridian, in degrees.
+ North: AstroVector; // A J2000 dimensionless unit vector pointing in the direction of the body's north pole.
+ end;
+
+ // Holds the positions and velocities of Jupiter's major 4 moons.
+ AstroJupiterMoons = packed record
+ IO: AstroStateVector; // Jovicentric position and velocity of Io.
+ Europa: AstroStateVector; // Jovicentric position and velocity of Europa.
+ Ganymede: AstroStateVector; // Jovicentric position and velocity of Ganymede.
+ Callisto: AstroStateVector; // Jovicentric position and velocity of Callisto.
+ end;
+
+ // Information about an ascending or descending node of a body.
+ AstroNodeEvent = packed record
+ Status: AstroStatus; // `ASTRO_SUCCESS` if this struct is valid; otherwise an error code.
+ Time: AstroTime; // The time when the body passes through the ecliptic plane.
+ Kind: AstroNodeKind; // Either `ASCENDING_NODE` or `DESCENDING_NODE`, depending on the direction of the ecliptic plane crossing.
+ end;
+
+ // A data type used for managing simulation of the gravitational forces on a small body.
+ AstroGravSim = packed record
+ end;
+
+ // Pointer to `AstroGravSim` record.
+ PAstroGravSim = ^AstroGravSim;
+
+ // A pointer to a function that is to be passed as a callback to #Astronomy_Search.
+ PAstroSearchFunc = function(Context: Pointer; Time: AstroTime): AstroFuncResult; cdecl;
+
+ // A pointer to a function that calculates Delta T.
+ PAstroDeltaTFunc = function(UT: Double): Double; cdecl;
+
+ // A pointer to a function for which to solve a light-travel time problem.
+ PAstroPositionFunc = function(Context: Pointer; Time: AstroTime): AstroVector; cdecl;
+
+ // The default Delta T function used by Astronomy Engine.
+ function Astronomy_DeltaT_EspenakMeeus(UT: Double): Double; cdecl; external LibraryName;
+
+ // A Delta T function that approximates the one used by the JPL Horizons tool
+ function Astronomy_DeltaT_JplHorizons(UT: Double): Double; cdecl; external LibraryName;
+
+ // Changes the function Astronomy Engine uses to calculate Delta T.
+ procedure Astronomy_SetDeltaTFunction(Func: PAstroDeltaTFunc); cdecl; external LibraryName;
+
+ // Frees up all dynamic memory allocated by Astronomy Engine.
+ procedure Astronomy_Reset(); cdecl; external LibraryName;
+
+ // Calculates the length of the given vector. The returned length is expressed usually in AU.
+ function Astronomy_VectorLength(Vector: AstroVector): Double; cdecl; external LibraryName;
+
+ // Calculates the angle between two vectors. The returned angle is expressed in degrees.
+ function Astronomy_AngleBetween(A: AstroVector; B: AstroVector): AstroAngleResult; cdecl; external LibraryName;
+
+ // Finds the name of a celestial body.
+ function Astronomy_BodyName(Body: AstroBody): PChar; cdecl; external LibraryName;
+
+{ Returns the #AstroBody value corresponding to the given English name.
+ Valid parameter values are one of: Sun, Moon, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, EMB, SSB. }
+ function Astronomy_BodyCode(Name: PChar): AstroBody; cdecl; external LibraryName;
+
+ // Creates an observer object that represents a location on or near the surface of the Earth.
+ function Astronomy_MakeObserver(Latitude: Double; Longitude: Double; Height: Double): AstroObserver; cdecl; external LibraryName;
+
+ // Returns the computer's current date and time in the form of an #AstroTime.
+ function Astronomy_CurrentTime(): AstroTime; cdecl; external LibraryName;
+
+ // Creates an #AstroTime value from a given calendar date and time.
+ function Astronomy_MakeTime(Year: Int32; Month: Int32; Day: Int32; Hour: Int32; Minute: Int32; Second: Double): AstroTime; cdecl; external LibraryName;
+
+ // Creates an #AstroTime value from a given calendar date and time.
+ function Astronomy_TimeFromUtc(UTC: AstroUTC): AstroTime; cdecl; external LibraryName;
+
+ // Determines the calendar year, month, day and time from an #AstroTime value.
+ function Astronomy_UtcFromTime(Time: AstroTime): AstroUTC; cdecl; external LibraryName;
+
+ // Formats an #AstroTime value as an ISO 8601 string.
+ function Astronomy_FormatTime(Time: AstroTime; Format: AstroTimeFormat; Text: PChar; Size: Int64): AstroStatus; cdecl; external LibraryName;
+
+ // Converts a J2000 day value to an #AstroTime value.
+ function Astronomy_TimeFromDays(UT: Double): AstroTime; cdecl; external LibraryName;
+
+ // Converts a terrestrial time value into an #AstroTime value.
+ function Astronomy_TerrestrialTime(TT: Double): AstroTime; cdecl; external LibraryName;
+
+ // Calculates the sum or difference of an #AstroTime with a specified floating point number of days.
+ function Astronomy_AddDays(Time: AstroTime; Days: Double): AstroTime; cdecl; external LibraryName;
+
+ // Calculates Greenwich Apparent Sidereal Time (GAST) and returns in sidereal hours.
+ function Astronomy_SiderealTime(Time: PAstroTime): Double; cdecl; external LibraryName;
+
+ // Calculates the distance from a body to the Sun at a given time.
+ function Astronomy_HelioDistance(Body: AstroBody; Time: AstroTime): AstroFuncResult; cdecl; external LibraryName;
+
+ // Calculates heliocentric Cartesian coordinates of a body in the J2000 equatorial system.
+ function Astronomy_HelioVector(Body: AstroBody; Time: AstroTime): AstroVector; cdecl; external LibraryName;
+
+ // Calculates geocentric Cartesian coordinates of a body in the J2000 equatorial system.
+ function Astronomy_GeoVector(Body: AstroBody; Time: AstroTime; Aberration: AstroAberration): AstroVector; cdecl; external LibraryName;
+
+ // Calculates equatorial geocentric position of the Moon at a given time in the J2000 equatorial system.
+ function Astronomy_GeoMoon(Time: AstroTime): AstroVector; cdecl; external LibraryName;
+
+ // Calculates spherical ecliptic geocentric postition of the Moon in the equatorial system of date.
+ function Astronomy_EclipticGeoMoon(Time: AstroTime): AstroSpherical; cdecl; external LibraryName;
+
+ // Calculates equatorial geocentric postition of the Moon at a given time in the J2000 equatorial system.
+ function Astronomy_GeoMoonState(Time: AstroTime): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates the geocentric position and velocity of the Earth/Moon barycenter in the J2000 equatorial system.
+ function Astronomy_GeoEmbState(Time: AstroTime): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates the Moon's libration angles at a given moment in time.
+ function Astronomy_Libration(Time: AstroTime): AstroLibration; cdecl; external LibraryName;
+
+ // Calculates barycentric position and velocity vectors for the given body (everything except stars).
+ function Astronomy_BaryState(Body: AstroBody; Time: AstroTime): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates heliocentric position and velocity vectors for the given body (including stars).
+ function Astronomy_HelioState(Body: AstroBody; Time: AstroTime): AstroStateVector; cdecl; external LibraryName;
+
+ // Returns the product of mass and universal gravitational constant of a Solar System body.
+ function Astronomy_MassProduct(Body: AstroBody): Double; cdecl; external LibraryName;
+
+ // Returns the average number of days it takes for a planet to orbit the Sun.
+ function Astronomy_PlanetOrbitalPeriod(Body: AstroBody): Double; cdecl; external LibraryName;
+
+ // Calculates one of the 5 Lagrange points for a pair of co-orbiting bodies.
+ function Astronomy_LagrangePoint(Point: Int32; Time: AstroTime; MajorBody: AstroBody; MinorBody: AstroBody): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates one of the 5 Lagrange points from body masses and state vectors.
+ function Astronomy_LagrangePointFast(Point: Int32; MajorState: AstroStateVector; MajorMass: Double; MinorState: AstroStateVector; MinorMass: Double): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates joviocentric positions and velocities of Jupiter's largest 4 moons.
+ function Astronomy_JupiterMoons(Time: AstroTime): AstroJupiterMoons; cdecl; external LibraryName;
+
+ // Calculates equatorial coordinates of a celestial body as seen by an observer on the Earth's surface.
+ function Astronomy_Equator(Body: AstroBody; Time: PAstroTime; Observer: AstroObserver; EquDate: AstroEquatorDate; Aberration: AstroAberration): AstroEquatorial; cdecl; external LibraryName;
+
+ // Calculates geocentric equatorial coordinates of an observer on the surface of the Earth.
+ function Astronomy_ObserverVector(Time: PAstroTime; Observer: AstroObserver; EquDate: AstroEquatorDate): AstroVector; cdecl; external LibraryName;
+
+ // Calculates geocentric equatorial postition and velocity of an observer on the surface of the Earth.
+ function Astronomy_ObserverState(Time: PAstroTime; Observer: AstroObserver; EquDate: AstroEquatorDate): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates the geographic location corresponding to an equatorial vector.
+ function Astronomy_VectorObserver(Vector: PAstroVector; EquDate: AstroEquatorDate): AstroObserver; cdecl; external LibraryName;
+
+ // Calculates the gravitational acceleration experienced by an observer on the Earth and returns acceleration expressed in meters per second squared.
+ function Astronomy_ObserverGravity(Latitude: Double; Height: Double): Double; cdecl; external LibraryName;
+
+ // Calculates geocentric ecliptic coordinates for the Sun.
+ function Astronomy_SunPosition(Time: AstroTime): AstroEcliptic; cdecl; external LibraryName;
+
+ // Converts a J2000 mean equator (EQJ) vector to a true ecliptic of date (ETC) vector and angles.
+ function Astronomy_Ecliptic(EQJ: AstroVector): AstroEcliptic; cdecl; external LibraryName;
+
+ // Calculates heliocentric ecliptic longitude of a body.
+ function Astronomy_EclipticLongitude(Body: AstroBody; Time: AstroTime): AstroAngleResult; cdecl; external LibraryName;
+
+ // Calculates the apparent location of a body relative to the local horizon of an observer on the Earth.
+ function Astronomy_Horizon(Time: PAstroTime; Observer: AstroObserver; RA: Double; Dec: Double; Refraction: AstroRefraction): AstroHorizon; cdecl; external LibraryName;
+
+ // Returns the angle between the given body and the Sun, as seen from the Earth.
+ function Astronomy_AngleFromSun(Body: AstroBody; Time: AstroTime): AstroAngleResult; cdecl; external LibraryName;
+
+ // Determins visibility of a celestial body realtive to the Sun, as seen from the Earth.
+ function Astronomy_Elongation(Body: AstroBody; Time: AstroTime): AstroElongation; cdecl; external LibraryName;
+
+ // Finds a date and time when Mercury or Venus reaches its maximum angle from the Sun as seen from the Earth.
+ function Astronomy_SearchMaxElongation(Body: AstroBody; StartTime: AstroTime): AstroElongation; cdecl; external LibraryName;
+
+ // Returns one body's ecliptic longitude with respect to another, as seen from Earth.
+ function Astronomy_PairLongitude(Body1: AstroBody; Body2: AstroBody; Time: AstroTime): AstroAngleResult; cdecl; external LibraryName;
+
+ // Searches for the time when the Earth and another planet are separated by a specified angle in eclipctic longitude, as seen from the Sun.
+ function Astronomy_SearchRelativeLongitude(Body: AstroBody; TargetRelLon: Double; StartTime: AstroTime): AstroSearchResult; cdecl; external LibraryName;
+
+ // Returns the Moon's phase as an angle from 0 to 360 degrees.
+ function Astronomy_MoonPhase(Time: AstroTime): AstroAngleResult; cdecl; external LibraryName;
+
+ // Searches for the time that the Moon reaches a specified phase.
+ function Astronomy_SearchMoonPhase(TargetLon: Double; StartTime: AstroTime; LimitDays: Double): AstroSearchResult; cdecl; external LibraryName;
+
+ // Finds the first lunar quarter after the specified date and time.
+ function Astronomy_SearchMoonQuarter(StartTime: AstroTime): AstroMoonQuarter; cdecl; external LibraryName;
+
+ // Continues searching for lunar quarters from previous search.
+ function Astronomy_NextMoonQuarter(MQ: AstroMoonQuarter): AstroMoonQuarter; cdecl; external LibraryName;
+
+ // Searches for a lunar eclipse.
+ function Astronomy_SearchLunarEclipse(StartTime: AstroTime): AstroLunarEclipse; cdecl; external LibraryName;
+
+ // Searches for the next lunar eclipse in a series.
+ function Astronomy_NextLunarEclipse(PrevEclipseTime: AstroTime): AstroLunarEclipse; cdecl; external LibraryName;
+
+ // Searches for a solar eclipse visible anywhere on the Earth's surface.
+ function Astronomy_SearchGlobalSolarEclipse(StartTime: AstroTime): AstroGlobalSolarEclipse; cdecl; external LibraryName;
+
+ // Searches for the next global solar eclipse in a series.
+ function Astronomy_NextGlobalSolarEclipse(PrevEclipseTime: AstroTime): AstroGlobalSolarEclipse; cdecl; external LibraryName;
+
+ // Searches for a solar eclipse visible at specific location on the Earth's surface.
+ function Astronomy_SearchLocalSolarEclipse(StartTime: AstroTime; Observer: AstroObserver): AstroLocalSolarEclipse; cdecl; external LibraryName;
+
+ // Searches for the next local solar eclipse in a series.
+ function Astronomy_NextLocalSolarEclipse(PrevEclipseTime: AstroTime; Observer: AstroObserver): AstroLocalSolarEclipse; cdecl; external LibraryName;
+
+ // Searches for the first transit of Mercury or Venus after a given date.
+ function Astronomy_SearchTransit(Body: AstroBody; StartTime: AstroTime): AstroTransit; cdecl; external LibraryName;
+
+ // Searches for another transit of Mercury or Venus.
+ function Astronomy_NextTransit(Body: AstroBody; PrevTransitTime: AstroTime): AstroTransit; cdecl; external LibraryName;
+
+ // Searches for a time when the Moon's center crosses through the ecliptic plane.
+ function Astronomy_SearchMoonNode(StartTime: AstroTime): AstroNodeEvent; cdecl; external LibraryName;
+
+ // Searches for the next time when the Moon's center crosses through the ecliptic plane.
+ function Astronomy_NextMoonNode(PrevNode: AstroNodeEvent): AstroNodeEvent; cdecl; external LibraryName;
+
+ // Searches for a time at which a function's value increases through zero.
+ function Astronomy_Search(Func: PAstroSearchFunc; Context: Pointer; T1: AstroTime; T2: AstroTime; DTToleranceSeconds: Double): AstroSearchResult; cdecl; external LibraryName;
+
+ // Searches for the time when the Sun reaches an apparent ecliptic longitude as seen from the Earth.
+ function Astronomy_SearchSunLongitude(TargetLon: Double; StartTime: AstroTime; LimitDays: Double): AstroSearchResult; cdecl; external LibraryName;
+
+ // Searches for the time when the center of a body reaches a specified hour angle as seen by an observer on the Earth.
+ function Astronomy_SearchHourAngleEx(Body: AstroBody; Observer: AstroObserver; HourAngle: Double; StartTime: AstroTime; Direction: Int32): AstroHourAngle; cdecl; external LibraryName;
+
+ // Finds the hour angle of a body for a given observer and time.
+ function Astronomy_HourAngle(Body: AstroBody; Time: PAstroTime; Observer: AstroObserver): AstroFuncResult; cdecl; external LibraryName;
+
+ // Searches for the next time a celestial body rises or sets as seen by an observer on the Earth.
+ function Astronomy_SearchRiseSetEx(Body: AstroBody; Observer: AstroObserver; Direction: AstroDirection; StartTime: AstroTime; LimitDays: Double; MetersAboveGround: Double): AstroSearchResult; cdecl; external LibraryName;
+
+ // Finds the next time the center of a body passes through a given altitude.
+ function Astronomy_SearchAltitude(Body: AstroBody; Observer: AstroObserver; Direction: AstroDirection; StartTime: AstroTime; LimitDays: Double; Altitude: Double): AstroSearchResult; cdecl; external LibraryName;
+
+ // Calculates U.S. Standard Atmosphere (1976) variables as a function of elevation.
+ function Astronomy_Atmosphere(ElevationMeters: Double): AstroAtmosphere; cdecl; external LibraryName;
+
+ // Calculates information about a body's rotation axis at a given time.
+ function Astronomy_RotationAxis(Body: AstroBody; Time: PAstroTime): AstroAxis; cdecl; external LibraryName;
+
+ // Finds both equinoxes and both solstices for a given calendar year.
+ function Astronomy_Seasons(Year: Int32): AstroSeasons; cdecl; external LibraryName;
+
+ // Finds visual magnitude, phase angle, and other illumination information about a celestial body.
+ function Astronomy_Illumination(Body: AstroBody; Time: AstroTime): AstroIllum; cdecl; external LibraryName;
+
+ // Searches for the date and time Venus will next appear brightest as seen from the Earth.
+ function Astronomy_SearchPeakMagnitude(Body: AstroBody; StartTime: AstroTime): AstroIllum; cdecl; external LibraryName;
+
+ // Finds the date and time of the Moon's closest distance (perigee) or farthest distance (apogee) with the respect to the Earth.
+ function Astronomy_SearchLunarApsis(StartTime: AstroTime): AstroApsis; cdecl; external LibraryName;
+
+ // Finds the next lunar perigee or apogee event in a series.
+ function Astronomy_NextLunarApsis(Apsis: AstroApsis): AstroApsis; cdecl; external LibraryName;
+
+ // Finds the date and time of a planet's perihelion (closest approach to the Sun) or aphelion (farthest distance from the Sun) after a given time.
+ function Astronomy_SearchPlanetApsis(Body: AstroBody; StartTime: AstroTime): AstroApsis; cdecl; external LibraryName;
+
+ // Finds the next planetary perihelion or aphelion event in a series.
+ function Astronomy_NextPlanetApsis(Body: AstroBody; Apsis: AstroApsis): AstroApsis; cdecl; external LibraryName;
+
+ // Creates an identity rotation matrix.
+ function Astronomy_IdentityMatrix(): AstroRotation; cdecl; external LibraryName;
+
+ // Calculatues the inverse of a rotation matrix.
+ function Astronomy_InverseRotation(Rotation: AstroRotation): AstroRotation; cdecl; external LibraryName;
+
+ // Creates a rotation based on applying one rotation followed by another.
+ function Astronomy_CombineRotation(A: AstroRotation; B: AstroRotation): AstroRotation; cdecl; external LibraryName;
+
+ // Re-orients a rotation matrix by pivoting it by an angle around one of its axes.
+ function Astronomy_Pivot(Rotation: AstroRotation; Axis: Int32; Angle: Double): AstroRotation; cdecl; external LibraryName;
+
+ // Converts spherical coordinates to Cartesian coordinates.
+ function Astronomy_VectorFromSphere(Sphere: AstroSpherical; Time: AstroTime): AstroVector; cdecl; external LibraryName;
+
+ // Converts Cartesian coordinates to spherical coordinates.
+ function Astronomy_SphereFromVector(Vector: AstroVector): AstroSpherical; cdecl; external LibraryName;
+
+ // Given an equatorial vector, calculates equatorial angular coordinates.
+ function Astronomy_EquatorFromVector(Vector: AstroVector): AstroEquatorial; cdecl; external LibraryName;
+
+ // Given apparent angular horizontal coordinates in `sphere`, calculates horizontal vector.
+ function Astronomy_VectorFromHorizon(Sphere: AstroSpherical; Time: AstroTime; Refraction: AstroRefraction): AstroVector; cdecl; external LibraryName;
+
+ // Converts Cartesian coordinates to horizontal coordinates.
+ function Astronomy_HorizonFromVector(Vector: AstroVector; Refraction: AstroRefraction): AstroSpherical; cdecl; external LibraryName;
+
+ // Applies a rotation to a vector, yielding a rotated vector.
+ function Astronomy_RotateVector(Rotation: AstroRotation; Vector: AstroVector): AstroVector; cdecl; external LibraryName;
+
+ // Applies a rotation to a state vector, yielding a rotated vector.
+ function Astronomy_RotateState(Rotation: AstroRotation; State: AstroStateVector): AstroStateVector; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from equatorial of-date (EQD) to J2000 mean equator (EQJ).
+ function Astronomy_Rotation_EQD_EQJ(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from equatorial of-date (EQD) to J2000 mean ecliptic (ECL).
+ function Astronomy_Rotation_EQD_ECL(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Returns a rotation matrix from equator of date (EQD) to true ecliptic of date (ECT).
+ function Astronomy_Rotation_EQD_ECT(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from equatorial of-date (EQD) to horizontal (HOR).
+ function Astronomy_Rotation_EQD_HOR(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean equator (EQJ) to equatorial of-date (EQD).
+ function Astronomy_Rotation_EQJ_EQD(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean equator (EQJ) to true ecliptic of date (ECT).
+ function Astronomy_Rotation_EQJ_ECT(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean equator (EQJ) to J2000 mean ecliptic (ECL).
+ function Astronomy_Rotation_EQJ_ECL(): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean equator (EQJ) to horizontal (HOR).
+ function Astronomy_Rotation_EQJ_HOR(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean ecliptic (ECL) to equatorial of-date (EQD).
+ function Astronomy_Rotation_ECL_EQD(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean ecliptic (ECL) to J2000 mean equator (EQJ).
+ function Astronomy_Rotation_ECL_EQJ(): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from J2000 mean ecliptic (ECL) to horizontal (HOR).
+ function Astronomy_Rotation_ECL_HOR(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates a rotation matrix from true ecliptic of date (ECT) to J2000 mean equator (EQJ).
+ function Astronomy_Rotation_ECT_EQJ(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calulcates a rotation matrix from true ecliptic of date (ECT) to equator of date (EQD).
+ function Astronomy_Rotation_ECT_EQD(Time: PAstroTime): AstroRotation; cdecl; external LibraryName;
+
+ // Calulcates a rotation matrix from horizontal (HOR) to equatorial of-date (EQD).
+ function Astronomy_Rotation_HOR_EQD(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName;
+
+ // Calulcates a rotation matrix from horizontal (HOR) to J2000 equatorial (EQJ).
+ function Astronomy_Rotation_HOR_EQJ(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName;
+
+ // Calulcates a rotation matrix from horizontal (HOR) to J2000 mean ecliptic (ECL).
+ function Astronomy_Rotation_HOR_ECL(Time: PAstroTime; Observer: AstroObserver): AstroRotation; cdecl; external LibraryName;
+
+ // Calulcates a rotation matrix from J2000 mean ecliptic (EQJ) to galactic (GAL).
+ function Astronomy_Rotation_EQJ_GAL(): AstroRotation; cdecl; external LibraryName;
+
+ // Calulcates a rotation matrix from galactic (GAL) to J2000 mean ecliptic (EQJ).
+ function Astronomy_Rotation_GAL_EQJ(): AstroRotation; cdecl; external LibraryName;
+
+ // Calculates the amount of "lift" to an altitude angle caused by atmospheric refraction.
+ function Astronomy_Refraction(Refraction: AstroRefraction; Altitude: Double): Double; cdecl; external LibraryName;
+
+ // Calculates the inverse of an atmospheric refraction angle.
+ function Astronomy_InverseRefraction(Refraction: AstroRefraction; BentAltitude: Double): Double; cdecl; external LibraryName;
+
+ // Determines the constellation that contains the given point in the sky.
+ function Astronomy_Constellation(RA: Double; Dec: Double): AstroConstellation; cdecl; external LibraryName;
+
+{ Allocate and initialize a gravity step simulator.
+ Prepares to simulate a series of incremental time steps,
+ simulating the movement of zero or more small bodies through the Solar System
+ acting under gravitational attraction from the Sun and planets. }
+ function Astronomy_GravSimInit(SimOut: PAstroGravSim; OriginBody: AstroBody; Time: AstroTime; NumBodies: Int32; BodyStateArray: PAstroStateVector): AstroStatus; cdecl; external LibraryName;
+
+ // Advances a gravity simulation by a small time step.
+ function Astronomy_GravSimUpdate(Sim: PAstroGravSim; Time: AstroTime; NumBodies: Int32; BodyStateArray: PAstroStateVector): AstroStatus; cdecl; external LibraryName;
+
+ // Get the position and velocity of a Solar System body included in the simulation.
+ function Astronomy_GravSimBodyState(Sim: PAstroGravSim; Body: AstroBody): AstroStateVector; cdecl; external LibraryName;
+
+ // Returns the time of the current simulation step.
+ function Astronomy_GravSimTime(Sim: PAstroGravSim): AstroTime; cdecl; external LibraryName;
+
+ // Returns the number of small bodies represented in this simulation.
+ function Astronomy_GravSimNumBodies(Sim: PAstroGravSim): Int32; cdecl; external LibraryName;
+
+ // Returns the body whose center is the coordinate origin that small bodies are referenced to.
+ function Astronomy_GravSimOrigin(Sim: PAstroGravSim): AstroBody; cdecl; external LibraryName;
+
+ // Exchange the current time step with the previous time step.
+ procedure Astronomy_GravSimSwap(Sim: PAstroGravSim); cdecl; external LibraryName;
+
+ // Releases memory allocated to a gravity simulator object.
+ procedure Astronomy_GravSimFree(Sim: PAstroGravSim); cdecl; external LibraryName;
+
+ // Solve for light travel time of a vector function.
+ function Astronomy_CorrectLightTravel(Context: Pointer; Func: PAstroPositionFunc; Time: AstroTime): AstroVector; cdecl; external LibraryName;
+
+ // Solve for light travel time correction of apparent position.
+ function Astronomy_BackdatePosition(Time: AstroTime; ObserverBody: AstroBody; TargetBody: AstroBody; Aberration: AstroAberration): AstroVector; cdecl; external LibraryName;
+
+ // Assign equatorial coordinates to a user-defined star.
+ function Astronomy_DefineStar(Body: AstroBody; RA: Double; Dec: Double; DistanceLightYears: Double): AstroStatus; cdecl; external LibraryName;
+
+implementation
+
+end.
+
diff --git a/source/pascal/README.md b/source/pascal/README.md
new file mode 100644
index 00000000..67547c6e
--- /dev/null
+++ b/source/pascal/README.md
@@ -0,0 +1,15 @@
+# Astronomy Engine for FreePascal language
+This is the programming reference for the [FreePascal](https://www.freepascal.org/) version of Astronomy Engine. It can be used directly from FreePascal (and probably also Delphi) programs. Other programming languages are supported. See the [home page](https://github.com/cosinekitty/astronomy) for more info.
+
+---
+
+## Quick Start
+To include Astronomy Engine in your own FreePascal program, all you need is the
+file `Astronomy.pas` from this directory.
+
+To get started quickly, here are some [examples](../../demo/pascal/).
+
+## Pascal developer note
+The `Astronomy.pas` Pascal unit (module) is a [wrapper library](https://en.wikipedia.org/wiki/Wrapper_library) that bridges the C and Pascal programming languages so that the Astronomy Engine C/C++ library can be used in the Pascal language. The C library binary (`Astronomy.dll` on Windows) is also required to use this Pascal module. This means one needs to put the binary file in the same directory where the Pascal program executable is located.
+
+To build Astronomy Engine C/C++ library (for Windows) check the [documentation](../c/README.Windows.md).