@@ -81,6 +81,8 @@ static Texture2D satIcon, markerIcon, earthTexture, moonTexture, cloudTexture, e
8181static Texture2D periMark , apoMark ;
8282static Model earthModel , moonModel , cloudModel ;
8383
84+
85+
8486// safely modifies the alpha channel without relying on raylib's Fade()
8587static Color ApplyAlpha (Color c , float alpha ) {
8688 if (alpha < 0.0f ) alpha = 0.0f ;
@@ -183,18 +185,88 @@ static void DrawUIText(const char* text, float x, float y, float size, Color col
183185
184186typedef enum { LOCK_NONE , LOCK_EARTH , LOCK_MOON } TargetLock ;
185187
188+
189+ static void DrawLoadingScreen (float progress , const char * message ) {
190+ BeginDrawing ();
191+ ClearBackground (cfg .bg_color );
192+
193+ int screenW = GetScreenWidth ();
194+ int screenH = GetScreenHeight ();
195+ float barW = 400 * cfg .ui_scale ;
196+ float barH = 30 * cfg .ui_scale ;
197+
198+ Rectangle barOutline = { (screenW - barW )/2 , (screenH - barH )/2 , barW , barH };
199+ Rectangle barProgress = { barOutline .x + 5 , barOutline .y + 5 , (barW - 10 ) * progress , barH - 10 };
200+
201+ DrawRectangleLinesEx (barOutline , 2 , cfg .text_main );
202+ DrawRectangleRec (barProgress , cfg .text_secondary );
203+
204+ Vector2 msgSize = MeasureTextEx (customFont , message , 20 * cfg .ui_scale , 1.0f );
205+ DrawUIText (message , (screenW - msgSize .x )/2 , barOutline .y - 40 * cfg .ui_scale , 20 * cfg .ui_scale , cfg .text_main );
206+
207+ EndDrawing ();
208+ }
209+
186210int main (void ) {
211+ /*
212+ -----------------------------------------------------------------------------
213+ INITIALIZATION AND LOADING SEQUENCE HERE
214+ loading crap into VRAM is slow so here we show a lil loading screen~
215+ -----------------------------------------------------------------------------
216+ */
187217 LoadAppConfig ("settings.json" , & cfg );
188218
189219 SetConfigFlags (FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE );
190- InitWindow (cfg .window_width , cfg .window_height , "TLEScope 3.1 " );
191-
192- // load our font and icons
193- customFont = LoadFontEx ("resources/font.ttf" , 64 , 0 , 0 );
194- GenTextureMipmaps (& customFont .texture );
220+ InitWindow (cfg .window_width , cfg .window_height , "TLEScope 3.3 " );
221+
222+ // Load font first so we can use it for the loading text
223+ customFont = LoadFontEx ("resources/font.ttf" , 64 , 0 , 0 );
224+ GenTextureMipmaps (& customFont .texture );
195225 SetTextureFilter (customFont .texture , TEXTURE_FILTER_BILINEAR );
196- GuiSetFont (customFont ); // Ensure raygui uses the custom font
226+ GuiSetFont (customFont );
197227
228+ DrawLoadingScreen (0.1f , "Fetching TLE Data..." );
229+ load_tle_data ("resources/data.tle" );
230+
231+ DrawLoadingScreen (0.25f , "Initializing Textures..." );
232+ earthTexture = LoadTexture ("resources/earth.png" );
233+ earthNightTexture = LoadTexture ("resources/earth_night.png" );
234+
235+ DrawLoadingScreen (0.4f , "Compiling Shaders..." );
236+ Shader shader3D = LoadShaderFromMemory (NULL , fs3D );
237+ int sunDirLoc3D = GetShaderLocation (shader3D , "sunDir" );
238+ shader3D .locs [SHADER_LOC_MAP_EMISSION ] = GetShaderLocation (shader3D , "texture1" );
239+
240+ Shader shader2D = LoadShaderFromMemory (NULL , fs2D );
241+ int sunDirLoc2D = GetShaderLocation (shader2D , "sunDir" );
242+ int nightTexLoc2D = GetShaderLocation (shader2D , "texture1" );
243+
244+ Shader shaderCloud = LoadShaderFromMemory (NULL , fsCloud3D );
245+ int sunDirLocCloud = GetShaderLocation (shaderCloud , "sunDir" );
246+
247+ DrawLoadingScreen (0.6f , "Generating Meshes..." );
248+ float draw_earth_radius = EARTH_RADIUS_KM / DRAW_SCALE ;
249+ Mesh sphereMesh = GenEarthMesh (draw_earth_radius , 64 , 64 );
250+ earthModel = LoadModelFromMesh (sphereMesh );
251+ earthModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = earthTexture ;
252+ earthModel .materials [0 ].maps [MATERIAL_MAP_EMISSION ].texture = earthNightTexture ;
253+ Shader defaultEarthShader = earthModel .materials [0 ].shader ;
254+
255+ DrawLoadingScreen (0.8f , "Loading Celestial Bodies..." );
256+ float draw_cloud_radius = (EARTH_RADIUS_KM + 25.0f ) / DRAW_SCALE ;
257+ Mesh cloudMesh = GenEarthMesh (draw_cloud_radius , 64 , 64 );
258+ cloudModel = LoadModelFromMesh (cloudMesh );
259+ cloudTexture = LoadTexture ("resources/clouds.png" );
260+ cloudModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = cloudTexture ;
261+ Shader defaultCloudShader = cloudModel .materials [0 ].shader ;
262+
263+ float draw_moon_radius = MOON_RADIUS_KM / DRAW_SCALE ;
264+ Mesh moonMesh = GenEarthMesh (draw_moon_radius , 32 , 32 );
265+ moonModel = LoadModelFromMesh (moonMesh );
266+ moonTexture = LoadTexture ("resources/moon.png" );
267+ moonModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = moonTexture ;
268+
269+ DrawLoadingScreen (0.95f , "Finalizing UI..." );
198270 satIcon = LoadTexture ("resources/sat_icon.png" );
199271 markerIcon = LoadTexture ("resources/marker_icon.png" );
200272 periMark = LoadTexture ("resources/smallmark.png" );
@@ -205,7 +277,12 @@ int main(void) {
205277 SetTextureFilter (periMark , TEXTURE_FILTER_BILINEAR );
206278 SetTextureFilter (apoMark , TEXTURE_FILTER_BILINEAR );
207279
208- load_tle_data ("resources/data.tle" );
280+ DrawLoadingScreen (1.0f , "Ready!" );
281+ /*
282+ -----------------------------------------------------------------------------
283+ stuff after loading and initialization, like setting up the cameras and main loop variables
284+ -----------------------------------------------------------------------------
285+ */
209286
210287 // set up the cameras for both views
211288 Camera camera3d = { 0 };
@@ -223,42 +300,6 @@ int main(void) {
223300 float target_camera2d_zoom = camera2d .zoom ;
224301 Vector2 target_camera2d_target = camera2d .target ;
225302
226- float draw_earth_radius = EARTH_RADIUS_KM / DRAW_SCALE ;
227- Mesh sphereMesh = GenEarthMesh (draw_earth_radius , 64 , 64 );
228- earthModel = LoadModelFromMesh (sphereMesh );
229- earthTexture = LoadTexture ("resources/earth.png" );
230- earthModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = earthTexture ;
231- earthNightTexture = LoadTexture ("resources/earth_night.png" );
232-
233- Shader shader3D = LoadShaderFromMemory (NULL , fs3D );
234- int sunDirLoc3D = GetShaderLocation (shader3D , "sunDir" );
235-
236- // link texture1 to raylib's EMISSION material map
237- shader3D .locs [SHADER_LOC_MAP_EMISSION ] = GetShaderLocation (shader3D , "texture1" );
238- earthModel .materials [0 ].maps [MATERIAL_MAP_EMISSION ].texture = earthNightTexture ;
239-
240- Shader defaultEarthShader = earthModel .materials [0 ].shader ; // cache the default shader
241-
242- Shader shader2D = LoadShaderFromMemory (NULL , fs2D );
243- int sunDirLoc2D = GetShaderLocation (shader2D , "sunDir" );
244- int nightTexLoc2D = GetShaderLocation (shader2D , "texture1" );
245-
246- float draw_cloud_radius = (EARTH_RADIUS_KM + 25.0f ) / DRAW_SCALE ;
247- Mesh cloudMesh = GenEarthMesh (draw_cloud_radius , 64 , 64 );
248- cloudModel = LoadModelFromMesh (cloudMesh );
249- cloudTexture = LoadTexture ("resources/clouds.png" );
250- cloudModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = cloudTexture ;
251-
252- Shader shaderCloud = LoadShaderFromMemory (NULL , fsCloud3D );
253- int sunDirLocCloud = GetShaderLocation (shaderCloud , "sunDir" );
254- Shader defaultCloudShader = cloudModel .materials [0 ].shader ;
255-
256- float draw_moon_radius = MOON_RADIUS_KM / DRAW_SCALE ;
257- Mesh moonMesh = GenEarthMesh (draw_moon_radius , 32 , 32 );
258- moonModel = LoadModelFromMesh (moonMesh );
259- moonTexture = LoadTexture ("resources/moon.png" );
260- moonModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = moonTexture ;
261-
262303 float map_w = 2048.0f , map_h = 1024.0f ;
263304 float camDistance = 35.0f , camAngleX = 0.785f , camAngleY = 0.5f ;
264305
@@ -284,6 +325,13 @@ int main(void) {
284325 SetTargetFPS (cfg .target_fps );
285326
286327 while (!WindowShouldClose ()) {
328+ /*
329+ -----------------------------------------------------------------------------
330+ main simulation loop starts here.
331+ all the input handling, updating, and drawing happens in this loop, on each frame drawn
332+ -----------------------------------------------------------------------------
333+ */
334+
287335 // keyboard stuff
288336 if (IsKeyPressed (KEY_SPACE )) paused = !paused ;
289337 if (IsKeyPressed (KEY_PERIOD )) time_multiplier *= 2.0 ;
@@ -333,7 +381,7 @@ int main(void) {
333381 Vector2 mouseDelta = GetMouseDelta ();
334382 hovered_sat = NULL ;
335383
336- // moving the camera around smoothly via targets
384+ // moving the camera around smoothly via targets, split between 2d and 3d controls
337385 if (is_2d_view ) {
338386 if (IsMouseButtonDown (MOUSE_BUTTON_RIGHT ) || (IsMouseButtonDown (MOUSE_BUTTON_MIDDLE ) && IsKeyDown (KEY_LEFT_SHIFT ))) {
339387 target_camera2d_target = Vector2Add (target_camera2d_target , Vector2Scale (mouseDelta , -1.0f / target_camera2d_zoom ));
@@ -408,9 +456,12 @@ int main(void) {
408456
409457 // defining a hitbox area to cover the UI checkboxes + texts
410458 Rectangle cbHitbox = { 10 * cfg .ui_scale , (10 + 104 ) * cfg .ui_scale , 200 * cfg .ui_scale , 74 * cfg .ui_scale };
459+
411460
461+ // shooting left and right like its an american high school prom night
412462 if (IsMouseButtonPressed (MOUSE_BUTTON_LEFT )) {
413- // only update selection if the mouse is not clicking on the UI Checkboxes
463+ /* only update selection if the mouse is not clicking on the UI Checkboxes (wouldn't want to hurt them,
464+ they're just trying to do their job) */
414465 if (!CheckCollisionPointRec (GetMousePosition (), cbHitbox )) {
415466 selected_sat = hovered_sat ;
416467
@@ -451,7 +502,7 @@ int main(void) {
451502 else target_camera3d_target = draw_moon_pos ;
452503 }
453504
454- // apply the smooth lerping
505+ // apply the smooth lerping (is just linear interpolation for smoofness :D)
455506 float smooth_speed = 10.0f * GetFrameTime ();
456507
457508 camera2d .zoom = Lerp (camera2d .zoom , target_camera2d_zoom , smooth_speed );
@@ -506,6 +557,12 @@ int main(void) {
506557 float m_text_2d = 16.0f * cfg .ui_scale / camera2d .zoom ;
507558 float mark_size_2d = 32.0f * cfg .ui_scale / camera2d .zoom ;
508559
560+ /*
561+ -----------------------------------------------------------------------------
562+ drawing the 2d and 3d views depending on what's currently active;
563+ they share some of the same logic but are separate in how they render things
564+ -----------------------------------------------------------------------------
565+ */
509566 if (is_2d_view ) {
510567 // drawing the flat map
511568 BeginMode2D (camera2d );
@@ -785,6 +842,15 @@ int main(void) {
785842 }
786843 }
787844
845+
846+ /*
847+ -----------------------------------------------------------------------------
848+ aaaand finally the UI layer!!!! this is easy, just some text and checkboxes, no big deal~
849+ also includes the logic for the "hide unselected" feature which fades out non-selected satellites when enabled,
850+ gonna move that out eventually TODO
851+ -----------------------------------------------------------------------------
852+ */
853+
788854 // text overlays for the ui
789855 DrawUIText (is_2d_view ? "Controls: RMB to pan, Scroll to zoom. 'M' switches to 3D. Space: Pause." : "Controls: RMB to orbit, Shift+RMB to pan. 'M' switches to 2D. Space: Pause." , 10 * cfg .ui_scale , 10 * cfg .ui_scale , 20 * cfg .ui_scale , cfg .text_secondary );
790856 DrawUIText ("Time: '.' (Faster 2x), ',' (Slower 0.5x), '/' (1x Speed), 'Shift+/' (Reset)" , 10 * cfg .ui_scale , (10 + 24 )* cfg .ui_scale , 20 * cfg .ui_scale , cfg .text_secondary );
@@ -851,6 +917,7 @@ int main(void) {
851917 bool show_peri = true;
852918 bool show_apo = true;
853919
920+ // calculate the time of periapsis and apoapsis passages and their current positions for display in the UI
854921 double delta_time_s_curr = (current_epoch - active_sat -> epoch_days ) * 86400.0 ;
855922 double M_curr = fmod (active_sat -> mean_anomaly + active_sat -> mean_motion * delta_time_s_curr , 2.0 * PI );
856923 if (M_curr < 0 ) M_curr += 2.0 * PI ;
@@ -863,7 +930,7 @@ int main(void) {
863930
864931 double real_rp = Vector3Length (calculate_position (active_sat , t_peri ));
865932 double real_ra = Vector3Length (calculate_position (active_sat , t_apo ));
866-
933+ // hide the periapsis/apoapsis markers if they're currently behind the Earth in the 3D view, or just off the edge of the map in 2D
867934 if (is_2d_view ) {
868935 Vector2 p2 , a2 ;
869936 get_apsis_2d (active_sat , current_epoch , false, gmst_deg , cfg .earth_rotation_offset , map_w , map_h , & p2 );
@@ -899,7 +966,7 @@ int main(void) {
899966 // performance stats :3
900967 DrawUIText (TextFormat ("%3i FPS" , GetFPS ()), GetScreenWidth () - (90 * cfg .ui_scale ), 10 * cfg .ui_scale , 20 * cfg .ui_scale , cfg .sat_selected );
901968 DrawUIText (TextFormat ("%i Sats" , sat_count ), GetScreenWidth () - (90 * cfg .ui_scale ), 34 * cfg .ui_scale , 16 * cfg .ui_scale , cfg .text_secondary );
902-
969+
903970 EndDrawing ();
904971 }
905972
0 commit comments