1616/* Embedded font, image, and music data */
1717#include "font_data.h"
1818#include "image_data.h"
19+ #include "logo_data.h"
1920
2021/* Music data will be included when available */
2122#ifdef HAVE_MUSIC
@@ -46,6 +47,8 @@ typedef struct {
4647 TTF_Font * font ;
4748 SDL_Surface * jack_surface ;
4849 SDL_Texture * jack_texture ;
50+ SDL_Surface * logo_surface ;
51+ SDL_Texture * logo_texture ;
4952 int current_scene ;
5053 int fixed_scene ;
5154 float time ;
@@ -415,6 +418,95 @@ void render_tunnel(DemoContext *ctx) {
415418 }
416419}
417420
421+ /* Bouncing logo effect with squash and stretch */
422+ void render_bouncing_logo (DemoContext * ctx ) {
423+ static float squash_x = 1.0f ; /* Horizontal scale factor */
424+ static float squash_y = 1.0f ; /* Vertical scale factor */
425+ static float prev_x = -1.0f ; /* Previous x position */
426+ static float prev_y = -1.0f ; /* Previous y position */
427+
428+ /* Clear to dark blue background */
429+ for (int i = 0 ; i < WIDTH * HEIGHT ; i ++ ) {
430+ ctx -> pixels [i ] = 0xFF001020 ;
431+ }
432+
433+ if (!ctx -> logo_texture ) {
434+ SDL_UpdateTexture (ctx -> texture , NULL , ctx -> pixels , WIDTH * sizeof (Uint32 ));
435+ SDL_RenderClear (ctx -> renderer );
436+ SDL_RenderCopy (ctx -> renderer , ctx -> texture , NULL , NULL );
437+ return ;
438+ }
439+
440+ /* Get logo dimensions */
441+ int logo_w , logo_h ;
442+ SDL_QueryTexture (ctx -> logo_texture , NULL , NULL , & logo_w , & logo_h );
443+
444+ /* Bouncing physics with sine waves for smooth motion */
445+ float t = ctx -> time ;
446+ float bounce_x = sin (t * 0.8 ) * (WIDTH - logo_w ) / 2 + (WIDTH - logo_w ) / 2 ;
447+ float bounce_y = fabs (sin (t * 1.1 )) * (HEIGHT - logo_h - 50 ) + 25 ;
448+
449+ /* Detect edge collisions by checking velocity direction changes */
450+ float squash_intensity = 0.1f ; /* How much to squash (0.1 = 10% compression) */
451+ float recovery_speed = 0.25f ; /* How fast to recover to normal */
452+
453+ /* Check horizontal collision (left/right edges) */
454+ /*if (prev_x >= 0) {
455+ float dx = bounce_x - prev_x;
456+ // Detect direction change = wall hit
457+ if ((prev_x <= 5 && dx > 0) || (prev_x >= WIDTH - logo_w - 5 && dx < 0)) {
458+ squash_x = 1.0f - squash_intensity; // Squash horizontally
459+ squash_y = 1.0f + squash_intensity; // Stretch vertically
460+ }
461+ }*/
462+
463+ /* Check vertical collision (top/bottom edges) */
464+ if (prev_y >= 0 ) {
465+ float dy = bounce_y - prev_y ;
466+ /* Detect direction change = floor/ceiling hit */
467+ if ((prev_y <= 30 && dy > 0 ) || (prev_y >= HEIGHT - logo_h - 30 && dy < 0 )) {
468+ squash_y = 1.0f - squash_intensity ; /* Squash vertically */
469+ squash_x = 1.0f + squash_intensity ; /* Stretch horizontally */
470+ }
471+ }
472+
473+ /* Smoothly recover to normal scale */
474+ squash_x += (1.0f - squash_x ) * recovery_speed ;
475+ squash_y += (1.0f - squash_y ) * recovery_speed ;
476+
477+ /* Clamp to prevent overshoot */
478+ if (fabs (squash_x - 1.0f ) < 0.01f ) squash_x = 1.0f ;
479+ if (fabs (squash_y - 1.0f ) < 0.01f ) squash_y = 1.0f ;
480+
481+ /* Store position for next frame */
482+ prev_x = bounce_x ;
483+ prev_y = bounce_y ;
484+
485+ /* Add some gentle rotation */
486+ float rotation = sin (t * 0.5 ) * 8.0 ; /* ±8 degrees */
487+
488+ /* Apply squash and stretch to dimensions */
489+ int scaled_w = (int )(logo_w * squash_x );
490+ int scaled_h = (int )(logo_h * squash_y );
491+
492+ /* Center the scaled logo at the bounce position */
493+ SDL_Rect dest_rect = {
494+ (int )(bounce_x + (logo_w - scaled_w ) / 2 ),
495+ (int )(bounce_y + (logo_h - scaled_h ) / 2 ),
496+ scaled_w ,
497+ scaled_h
498+ };
499+
500+ /* Update background texture */
501+ SDL_UpdateTexture (ctx -> texture , NULL , ctx -> pixels , WIDTH * sizeof (Uint32 ));
502+ SDL_RenderClear (ctx -> renderer );
503+ SDL_RenderCopy (ctx -> renderer , ctx -> texture , NULL , NULL );
504+
505+ /* Render the rotating, squashing logo */
506+ SDL_RenderCopyEx (ctx -> renderer , ctx -> logo_texture , NULL , & dest_rect ,
507+ rotation , NULL , SDL_FLIP_NONE );
508+ }
509+
418510/* Scroll text rendering with different styles */
419511void render_scroll_text (DemoContext * ctx ) {
420512 const char * text = " INFIX - CONTAINER DEMO"
@@ -594,22 +686,23 @@ int main(int argc, char *argv[]) {
594686 if (strcmp (argv [1 ], "--help" ) == 0 || strcmp (argv [1 ], "-h" ) == 0 ) {
595687 printf ("Usage: %s [scene]\n" , argv [0 ]);
596688 printf ("Scenes:\n" );
597- printf (" 0 - Plasma \n" );
598- printf (" 1 - Scroller \n" );
689+ printf (" 0 - Starfield \n" );
690+ printf (" 1 - Plasma \n" );
599691 printf (" 2 - Cube\n" );
600692 printf (" 3 - Tunnel\n" );
693+ printf (" 4 - Bouncing Logo\n" );
601694 printf ("\nIf no scene is specified, auto-switches between all scenes.\n" );
602695 IMG_Quit ();
603696 TTF_Quit ();
604697 SDL_Quit ();
605698 return 0 ;
606699 }
607700 int scene = atoi (argv [1 ]);
608- if (scene >= 0 && scene <= 3 ) {
701+ if (scene >= 0 && scene <= 4 ) {
609702 ctx .fixed_scene = scene ;
610703 ctx .current_scene = scene ;
611704 } else {
612- fprintf (stderr , "Invalid scene number. Use 0-3 .\n" );
705+ fprintf (stderr , "Invalid scene number. Use 0-4 .\n" );
613706 IMG_Quit ();
614707 TTF_Quit ();
615708 SDL_Quit ();
@@ -696,6 +789,26 @@ int main(int argc, char *argv[]) {
696789 }
697790 }
698791
792+ /* Load embedded logo.png from memory */
793+ SDL_RWops * logo_rw = SDL_RWFromConstMem (logo_png , logo_png_len );
794+ if (!logo_rw ) {
795+ fprintf (stderr , "Warning: Failed to create RWops for logo: %s\n" , SDL_GetError ());
796+ fprintf (stderr , "Bouncing logo scene will not render.\n" );
797+ ctx .logo_texture = NULL ;
798+ ctx .logo_surface = NULL ;
799+ } else {
800+ ctx .logo_surface = IMG_Load_RW (logo_rw , 1 ); /* 1 = automatically close RW */
801+ if (!ctx .logo_surface ) {
802+ fprintf (stderr , "Warning: Failed to load embedded logo: %s\n" , IMG_GetError ());
803+ fprintf (stderr , "Bouncing logo scene will not render.\n" );
804+ ctx .logo_texture = NULL ;
805+ } else {
806+ /* Create and cache the texture */
807+ ctx .logo_texture = SDL_CreateTextureFromSurface (ctx .renderer , ctx .logo_surface );
808+ SDL_SetTextureBlendMode (ctx .logo_texture , SDL_BLENDMODE_BLEND );
809+ }
810+ }
811+
699812 /* Initialize starfield */
700813 for (int i = 0 ; i < NUM_STARS ; i ++ ) {
701814 ctx .stars [i ].x = (rand () % 2000 - 1000 ) / 10.0f ;
@@ -757,7 +870,7 @@ int main(int argc, char *argv[]) {
757870 } else if (fade_progress < 2.0f ) {
758871 /* Switch scene and fade in */
759872 if (ctx .fade_alpha < 0.5f ) {
760- ctx .current_scene = (ctx .current_scene + 1 ) % 4 ;
873+ ctx .current_scene = (ctx .current_scene + 1 ) % 5 ;
761874 scene_start = current_time - (Uint32 )fade_duration ;
762875 ctx .time = 0 ;
763876 }
@@ -804,6 +917,11 @@ int main(int argc, char *argv[]) {
804917 SDL_RenderCopy (ctx .renderer , ctx .texture , NULL , NULL );
805918 render_scroll_text (& ctx );
806919 break ;
920+ case 4 :
921+ ctx .scroll_style = SCROLL_BOTTOM_TRADITIONAL ;
922+ render_bouncing_logo (& ctx );
923+ render_scroll_text (& ctx );
924+ break ;
807925 }
808926
809927 /* Apply fade effect */
@@ -825,6 +943,12 @@ int main(int argc, char *argv[]) {
825943 if (ctx .jack_texture ) {
826944 SDL_DestroyTexture (ctx .jack_texture );
827945 }
946+ if (ctx .logo_surface ) {
947+ SDL_FreeSurface (ctx .logo_surface );
948+ }
949+ if (ctx .logo_texture ) {
950+ SDL_DestroyTexture (ctx .logo_texture );
951+ }
828952 if (ctx .plasma_texture ) {
829953 SDL_DestroyTexture (ctx .plasma_texture );
830954 }
0 commit comments