[Tux4kids-commits] r320 - tuxmath/trunk/src

tholy-guest at alioth.debian.org tholy-guest at alioth.debian.org
Thu Nov 15 14:12:54 UTC 2007


Author: tholy-guest
Date: 2007-11-15 14:12:53 +0000 (Thu, 15 Nov 2007)
New Revision: 320

Modified:
   tuxmath/trunk/src/Makefile.in
   tuxmath/trunk/src/SDL_extras.c
   tuxmath/trunk/src/SDL_extras.h
   tuxmath/trunk/src/game.c
   tuxmath/trunk/src/setup.c
   tuxmath/trunk/src/tuxmath.h
Log:
Add a new function "Blend" in SDL_extras, and use it to smooth out the
animation of the igloo rebuilding.


Modified: tuxmath/trunk/src/Makefile.in
===================================================================
--- tuxmath/trunk/src/Makefile.in	2007-11-14 19:46:20 UTC (rev 319)
+++ tuxmath/trunk/src/Makefile.in	2007-11-15 14:12:53 UTC (rev 320)
@@ -59,7 +59,7 @@
 	$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"

Modified: tuxmath/trunk/src/SDL_extras.c
===================================================================
--- tuxmath/trunk/src/SDL_extras.c	2007-11-14 19:46:20 UTC (rev 319)
+++ tuxmath/trunk/src/SDL_extras.c	2007-11-15 14:12:53 UTC (rev 320)
@@ -234,7 +234,87 @@
 	return out;
 }
 
+/* Blend two surfaces together. The third argument is between 0.0 and
+   1.0, and represents the weight assigned to the first surface.  If
+   the pointer to the second surface is NULL, this performs fading.
 
+   Currently this works only with RGBA images, but this is largely to
+   make the (fast) pointer arithmetic work out; it could be easily
+   generalized to other image types. */
+SDL_Surface* Blend(SDL_Surface *S1,SDL_Surface *S2,float gamma)
+{
+  SDL_PixelFormat *fmt1,*fmt2;
+  Uint8 r1,r2,g1,g2,b1,b2,a1,a2;
+  SDL_Surface *tmpS,*ret;
+  Uint32 *cpix1,*epix1,*cpix2,*epix2;
+  float gamflip;
+
+  gamflip = 1.0-gamma;
+  if (gamma < 0 || gamflip < 0) {
+    perror("gamma must be between 0 and 1");
+    exit(0);
+  }
+  fmt1 = S1->format;
+  if (fmt1->BitsPerPixel != 32) {
+    perror("This works only with RGBA images");
+    return S1;
+  }
+  if (S2 != NULL) {
+    fmt2 = S2->format;
+    if (fmt2->BitsPerPixel != 32) {
+    perror("This works only with RGBA images");
+    return S1;
+    }
+    // Check that both images have the same width dimension
+    if (S1->w != S2->w) {
+      printf("S1->w %d, S2->w %d;  S1->h %d, S2->h %d\n",
+	     S1->w,S2->w,S1->h,S2->h);
+      printf("Both images must have the same width dimensions\n");
+      return S1;
+    }
+  }
+
+  tmpS = SDL_ConvertSurface(S1,fmt1,SDL_SWSURFACE);
+  SDL_LockSurface(tmpS);
+  // We're going to go through the pixels in reverse order, to start
+  // from the bottom of each image. That way, we can blend things that
+  // are not of the same height and have them align at the bottom.
+  // So the "ending pixel" (epix) will be before the first pixel, and
+  // the current pixel (cpix) will be the last pixel.
+  epix1 = (Uint32*) tmpS->pixels-1;
+  cpix1 = epix1 + tmpS->w*tmpS->h;
+  if (S2 != NULL) {
+    SDL_LockSurface(S2);
+    epix2 = (Uint32*) S2->pixels-1;
+    cpix2 = epix2 + S2->w*S2->h;
+  } else {
+    epix2 = epix1;
+    cpix2 = cpix1;
+  }
+
+  for (; cpix1 > epix1; cpix1--,cpix2--) {
+    SDL_GetRGBA(*cpix1,fmt1,&r1,&g1,&b1,&a1);
+    a1 = gamma*a1;
+    if (S2 != NULL && cpix2 > epix2) {
+      SDL_GetRGBA(*cpix2,fmt2,&r2,&g2,&b2,&a2);
+      r1 = gamma*r1 + gamflip*r2;
+      g1 = gamma*g1 + gamflip*g2;
+      b1 = gamma*b1 + gamflip*b2;
+      a1 += gamflip*a2;
+    }
+    *cpix1 = SDL_MapRGBA(fmt1,r1,g1,b1,a1);
+  }
+  SDL_UnlockSurface(tmpS);
+  if (S2 != NULL)
+    SDL_UnlockSurface(S2);
+
+  ret = SDL_DisplayFormatAlpha(tmpS);
+  SDL_FreeSurface(tmpS);
+
+  return ret;
+}
+
+
 /* BlackOutline() creates a surface containing text of the designated */
 /* foreground color, surrounded by a black shadow, on a transparent    */
 /* background.  The appearance can be tuned by adjusting the number of */

Modified: tuxmath/trunk/src/SDL_extras.h
===================================================================
--- tuxmath/trunk/src/SDL_extras.h	2007-11-14 19:46:20 UTC (rev 319)
+++ tuxmath/trunk/src/SDL_extras.h	2007-11-15 14:12:53 UTC (rev 320)
@@ -35,5 +35,6 @@
 int  inRect(SDL_Rect r, int x, int y);
 void DarkenScreen(Uint8 bits);
 void SwitchScreenMode(void);
+SDL_Surface* Blend(SDL_Surface *S1,SDL_Surface *S2,float gamma);
 
 #endif

Modified: tuxmath/trunk/src/game.c
===================================================================
--- tuxmath/trunk/src/game.c	2007-11-14 19:46:20 UTC (rev 319)
+++ tuxmath/trunk/src/game.c	2007-11-15 14:12:53 UTC (rev 320)
@@ -737,6 +737,7 @@
   game_set_message(&s4,"Notice the answer",left_edge,comets[0].y-100);
   help_renderframe_exit();
   SDL_Delay(4000);
+  game_clear_message(&s4);
 
   frame_start = frame;
   while (frame-frame_start < 5*FPS && !(quit_help = help_renderframe_exit()));  // wait 5 secs
@@ -746,7 +747,6 @@
   game_set_message(&s1,"If it gets hit again, the",left_edge,100);
   game_set_message(&s2,"penguin leaves.",left_edge,135);
   game_set_message(&s3, "(Press a key when ready)",left_edge,200);
-  game_clear_message(&s4);
 
   key_pressed = 0;
   while (!key_pressed && !(quit_help = help_renderframe_exit()));
@@ -1610,8 +1610,8 @@
 
 void game_handle_extra_life(void)
 {
-  int i,igloo_top,num_below,status,direction;
-  Uint8 cloud_transparency;
+  // This handles the animation sequence during the rebuilding of an igloo
+  int i,igloo_top,num_below_igloo,status,direction;
 
   if (cloud.status == EXTRA_LIFE_ON) {
 
@@ -1622,37 +1622,32 @@
      }
 #endif
 
+    // Get the cloud moving in the right direction, if not yet "parked"
     direction = 2*(cloud.city < NUM_CITIES/2) - 1;
     if (direction*cloud.x < direction*cities[cloud.city].x) {
       cloud.x += direction*PENGUIN_WALK_SPEED;
-      SDL_SetAlpha(images[IMG_CLOUD],SDL_SRCALPHA | SDL_RLEACCEL,
-		   SDL_ALPHA_OPAQUE);
     }
     else {
+      // Cloud is "parked," handle the snowfall and igloo rebuilding
       cities[cloud.city].status = CITY_REBUILDING;
-      for (i = 0, num_below = 0; i < NUM_SNOWFLAKES; i++) {
+      igloo_top = screen->h - igloo_vertical_offset
+	- images[IMG_IGLOO_INTACT]->h;
+      for (i = 0, num_below_igloo = 0; i < NUM_SNOWFLAKES; i++) {
 	cloud.snowflake_y[i] += SNOWFLAKE_SPEED;
-	if (cloud.snowflake_y[i] > cloud.y)
-	  num_below++;
+	if (cloud.snowflake_y[i] > igloo_top)
+	  num_below_igloo++;
       }
-      cloud_transparency = (Uint8) ((float) (NUM_SNOWFLAKES-num_below)/NUM_SNOWFLAKES
-	* (float) SDL_ALPHA_OPAQUE);
-      status = SDL_SetAlpha(images[IMG_CLOUD],SDL_SRCALPHA,cloud_transparency);
-      igloo_top = screen->h - igloo_vertical_offset
-	- images[IMG_IGLOO_INTACT]->h;
       if (cloud.snowflake_y[NUM_SNOWFLAKES-1] > igloo_top) {
 	cities[cloud.city].hits_left = 2;
-	cities[cloud.city].img = IMG_IGLOO_INTACT;
-      }
-      else if (cloud.snowflake_y[2*NUM_SNOWFLAKES/3] > igloo_top &&
-	       cities[cloud.city].hits_left == 0)
-	cities[cloud.city].img = IMG_IGLOO_REBUILDING2;
-      else if (cloud.snowflake_y[NUM_SNOWFLAKES/3] > igloo_top &&
-	       cities[cloud.city].hits_left == 0)
-	cities[cloud.city].img = IMG_IGLOO_REBUILDING1;
-      if (cloud.snowflake_y[NUM_SNOWFLAKES/3] > igloo_top) {
+	cities[cloud.city].img = IMG_IGLOO_INTACT; // completely rebuilt
+      } else if (cities[cloud.city].hits_left == 0) {
+	// We're going to draw one of the blended igloos
+	// FIXME: It's a hack to encode a blended igloo with a negative number!
 	penguins[cloud.city].layer = 0;
 	cities[cloud.city].layer = 1;
+	if (num_below_igloo < 3)
+	  num_below_igloo = 0;   // Don't show progress until a few have fallen
+	cities[cloud.city].img = -((float) (num_below_igloo)/NUM_SNOWFLAKES) * NUM_BLENDED_IGLOOS;
       }
       if (cloud.snowflake_y[NUM_SNOWFLAKES-1] > screen->h - igloo_vertical_offset) {
 	/* exit rebuilding when last snowflake at igloo bottom */
@@ -1790,7 +1785,13 @@
 	  max_layer = steam[i].layer;
 	if (cities[i].layer == current_layer &&
 	    cities[i].img != IMG_CITY_NONE) {
-	  this_image = images[cities[i].img];
+	  // Handle the blended igloo images, which are encoded
+	  // (FIXME) with a negative image number
+	  if (cities[i].img <= 0)
+	    this_image = blended_igloos[-cities[i].img];
+	  else
+	    this_image = images[cities[i].img];
+	  //this_image = blended_igloos[frame % NUM_BLENDED_IGLOOS];
 	  dest.x = cities[i].x - (this_image->w / 2);
 	  dest.y = (screen->h) - (this_image->h) - igloo_vertical_offset;
 	  if (cities[i].img == IMG_IGLOO_MELTED3 ||

Modified: tuxmath/trunk/src/setup.c
===================================================================
--- tuxmath/trunk/src/setup.c	2007-11-14 19:46:20 UTC (rev 319)
+++ tuxmath/trunk/src/setup.c	2007-11-15 14:12:53 UTC (rev 320)
@@ -59,6 +59,7 @@
 #define NUM_FLIPPED_IMAGES 6
 SDL_Surface* flipped_images[NUM_FLIPPED_IMAGES];
 int flipped_img_lookup[NUM_IMAGES];
+SDL_Surface* blended_igloos[NUM_BLENDED_IGLOOS];
 
 const int flipped_img[] = {
   IMG_PENGUIN_WALK_ON1,
@@ -81,6 +82,7 @@
 void initialize_SDL(void);
 void load_data_files(void);
 void generate_flipped_images(void);
+void generate_blended_images(void);
 
 //int initialize_game_options(void);
 void seticon(void);
@@ -104,6 +106,8 @@
   load_data_files();
  /* Generate flipped versions of walking images */
   generate_flipped_images();
+  /* Generate blended images (e.g., igloos) */
+  generate_blended_images();
 }
 
 
@@ -536,6 +540,28 @@
 }
 
 
+/* Created images that are blends of two other images to smooth out
+   the transitions. */
+void generate_blended_images(void)
+{
+  blended_igloos[0] = Blend(images[IMG_IGLOO_REBUILDING1],NULL,0.06);
+  blended_igloos[1] = Blend(images[IMG_IGLOO_REBUILDING1],NULL,0.125);
+  blended_igloos[2] = Blend(images[IMG_IGLOO_REBUILDING1],NULL,0.185);
+  blended_igloos[3] = Blend(images[IMG_IGLOO_REBUILDING1],NULL,0.25);
+  blended_igloos[4] = Blend(images[IMG_IGLOO_REBUILDING1],NULL,0.5);
+  blended_igloos[5] = Blend(images[IMG_IGLOO_REBUILDING1],NULL,0.75);
+  blended_igloos[6] = images[IMG_IGLOO_REBUILDING1];
+  blended_igloos[7] = Blend(images[IMG_IGLOO_REBUILDING2],images[IMG_IGLOO_REBUILDING1],0.25);
+  blended_igloos[8] = Blend(images[IMG_IGLOO_REBUILDING2],images[IMG_IGLOO_REBUILDING1],0.5);
+  blended_igloos[9] = Blend(images[IMG_IGLOO_REBUILDING2],images[IMG_IGLOO_REBUILDING1],0.75);
+  blended_igloos[10] = images[IMG_IGLOO_REBUILDING2];
+  blended_igloos[11] = Blend(images[IMG_IGLOO_INTACT],images[IMG_IGLOO_REBUILDING2],0.25);
+  blended_igloos[12] = Blend(images[IMG_IGLOO_INTACT],images[IMG_IGLOO_REBUILDING2],0.5);
+  blended_igloos[13] = Blend(images[IMG_IGLOO_INTACT],images[IMG_IGLOO_REBUILDING2],0.75);
+  blended_igloos[14] = images[IMG_IGLOO_INTACT];
+}
+
+
 /* save options and free heap */
 /* use for successful exit */
 void cleanup(void)

Modified: tuxmath/trunk/src/tuxmath.h
===================================================================
--- tuxmath/trunk/src/tuxmath.h	2007-11-14 19:46:20 UTC (rev 319)
+++ tuxmath/trunk/src/tuxmath.h	2007-11-15 14:12:53 UTC (rev 320)
@@ -147,6 +147,8 @@
 extern SDL_Surface* screen; /* declared in setup.c; also used in game.c, options.c, fileops.c, credits.c, titlescreen.c */
 extern SDL_Surface* images[];    /* declared in setup.c, used in same files as screen */
 extern SDL_Surface* flipped_images[];
+#define NUM_BLENDED_IGLOOS 15
+extern SDL_Surface* blended_igloos[];
 extern int flipped_img_lookup[];
 
 extern TTF_Font  *default_font;




More information about the Tux4kids-commits mailing list