From 6510c9f3b47525b2518e3e4769529a1ecb601835 Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 22 Aug 1997 21:34:32 +0000 Subject: [PATCH] Doing a bit of reorganizing and house cleaning. --- Main/GLUTkey.c | 35 ++++++---- Main/GLUTmain.c | 152 +++++++++++------------------------------- Main/Makefile | 5 +- Main/depend | 18 +++-- Scenery/scenery.c | 23 +++++-- Simulator/constants.h | 19 +++++- Simulator/make.inc | 13 ++-- Time/sunpos.c | 9 ++- Weather/weather.c | 24 +++++-- Weather/weather.h | 15 ++++- 10 files changed, 158 insertions(+), 155 deletions(-) diff --git a/Main/GLUTkey.c b/Main/GLUTkey.c index 75701b835..3eeebd737 100644 --- a/Main/GLUTkey.c +++ b/Main/GLUTkey.c @@ -33,17 +33,21 @@ #include #include "GLUTkey.h" -#include "../Aircraft/aircraft.h" + #include "../constants.h" -extern double fogDensity; +#include "../Aircraft/aircraft.h" +#include "../Weather/weather.h" + extern double goal_view_offset; /* Handle keyboard events */ void GLUTkey(unsigned char k, int x, int y) { struct control_params *c; + struct weather_params *w; c = ¤t_aircraft.controls; + w = ¤t_weather; printf("Key hit = %d", k); @@ -74,6 +78,11 @@ void GLUTkey(unsigned char k, int x, int y) { case 57: /* numeric keypad 9 */ goal_view_offset = FG_PI * 1.75; return; + case 90: /* Z */ + w->visibility /= 1.10; + glFogf(GL_FOG_END, w->visibility); + printf("Fog density = %.4f\n", w->visibility); + return; } } else { printf("\n"); @@ -113,15 +122,10 @@ void GLUTkey(unsigned char k, int x, int y) { case 51: /* numeric keypad 3 (Pg Dn) */ fgThrottleMove(0, -0.01); return; - case 122: - fogDensity *= 1.10; - glFogf(GL_FOG_END, fogDensity); - printf("Fog density = %.4f\n", fogDensity); - return; - case 90: - fogDensity /= 1.10; - glFogf(GL_FOG_END, fogDensity); - printf("Fog density = %.4f\n", fogDensity); + case 122: /* z */ + w->visibility *= 1.10; + glFogf(GL_FOG_END, w->visibility); + printf("Fog density = %.4f\n", w->visibility); return; case 27: /* ESC */ exit(0); @@ -211,10 +215,13 @@ void GLUTspecialkey(int k, int x, int y) { /* $Log$ -/* Revision 1.17 1997/07/19 22:34:02 curt -/* Moved PI definitions to ../constants.h -/* Moved random() stuff to ../Utils/ and renamed fg_random() +/* Revision 1.18 1997/08/22 21:34:38 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.17 1997/07/19 22:34:02 curt + * Moved PI definitions to ../constants.h + * Moved random() stuff to ../Utils/ and renamed fg_random() + * * Revision 1.16 1997/07/18 23:41:24 curt * Tweaks for building with Cygnus Win32 compiler. * diff --git a/Main/GLUTmain.c b/Main/GLUTmain.c index 731fb15ae..6d88360ce 100644 --- a/Main/GLUTmain.c +++ b/Main/GLUTmain.c @@ -1,5 +1,5 @@ /************************************************************************** - * GLmain.c -- top level sim routines + * GLUTmain.c -- top level sim routines * * Written by Curtis Olson for OpenGL, started May 1997. * @@ -35,15 +35,17 @@ #include "GLUTkey.h" #endif +#include "fg_init.h" + #include "../constants.h" +#include "../general.h" #include "../Aircraft/aircraft.h" -#include "../Scenery/mesh.h" -#include "../Scenery/scenery.h" #include "../Math/fg_geodesy.h" -#include "../Math/fg_random.h" #include "../Math/mat3.h" #include "../Math/polar.h" +#include "../Scenery/mesh.h" +#include "../Scenery/scenery.h" #include "../Time/fg_time.h" #include "../Time/fg_timer.h" #include "../Time/sunpos.h" @@ -54,6 +56,12 @@ being operated */ struct aircraft_params current_aircraft; +/* This is a record containing global housekeeping information */ +struct general_params general; + +/* This is a record containing current weather info */ +struct weather_params current_weather; + /* view parameters */ static GLfloat win_ratio = 1.0; @@ -76,15 +84,9 @@ static GLfloat fgFogColor[4] = {0.65, 0.65, 0.85, 1.0}; /* static GLint scenery, runway; */ /* Another hack */ -double fogDensity = 60000.0; /* in meters */ double view_offset = 0.0; double goal_view_offset = 0.0; -/* Another hack */ -#define DEFAULT_TIMER_HZ 20 -#define DEFAULT_MULTILOOP 6 -#define DEFAULT_MODEL_HZ (DEFAULT_TIMER_HZ * DEFAULT_MULTILOOP) - double Simtime; /* Another hack */ @@ -96,6 +98,10 @@ int use_signals = 0; **************************************************************************/ static void fgInitVisuals() { + struct weather_params *w; + + w = ¤t_weather; + glEnable( GL_DEPTH_TEST ); /* glFrontFace(GL_CW); */ glEnable( GL_CULL_FACE ); @@ -113,9 +119,9 @@ static void fgInitVisuals() { glEnable( GL_FOG ); glFogi (GL_FOG_MODE, GL_LINEAR); /* glFogf (GL_FOG_START, 1.0); */ - glFogf (GL_FOG_END, fogDensity); + glFogf (GL_FOG_END, w->visibility); glFogfv (GL_FOG_COLOR, fgFogColor); - /* glFogf (GL_FOG_DENSITY, fogDensity); */ + /* glFogf (GL_FOG_DENSITY, w->visibility); */ /* glHint (GL_FOG_HINT, GL_FASTEST); */ glClearColor(fgClearColor[0], fgClearColor[1], fgClearColor[2], @@ -467,7 +473,7 @@ void fgInitTimeDepCalcs() { static void fgMainLoop( void ) { static int remainder = 0; int elapsed, multi_loop; - double rough_elev; + double cur_elev; struct flight_params *f; f = ¤t_aircraft.flight; @@ -493,18 +499,18 @@ static void fgMainLoop( void ) { /* I'm just sticking this here for now, it should probably move * eventually */ - rough_elev = mesh_altitude(FG_Longitude * RAD_TO_ARCSEC, + cur_elev = mesh_altitude(FG_Longitude * RAD_TO_ARCSEC, FG_Latitude * RAD_TO_ARCSEC); - printf("Ground elevation is %.2f meters here.\n", rough_elev); - /* FG_Runway_altitude = rough_elev * METER_TO_FEET; */ + printf("Ground elevation is %.2f meters here.\n", cur_elev); + /* FG_Runway_altitude = cur_elev * METER_TO_FEET; */ - if ( FG_Altitude * FEET_TO_METER < rough_elev + 3.758099) { + if ( FG_Altitude * FEET_TO_METER < cur_elev + 3.758099) { /* set this here, otherwise if we set runway height above our current height we get a really nasty bounce. */ FG_Runway_altitude = FG_Altitude - 3.758099; /* now set aircraft altitude above ground */ - FG_Altitude = rough_elev * METER_TO_FEET + 3.758099; + FG_Altitude = cur_elev * METER_TO_FEET + 3.758099; printf("<*> resetting altitude to %.0f meters\n", FG_Altitude * FEET_TO_METER); } @@ -542,12 +548,10 @@ static void fgReshape( int width, int height ) { int main( int argc, char *argv[] ) { struct flight_params *f; - double rough_elev; f = ¤t_aircraft.flight; - printf("Flight Gear: prototype code to test OpenGL, LaRCsim, and VRML\n\n"); - + printf("Flight Gear: prototype version %s\n\n", VERSION); /********************************************************************** * Initialize the Window/Graphics environment. @@ -567,106 +571,25 @@ int main( int argc, char *argv[] ) { glutCreateWindow("Flight Gear"); #endif - /* seed the random number generater */ - fg_srandom(); + /* This is the general house keeping init routine */ + fgInitGeneral(); + + /* This is the top level init routine which calls all the other + * subsystem initialization routines. If you are adding a + * subsystem to flight gear, its initialization call should + * located in this routine.*/ + fgInitSubsystems(); /* setup view parameters, only makes GL calls */ fgInitVisuals(); - - /**************************************************************** - * The following section sets up the flight model EOM parameters and - * should really be read in from one or more files. - ****************************************************************/ - - /* Globe Aiport, AZ */ - FG_Runway_altitude = 3234.5; - FG_Runway_latitude = 120070.41; - FG_Runway_longitude = -398391.28; - FG_Runway_heading = 102.0 * DEG_TO_RAD; - - /* Initial Position at GLOBE airport */ - FG_Latitude = ( 120070.41 / 3600.0 ) * DEG_TO_RAD; - FG_Longitude = ( -398391.28 / 3600.0 ) * DEG_TO_RAD; - FG_Altitude = FG_Runway_altitude + 3.758099; - - /* Initial Position north of the city of Globe */ - /* FG_Latitude = ( 120625.64 / 3600.0 ) * DEG_TO_RAD; */ - /* FG_Longitude = ( -398673.28 / 3600.0 ) * DEG_TO_RAD; */ - /* FG_Altitude = 0.0 + 3.758099; */ - - printf("Initial position is: (%.4f, %.4f, %.2f)\n", FG_Latitude, - FG_Longitude, FG_Altitude); - - /* Initial Velocity */ - FG_V_north = 0.0 /* 7.287719E+00 */; - FG_V_east = 0.0 /* 1.521770E+03 */; - FG_V_down = 0.0 /* -1.265722E-05 */; - - /* Initial Orientation */ - FG_Phi = -2.658474E-06; - FG_Theta = 7.401790E-03; - FG_Psi = 270.0 * DEG_TO_RAD; - /* FG_Psi = 0.0 * DEG_TO_RAD; */ - - /* Initial Angular B rates */ - FG_P_body = 7.206685E-05; - FG_Q_body = 0.000000E+00; - FG_R_body = 9.492658E-05; - - FG_Earth_position_angle = 0.000000E+00; - - /* Mass properties and geometry values */ - FG_Mass = 8.547270E+01; - FG_I_xx = 1.048000E+03; - FG_I_yy = 3.000000E+03; - FG_I_zz = 3.530000E+03; - FG_I_xz = 0.000000E+00; - - /* CG position w.r.t. ref. point */ - FG_Dx_cg = 0.000000E+00; - FG_Dy_cg = 0.000000E+00; - FG_Dz_cg = 0.000000E+00; - - /* Set initial position and slew parameters */ - /* fgSlewInit(-398391.3, 120070.41, 244, 3.1415); */ /* GLOBE Airport */ - /* fgSlewInit(-335340,162540, 15, 4.38); */ - /* fgSlewInit(-398673.28,120625.64, 53, 4.38); */ - - /* Initialize the Scenery Management system */ - fgSceneryInit(); - - /* Tell the Scenery Management system where we are so it can load - * the correct scenery data */ - fgSceneryUpdate(FG_Latitude, FG_Longitude, FG_Altitude); - - /* I'm just sticking this here for now, it should probably move - * eventually */ - rough_elev = mesh_altitude(FG_Longitude * RAD_TO_DEG * 3600.0, - FG_Latitude * RAD_TO_DEG * 3600.0); - printf("Ground elevation is %.2f meters here.\n", rough_elev); - if ( rough_elev > -9990.0 ) { - FG_Runway_altitude = rough_elev * METER_TO_FEET; - } - - if ( FG_Altitude < FG_Runway_altitude ) { - FG_Altitude = FG_Runway_altitude + 3.758099; - } - /* end of thing that I just stuck in that I should probably move */ - - /* Initialize the flight model data structures base on above values */ - fgFlightModelInit( FG_LARCSIM, f, 1.0 / DEFAULT_MODEL_HZ ); - if ( use_signals ) { /* init timer routines, signals, etc. Arrange for an alarm signal to be generated, etc. */ fgInitTimeDepCalcs(); } - /* Initialize the weather modeling subsystem */ - fgWeatherInit(); - - /********************************************************************** + /********************************************************************** * Initialize the Event Handlers. **********************************************************************/ @@ -700,9 +623,12 @@ int main( int argc, char *argv[] ) { /* $Log$ -/* Revision 1.8 1997/08/19 23:55:03 curt -/* Worked on better simulating real lighting. +/* Revision 1.9 1997/08/22 21:34:39 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.8 1997/08/19 23:55:03 curt + * Worked on better simulating real lighting. + * * Revision 1.7 1997/08/16 12:22:38 curt * Working on improving the lighting/shading. * diff --git a/Main/Makefile b/Main/Makefile index 8c8dca03b..40c101efd 100644 --- a/Main/Makefile +++ b/Main/Makefile @@ -26,7 +26,7 @@ TARGET=fg0 -CFILES = GLUTmain.c $(INTERFACE_FILES) +CFILES = fg_init.c $(INTERFACE_FILES) OFILES = $(CFILES:.c=.o) AFILES = ../Aircraft/libAircraft.a ../Controls/libControls.a \ ../Flight/libFlight.a ../Flight/LaRCsim/libLaRCsim.a \ @@ -72,6 +72,9 @@ GLTKkey.o: #--------------------------------------------------------------------------- # $Log$ +# Revision 1.30 1997/08/22 21:34:40 curt +# Doing a bit of reorganizing and house cleaning. +# # Revision 1.29 1997/08/04 20:25:15 curt # Organizational tweaking. # diff --git a/Main/depend b/Main/depend index a1057afaf..b7e213b2f 100644 --- a/Main/depend +++ b/Main/depend @@ -4,13 +4,21 @@ GLUTkey.o: GLUTkey.c GLUTkey.h ../Aircraft/aircraft.h \ ../Aircraft/../Flight/LaRCsim/../flight.h \ ../Aircraft/../Controls/controls.h \ ../Aircraft/../Controls/../limits.h ../constants.h -GLUTmain.o: GLUTmain.c ../constants.h ../Aircraft/aircraft.h \ - ../Aircraft/../Flight/flight.h ../Aircraft/../Flight/Slew/slew.h \ +GLUTmain.o: GLUTmain.c fg_init.h ../constants.h ../general.h \ + ../Aircraft/aircraft.h ../Aircraft/../Flight/flight.h \ + ../Aircraft/../Flight/Slew/slew.h \ ../Aircraft/../Flight/LaRCsim/ls_interface.h \ ../Aircraft/../Flight/LaRCsim/../flight.h \ ../Aircraft/../Controls/controls.h \ ../Aircraft/../Controls/../limits.h ../Scenery/mesh.h \ ../Scenery/scenery.h ../Scenery/../types.h ../Math/fg_geodesy.h \ - ../Math/fg_random.h ../Math/mat3.h ../Math/polar.h ../Math/../types.h \ - ../Time/fg_time.h ../Time/../types.h ../Time/fg_timer.h \ - ../Time/sunpos.h ../Weather/weather.h + ../Math/mat3.h ../Math/polar.h ../Math/../types.h ../Time/fg_time.h \ + ../Time/../types.h ../Time/fg_timer.h ../Time/sunpos.h \ + ../Weather/weather.h +fg_init.o: fg_init.c fg_init.h ../constants.h ../general.h \ + ../Aircraft/aircraft.h ../Aircraft/../Flight/flight.h \ + ../Aircraft/../Flight/Slew/slew.h \ + ../Aircraft/../Flight/LaRCsim/ls_interface.h \ + ../Aircraft/../Flight/LaRCsim/../flight.h \ + ../Aircraft/../Controls/controls.h \ + ../Aircraft/../Controls/../limits.h ../Math/fg_random.h diff --git a/Scenery/scenery.c b/Scenery/scenery.c index f1b745bc6..eb8dd0c9f 100644 --- a/Scenery/scenery.c +++ b/Scenery/scenery.c @@ -29,6 +29,9 @@ #endif #include +#include + +#include "../general.h" #include "scenery.h" #include "parsevrml.h" @@ -45,18 +48,27 @@ struct scenery_params scenery; /* Initialize the Scenery Management system */ void fgSceneryInit() { /* set the default terrain detail level */ - scenery.terrain_skip = 5; + scenery.terrain_skip = 10; } /* Tell the scenery manager where we are so it can load the proper data, and * build the proper structures. */ void fgSceneryUpdate(double lon, double lat, double elev) { + struct general_params *g; + char path[1024]; + + g = &general; + /* a hardcoded hack follows */ /* this routine should parse the file, and make calls back to the * scenery management system to build the appropriate structures */ - fgParseVRML("mesa-e.wrl"); + path[0] = '\0'; + strcat(path, g->root_dir); + strcat(path, "/Scenery/"); + strcat(path, "mesa-e.wrl"); + fgParseVRML(path); } @@ -69,9 +81,12 @@ void fgSceneryRender() { /* $Log$ -/* Revision 1.12 1997/08/19 23:55:08 curt -/* Worked on better simulating real lighting. +/* Revision 1.13 1997/08/22 21:34:41 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.12 1997/08/19 23:55:08 curt + * Worked on better simulating real lighting. + * * Revision 1.11 1997/08/13 20:24:22 curt * Changed default detail level. * diff --git a/Simulator/constants.h b/Simulator/constants.h index 0bd37ad99..625217378 100644 --- a/Simulator/constants.h +++ b/Simulator/constants.h @@ -31,6 +31,12 @@ #include +/* This should be defined in the toplevel make.inc */ +#ifndef VERSION +#define VERSION "\"not defined\"" +#endif + + /* Make sure PI is defined in its various forms */ #ifdef M_PI # define FG_PI M_PI @@ -99,13 +105,22 @@ #define EPSILON 0.000001 +/* Timing constants for Flight Model updates */ +#define DEFAULT_TIMER_HZ 20 +#define DEFAULT_MULTILOOP 6 +#define DEFAULT_MODEL_HZ (DEFAULT_TIMER_HZ * DEFAULT_MULTILOOP) + + #endif /* CONSTANTS_H */ /* $Log$ -/* Revision 1.8 1997/07/31 22:52:22 curt -/* Working on redoing internal coordinate systems & scenery transformations. +/* Revision 1.9 1997/08/22 21:34:32 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.8 1997/07/31 22:52:22 curt + * Working on redoing internal coordinate systems & scenery transformations. + * * Revision 1.7 1997/07/23 21:52:10 curt * Put comments around the text after an #endif for increased portability. * diff --git a/Simulator/make.inc b/Simulator/make.inc index 12d4196a1..e5f008146 100644 --- a/Simulator/make.inc +++ b/Simulator/make.inc @@ -25,7 +25,7 @@ #--------------------------------------------------------------------------- -VERSION = 0.08 +VERSION = 0.09 #--------------------------------------------------------------------------- # Choose your weapons @@ -52,7 +52,7 @@ RANLIB = ranlib # #--------------------------------------------------------------------------- -GLOBAL_CFLAGS = -g -Wall +GLOBAL_CFLAGS = -g -Wall -DVERSION=\"$(VERSION)\" #--------------------------------------------------------------------------- @@ -90,7 +90,7 @@ GLOBAL_CFLAGS = -g -Wall # # INTERFACE_FLAGS = -DGLUT # INTERFACE_LIBS = -lglut -# INTERFACE_FILES = GLUTkey.c +# INTERFACE_FILES = GLUTmain.c GLUTkey.c # GRAPHICS_LIBS = -lGLU -lGL -lXmu -lX11 # FG_CFLAGS = $(GLOBAL_CFLAGS) #--------------------------------------------------------------------------- @@ -100,7 +100,7 @@ GLOBAL_CFLAGS = -g -Wall # INTERFACE_FLAGS = -DGLUT INTERFACE_LIBS = -lglut -INTERFACE_FILES = GLUTkey.c +INTERFACE_FILES = GLUTmain.c GLUTkey.c MESA_LIBS = -L/usr/lib/mesa -lMesatk -lMesaaux -lMesaGLU -lMesaGL X11_LIBS = -L/usr/X11R6/lib -lXext -lXmu -lXi -lX11 GRAPHICS_LIBS = $(MESA_LIBS) $(X11_LIBS) @@ -112,7 +112,7 @@ FG_CFLAGS = $(GLOBAL_CFLAGS) # # INTERFACE_FLAGS = -DGLUT # INTERFACE_LIBS = ../Win32/libglut.a -# INTERFACE_FILES = GLUTkey.c +# INTERFACE_FILES = GLUTmain.c GLUTkey.c # GRAPHICS_LIBS = -lglu32 -lopengl32 -luser32 -lgdi32 # FG_CFLAGS = $(GLOBAL_CFLAGS) -DWIN32 -DUSE_RAND #--------------------------------------------------------------------------- @@ -120,6 +120,9 @@ FG_CFLAGS = $(GLOBAL_CFLAGS) #--------------------------------------------------------------------------- # $Log$ +# Revision 1.11 1997/08/22 21:34:33 curt +# Doing a bit of reorganizing and house cleaning. +# # Revision 1.10 1997/08/16 12:22:19 curt # Tweaks for new version. # diff --git a/Time/sunpos.c b/Time/sunpos.c index 1c1bf77df..9965f0797 100644 --- a/Time/sunpos.c +++ b/Time/sunpos.c @@ -265,7 +265,7 @@ void fgUpdateSunPos() { t = &cur_time_params; - time_warp += 300; /* increase this to make the world spin real fast */ + time_warp += 200; /* increase this to make the world spin real fast */ fgSunPosition(time(NULL) + time_warp, &t->sun_lon, &sun_gd_lat); @@ -276,9 +276,12 @@ void fgUpdateSunPos() { /* $Log$ -/* Revision 1.4 1997/08/19 23:55:09 curt -/* Worked on better simulating real lighting. +/* Revision 1.5 1997/08/22 21:34:41 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.4 1997/08/19 23:55:09 curt + * Worked on better simulating real lighting. + * * Revision 1.3 1997/08/13 20:23:49 curt * The interface to sunpos now updates a global structure rather than returning * current sun position. diff --git a/Weather/weather.c b/Weather/weather.c index e7ce4d217..f3070b252 100644 --- a/Weather/weather.c +++ b/Weather/weather.c @@ -31,27 +31,39 @@ /* Initialize the weather modeling subsystem */ void fgWeatherInit(void) { + struct weather_params *w; + + w = ¤t_weather; + + /* Configure some wind */ + /* FG_V_north_airmass = 15; */ /* ft/s =~ 10mph */ + + w->visibility = 60000.0; /* meters = 60km */ } + /* Update the weather parameters for the current position */ void fgWeatherUpdate(double lon, double lat, double alt) { struct flight_params *f; - f = ¤t_aircraft.flight; + struct weather_params *w; - /* Configure some wind */ - /* FG_V_north_airmass = 15; */ /* ft/s =~ 10mph */ + f = ¤t_aircraft.flight; + w = ¤t_weather; /* Add some random turbulence */ /* FG_U_gust = fg_random() * 1.0 - 0.5; FG_V_gust = fg_random() * 1.0 - 0.5; FG_W_gust = fg_random() * 1.0 - 0.5; */ - } + /* $Log$ -/* Revision 1.4 1997/08/02 16:23:55 curt -/* Misc. tweaks. +/* Revision 1.5 1997/08/22 21:34:42 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.4 1997/08/02 16:23:55 curt + * Misc. tweaks. + * * Revision 1.3 1997/07/31 22:52:41 curt * Working on redoing internal coordinate systems & scenery transformations. * diff --git a/Weather/weather.h b/Weather/weather.h index d92b909ab..7e93f60a9 100644 --- a/Weather/weather.h +++ b/Weather/weather.h @@ -28,6 +28,14 @@ #define WEATHER_H +/* holds the current weather values */ +struct weather_params { + float visibility; +}; + +extern struct weather_params current_weather; + + /* Initialize the weather modeling subsystem */ void fgWeatherInit(void); @@ -39,9 +47,12 @@ void fgWeatherUpdate(double lon, double lat, double alt); /* $Log$ -/* Revision 1.2 1997/07/23 21:52:30 curt -/* Put comments around the text after an #endif for increased portability. +/* Revision 1.3 1997/08/22 21:34:43 curt +/* Doing a bit of reorganizing and house cleaning. /* + * Revision 1.2 1997/07/23 21:52:30 curt + * Put comments around the text after an #endif for increased portability. + * * Revision 1.1 1997/07/19 23:03:58 curt * Initial revision. * -- 2.39.2