[Xbubble-commits] xbubble-sdl/src board.c, 1.11, 1.12 board.h, 1.8, 1.9 bubble.c, 1.3, 1.4 bubble.h, 1.2, 1.3 game.c, 1.8, 1.9 setting.h, 1.7, 1.8 sprite.c, 1.2, 1.3 sprite.h, 1.1.1.1, 1.2 utils.h, 1.5, 1.6

Martin Quinson mquinson at alioth.debian.org
Mon Oct 23 14:44:35 UTC 2006


Update of /cvsroot/xbubble/xbubble-sdl/src
In directory haydn:/tmp/cvs-serv2777

Modified Files:
	board.c board.h bubble.c bubble.h game.c setting.h sprite.c 
	sprite.h utils.h 
Log Message:
Redraw only dirty part of the screen (tryof)

Index: bubble.h
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/bubble.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- bubble.h	11 Sep 2006 21:33:19 -0000	1.2
+++ bubble.h	23 Oct 2006 14:44:31 -0000	1.3
@@ -10,8 +10,8 @@
   int color;
   int clock;
   int cell;
-  double x; /* offsetted by the board */
-  double y; /* offsetted by the board */
+  double x; /* screen coords */
+  double y; /* screen coords */
   double vx;
   double vy;
   double target_y; /* offsetted by the board */
@@ -23,8 +23,8 @@
 		     board_t board );
 void bubble_free( bubble_t bubble );
 void bubble_set_state( bubble_t bubble,enum e_bubble_state state, int layer, int c);
-void bubble_set_pos( bubble_t bubble, board_t board, double sx, double sy );
-void bubble_update_sprite(bubble_t bubble, board_t board);
+void bubble_set_pos( bubble_t bubble, double sx, double sy );
+void bubble_update_sprite(bubble_t bubble);
 
 
 int bubble_get_animation_duration( bubble_t bubble );

Index: game.c
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/game.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- game.c	14 Sep 2006 19:53:50 -0000	1.8
+++ game.c	23 Oct 2006 14:44:31 -0000	1.9
@@ -225,7 +225,7 @@
 static void redraw_game_window( game_t game ) {
   int n;
   for ( n = 0; n < game->nb_boards; n++ )
-    board_redraw( game->board[n], 0 );
+    board_redraw( game->board[n] );
 }
 
 static inline void game_get_cmds(game_t game) {
@@ -294,8 +294,7 @@
   for ( i = 0; i < game->nb_boards; i++ ) { 
     board_animate( game->board[i], dt );
     lost = lost || board_get_state( game->board[i] ) == board_state_lost;
-    board_redraw( game->board[i], 
-		  board_was_lowered( game->board[i] ) /* redraw everything if the board was lowered */ );
+    board_redraw( game->board[i] );
   }
   if (( game->multi_player )&&( game->state != game_state_over )&&( !lost )) {
     int given = 0;

Index: utils.h
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/utils.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- utils.h	16 Sep 2006 13:28:14 -0000	1.5
+++ utils.h	23 Oct 2006 14:44:31 -0000	1.6
@@ -81,7 +81,7 @@
 #define MIN(a,b) ((a)<(b)? (a):(b))
 #define MAX(a,b) ((a)>(b)? (a):(b))
 #define clip( X, m, M ) (( X < m )? m : (( X > M )? M : X ))
-#define BETWEEN(n, nmin, nmax) ((n>nmin)&&(n>nmax))
+#define BETWEEN(n, nmin, nmax) ((n>=nmin)&&(n<=nmax))
 
 char *file_resolve_path(const char *name, const char *theme);
 

Index: board.c
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/board.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- board.c	16 Sep 2006 00:49:01 -0000	1.11
+++ board.c	23 Oct 2006 14:44:31 -0000	1.12
@@ -103,7 +103,7 @@
   board->array = cell_array_new( mov_ceiling, scale, offset->x, offset->y );
   board->bubbles = set_new( 2*NB_CELLS );
   board->tmpset = set_new( 2*NB_CELLS );
-  board->sprite_pool = sprite_pool_new( TOP_LAYER+1, 2*NB_CELLS, theme );
+  board->sprite_pool = sprite_pool_new( 2*NB_CELLS, theme );
   board->input = vector_new( NB_CELLS );
   board->output = vector_new( NB_CELLS );
   board->explosive_bubbles = set_new( NB_CELLS );
@@ -151,15 +151,13 @@
   board->bottom_border = board2screen_y(BOARD_HEIGHT - 0.5, board);
 
   /* alert blinking light */
-  board->alert = sprite_new( BOTTOM_LAYER, 30, theme->alert_a, 0, 0);
-  sprite_set_pos( board->alert, board->alert_x, board->alert_y );
-  sprite_pool_add( board->sprite_pool, board->alert );
+  board->alert = sprite_new( board->sprite_pool, BOTTOM_LAYER, 30, theme->alert_a, 0, 0);
+  sprite_set_pos( board->alert, (int)board->alert_x, (int)board->alert_y );
   board->alert_on = 0;
   board->clock = 0;
 
   /* countdown */
-  board->countdown_sprite = sprite_new( BOTTOM_LAYER, 30, theme->countdown_a,
-					0, 0);
+  board->countdown_sprite = sprite_new( NULL, BOTTOM_LAYER, 30, theme->countdown_a, 0, 0);
   sprite_set_pos( board->countdown_sprite, 
 		  board->countdown_x, board->countdown_y);
   board->countdown_state = INACTIVE;
@@ -169,13 +167,13 @@
   board->canon_angle = 0;
   board->canon_virtual_angle = 0.0;
   board->canon_direction = canon_stopped;
-  board->canon_sprite = sprite_new( CANON_LAYER, 30, theme->canon_a, 0, 0);
+  board->canon_sprite = sprite_new( board->sprite_pool, CANON_LAYER, 30, theme->canon_a, 0, 0);
   frame_t frame= theme->canon_a->element[0];
   sprite_set_pos( board->canon_sprite, 
 		  board->ready_x - frame->surf->h/2,
 		  board->ready_y - frame->surf->w/4);
   sprite_pool_add( board->sprite_pool, board->canon_sprite );
-
+   
   /* precompute launching vectors */
   for ( i = 0; i < NB_ANGLES; i++ ) {
     board->vx[i] = board->scale*LAUNCHING_SPEED*sin((i-CANON_ANGLE_MAX)*ANGLE_STEP );
@@ -246,8 +244,8 @@
 void board_draw( board_t board ) {
   sprite_pool_draw(board->sprite_pool, screen, &board->offset);
 }
-void board_redraw( board_t board, int forcefully ) {
-  sprite_pool_redraw(board->sprite_pool, screen, forcefully, &board->offset);
+void board_redraw( board_t board ) {   
+  sprite_pool_redraw(board->sprite_pool, screen, &board->offset);
 }
 
 /************************** countdown functions ***************************/
@@ -346,7 +344,7 @@
   double sx, sy;
   cell_screen_coord( board->array, target, &sx, &sy );
   bubble_set_state( bubble, STUCK, BOTTOM_LAYER, 0);
-  bubble_set_pos( bubble, board, sx, sy );
+  bubble_set_pos( bubble, sx, sy );
   bubble->cell = target;
   board->array->cell[target] = bubble;
 }
@@ -402,13 +400,13 @@
 	/* elliptic trajectory */
        	x = board->ready_x - ( board->ready_x - board->new_x ) * cos(t);
 	y = board->new_y + ( board->ready_y - board->new_y )*sin(t);
-	bubble_set_pos( bubble, board, x, y );
+	bubble_set_pos( bubble, x, y );
 	bubble->clock += dt;
 	
 	/* if bubble has reached canon then we're ready to fire */
 	if ( bubble->clock > CANON_LOAD_TIME ) {
 	  bubble_set_state( bubble, READY, MEDIUM_LAYER, 0 );
-	  bubble_set_pos( bubble, board, board->ready_x, board->ready_y );
+	  bubble_set_pos( bubble, board->ready_x, board->ready_y );
 	  board->canon_empty = 0;
 	  /* add a new bubble */
 	  board->next_color = bubble_next_color( board );
@@ -506,7 +504,7 @@
 	                                     : board_state_ready_to_fire;
 
       } else { /* not reached position yet. Ask sprite to move */
-	bubble_update_sprite(bubble,board);
+	bubble_update_sprite(bubble);
       }
       break;
       
@@ -564,14 +562,14 @@
       }
 
       /* display the result */
-      bubble_update_sprite( bubble, board );
       sprite_inc_clock( bubble->sprite, dt );
+      bubble_update_sprite( bubble );
        
       break;
       
     case RISING:
       active = 1;
-      bubble_set_pos( bubble, board,
+      bubble_set_pos( bubble, 
 		      bubble->x + dt*bubble->vx,
 		      bubble->y + dt*bubble->vy );
       sprite_inc_clock( bubble->sprite, dt );
@@ -633,7 +631,7 @@
       bubble = board_new_bubble( board, color);
       bubble_set_state( bubble, RISING, TOP_LAYER, 0);
       cell_screen_coord( board->array, target_cell, &x, &y);
-      bubble_set_pos( bubble, board, x, BOARD_HEIGHT - 0.5);
+      bubble_set_pos( bubble, x, BOARD_HEIGHT - 0.5);
       bubble->vx = 0;
       bubble->vy = -board->scale*RISING_SPEED;
       bubble->cell = target_cell;
@@ -698,13 +696,13 @@
      double x,y;
      bubble=board->malus_indicators10->element[i];
      cell_screen_coord( board->array, cellCL(board->array, -1, i+1), &x, &y);
-     bubble_set_pos( bubble, board, x, y);
+     bubble_set_pos( bubble, x, y);
   }
   for (i=0; i<board->malus_indicators->size; i++) {
      double x,y;
      bubble=board->malus_indicators->element[i];
      cell_screen_coord( board->array, cellCL(board->array, -1, i+board->malus_indicators10->size), &x, &y);
-     bubble_set_pos( bubble, board, x, y);
+     bubble_set_pos( bubble, x, y);
   }
    
 }
@@ -742,7 +740,7 @@
   for ( i = 0; i < board->bubbles->size; i++ ) {
     bubble = board->bubbles->element[i];
     if ( bubble->state == STUCK ) 
-      bubble_set_pos( bubble, board, bubble->x, bubble->y+ROW_HEIGHT*board->scale );
+      bubble_set_pos( bubble, bubble->x, bubble->y+ROW_HEIGHT*board->scale );
     /* update cell record, avoiding overflow */
     if (bubble->cell + COLS < NB_CELLS) {
        bubble->cell += COLS;
@@ -864,7 +862,7 @@
 static const char *cmd_names[4]= {"left","stop","right","fire"};
    
 void board_cmd(board_t board, enum e_board_cmd cmd) {   
-   printf("%s %u\n", cmd_names[cmd], board->clock);
+//   printf("%s %u\n", cmd_names[cmd], board->clock);
 	    
    switch(cmd) {
     case canon_left:

Index: bubble.c
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/bubble.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- bubble.c	11 Sep 2006 21:33:19 -0000	1.3
+++ bubble.c	23 Oct 2006 14:44:31 -0000	1.4
@@ -36,8 +36,8 @@
   bubble->y = y;
   bubble->vx = bubble->vy = 0;
   bubble->theme = board->theme;
-  bubble->sprite = sprite_new_bubble( layer, 30, board->theme, color, NEW );
-  bubble_set_pos( bubble, board, x, y);
+  bubble->sprite = sprite_new_bubble( board->sprite_pool, layer, 30, board->theme, color, NEW );
+  bubble_set_pos( bubble, x, y);
 
   return bubble;
 }
@@ -57,14 +57,14 @@
   sprite_set_layer( s, layer);
 }
 
-void bubble_update_sprite(bubble_t bubble,board_t board) {
+void bubble_update_sprite(bubble_t bubble) {
   sprite_set_pos( bubble->sprite, bubble->x, bubble->y);
 }
 
-void bubble_set_pos( bubble_t bubble, board_t board, double sx, double sy ) {
+void bubble_set_pos( bubble_t bubble, double sx, double sy ) {
   bubble->x = sx;
   bubble->y = sy;
-  bubble_update_sprite(bubble,board);
+  bubble_update_sprite(bubble);
 }
 
 int bubble_get_animation_duration( bubble_t bubble ) {

Index: sprite.h
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/sprite.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- sprite.h	11 Aug 2006 12:14:43 -0000	1.1.1.1
+++ sprite.h	23 Oct 2006 14:44:31 -0000	1.2
@@ -9,7 +9,7 @@
 typedef struct _sprite_t * sprite_t;
 typedef struct _sprite_pool_t * sprite_pool_t;
 
-sprite_t sprite_new( int layer, int overlapmax, Set a, int frame, int cycle );
+sprite_t sprite_new( sprite_pool_t sp, int layer, int overlapmax, Set a, int frame, int cycle );
 void   sprite_free(sprite_t s);
 
 void   sprite_set_pos( sprite_t s, int x, int y );
@@ -21,10 +21,9 @@
 void   sprite_set_animation( sprite_t s, Set a, int frame, int cycle );
 Set    sprite_get_animation( sprite_t s );
 
-sprite_t sprite_new_bubble( int layer, int overlap_max, 
-			  theme_t *theme, int color, int state );
-void   sprite_set_bubble_animation( sprite_t s, 
-				    theme_t *theme, int color, int state);
+sprite_t sprite_new_bubble( sprite_pool_t sp, int layer, int overlap_max, 
+			    theme_t *theme, int color, int state );
+void   sprite_set_bubble_animation( sprite_t s, theme_t *theme, int color, int state);
 
 void   sprite_set_layer( sprite_t s, int layer );
 void   sprite_set_frame( sprite_t s, int frame );
@@ -33,15 +32,13 @@
 
 
 
-sprite_pool_t sprite_pool_new( int nb_layers, int nb_sprites_max, theme_t *t );
+sprite_pool_t sprite_pool_new( int nb_sprites_max, theme_t *t );
 void          sprite_pool_free( sprite_pool_t sp );
 
 void sprite_pool_add( sprite_pool_t sp, sprite_t s );
 void sprite_pool_del( sprite_pool_t sp, sprite_t s );
 
-void sprite_draw( sprite_pool_t sp, sprite_t s, SDL_Surface *onto);
 void sprite_pool_draw( sprite_pool_t sp, SDL_Surface *onto, SDL_Rect *bg_off);
-void sprite_pool_redraw( sprite_pool_t sp, SDL_Surface *onto, int forceful,
-			 SDL_Rect *bg_off);
+void sprite_pool_redraw( sprite_pool_t sp, SDL_Surface *onto, SDL_Rect *bg_off);
 
 #endif /* _SPRITE_H */

Index: setting.h
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/setting.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- setting.h	15 Sep 2006 10:14:46 -0000	1.7
+++ setting.h	23 Oct 2006 14:44:31 -0000	1.8
@@ -47,7 +47,7 @@
 #define LAUNCHING_SPEED      0.02     /* velocity of launched bubbles (cell/ms) */
 #define EXPLODING_SPEED      0.0003   /* vertical velocity after explosion (cell/ms) */
 #define RISING_SPEED         0.04     /* velocity of incoming bubbles (cell/ms) */
-#define GRAVITY              0.00003  /* gravity (cell.ms^-2) */
+#define GRAVITY              0.0003  /* gravity (cell.ms^-2) */
 
 /* times in milliseconds */
 #define PROPAGATION_TIME     15       /* explosion propagation time */
@@ -77,5 +77,6 @@
 #define MENUFONT_COLOR {0xc0, 0xc0, 0xc0}
 #define MENUFONT_SELECTED_COLOR {0xc0, 0xc0, 0x00}
 #define MAX_NB_LEVELS  100
+#define NB_LAYERS 5
 
 #endif /* _SETTING_H */

Index: sprite.c
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/sprite.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- sprite.c	12 Sep 2006 08:04:08 -0000	1.2
+++ sprite.c	23 Oct 2006 14:44:31 -0000	1.3
@@ -14,16 +14,19 @@
   SPIRIT_FINISHED
 };
 
+/* Update the dirty zone of the containing sprite pool whenever a sprite is changed */
+static void sprite_dirty(sprite_t s);
+
 /* * * * * * * * * * * * * * * * * * * * * * * * */
 /* sprite_t functions                              */
 /* * * * * * * * * * * * * * * * * * * * * * * * */
 struct _sprite_t {
+  sprite_pool_t sp; /* buddies */
   int layer;    /* layer at which I am in my pool */
   int frame;    /* frame number curently displayed */
   int clock;    /* Change frame when clock > frame->delay */
-  SDL_Rect pos; /* position */
-  SDL_Rect mov; /* speed */
-  SDL_Rect dim; /* x->width; y->heigth */
+  SDL_Rect pos; /* position and dimension*/
+  SDL_Rect mov; /* speed (h&w unused) */
   int cycle;    /* boolean: animation should cycle or stop at last frame */
   Set overlap;  /* all sprite of the same pool overlapping with me */
   Set animation;/* all frames of the graphical animation */
@@ -32,8 +35,10 @@
 
 
 /* Const/Dest */
-sprite_t sprite_new( int layer, int overlap_max, Set anim, int frame, int cycle){
+sprite_t sprite_new(sprite_pool_t sp, int layer, int overlap_max, Set anim, int frame, int cycle){
+  frame_t f=anim->element[frame];
   sprite_t s = ( sprite_t ) xmalloc( sizeof( struct _sprite_t ));
+  s->sp=sp;
   s->layer = layer;
   s->animation = anim;
   s->frame = frame;
@@ -41,28 +46,25 @@
   s->clock = 0;
   s->pos.x = -1;
   s->pos.y = -1;
+  s->pos.w = f->pos.w;
+  s->pos.h = f->pos.h;
   s->mov.x = -1;
   s->mov.y = -1;
-  s->dim.x = -1;
-  s->dim.y = -1;
   s->overlap = set_new(overlap_max);
   s->state = SPIRIT_UNCHANGED;
   return s;
 }
 
-sprite_t sprite_new_bubble( int layer, int overlap_max, 
+sprite_t sprite_new_bubble( sprite_pool_t sp, int layer, int overlap_max, 
 			  theme_t *theme, int color, int state ) {
   Set a = theme->bubble_a[color][state];
-  frame_t f=a->element[0];
-  sprite_t res = sprite_new(layer,overlap_max, 
+  sprite_t res = sprite_new(sp, layer,overlap_max, 
 			    a, 0/*first frame*/,a->size>1/*cycle?*/);
   
-  memcpy(&res->dim,&f->dim,sizeof(SDL_Rect));
   return res;
 }
 void sprite_free(sprite_t s) {
   set_free(s->overlap);
-  //  delete_rectangle_list(s->redraw_boxes);
   free(s);
 }
 
@@ -70,8 +72,11 @@
 
 void sprite_set_pos( sprite_t s, int x, int y ) {
   if (( x != s->pos.x )||( y != s->pos.y )) {
+    if (s->pos.x>=0 && s->pos.y>0) 
+       sprite_dirty(s);
     s->pos.x = x;
     s->pos.y = y;
+    sprite_dirty(s);
     if ( s->state == SPIRIT_UNCHANGED || s->state == SPIRIT_NEEDS_REPAINT )
       s->state = SPIRIT_CHANGED;
   }
@@ -94,9 +99,9 @@
 }
 void sprite_get_dim( sprite_t s, int *h, int *w ) {
   if (h)
-    *h = s->dim.y;
+    *h = s->pos.y;
   if (w)
-    *w = s->dim.x;
+    *w = s->pos.x;
 }
 
 void sprite_set_animation( sprite_t s, Set a, int frame, int cycle ) {
@@ -105,9 +110,10 @@
   s->frame = frame;
   s->clock = 0;
   s->cycle = cycle;
-  memcpy(&s->dim,&f->dim,sizeof(SDL_Rect));
-  if ( s->state == SPIRIT_UNCHANGED )
-    s->state = SPIRIT_CHANGED;
+  s->pos.w = f->pos.w;
+  s->pos.h = f->pos.h;
+
+  sprite_dirty(s);
 }
 
 void sprite_set_bubble_animation( sprite_t s, 
@@ -124,6 +130,7 @@
 void sprite_set_layer( sprite_t s, int layer ) {
   if ( layer != s->layer ) {
     s->layer = layer;
+    sprite_dirty(s);
     if ( s->state == SPIRIT_UNCHANGED )
       s->state = SPIRIT_CHANGED;
   }
@@ -138,10 +145,9 @@
   if ( s->frame != frame ) {
     old_frame = s->animation->element[s->frame];
     new_frame = s->animation->element[frame];
-    if (!old_frame 
-	|| (( old_frame->surf->pixels != new_frame->surf->pixels )
-	    &&( s->state == SPIRIT_UNCHANGED )))
-      s->state = SPIRIT_CHANGED;
+    if ( old_frame->surf->pixels != new_frame->surf->pixels )
+      sprite_dirty(s);
+     
     s->frame = frame;
   }
 }
@@ -164,53 +170,88 @@
 /* sprite_t pool functions                         */
 /* * * * * * * * * * * * * * * * * * * * * * * * */
 struct _sprite_pool_t {
-  int nb_layers;
   Set pool;
-  Set *layer;
   theme_t *theme;
+  SDL_Rect dirty;
 };
 
-sprite_pool_t sprite_pool_new( int nb_layers, int nb_sprites_max, theme_t *t ) {
+static void sprite_pool_clean( sprite_pool_t sp) {
+  sp->dirty.w=0;
+  sp->dirty.h=0;
+  sp->dirty.x=32767;
+  sp->dirty.y=32767;
+//  DEBUG("Clean that dirt %d %d %d %d",  
+//	sp->dirty.x, sp->dirty.y, sp->dirty.w, sp->dirty.h);
+	
+}
+
+sprite_pool_t sprite_pool_new( int nb_sprites_max, theme_t *t ) {
   int i;
   sprite_pool_t sp = (sprite_pool_t) xmalloc( sizeof( struct _sprite_pool_t ));
 
-  sp->layer = (Set*) xmalloc( sizeof( Set ) * nb_layers );
   sp->pool = set_new( nb_sprites_max );
-  for ( i = 0; i < nb_layers; i++ )
-    sp->layer[i] = set_new( nb_sprites_max );
-
-  sp->nb_layers = nb_layers;
   sp->theme = t;
-
+  /* mark everything dirty */
+  sp->dirty.w=65535;
+  sp->dirty.h=65535;
+  sp->dirty.x=0;
+  sp->dirty.y=0;
+   
   return sp;
 }
 
 void sprite_pool_free( sprite_pool_t sp ) {
   int i;
-  for ( i = 0; i < sp->nb_layers; i++ )
-    set_free(sp->layer[i]);
   set_free(sp->pool);
-  free(sp->layer);
   free(sp);
 }
 
 void sprite_pool_add( sprite_pool_t sp, sprite_t s ) {
   set_add( sp->pool, s);
   s->state = SPIRIT_NEW;
+  s->sp = sp;
+  sprite_dirty(s);
 }
 
 void sprite_pool_del( sprite_pool_t sp, sprite_t s ) {
+  s->sp=NULL;
   if ( s->state == SPIRIT_NEW )
     set_remove( sp->pool, s );
   else
     s->state = SPIRIT_FINISHED;
 }
 
-void sprite_draw(sprite_pool_t sp, sprite_t s, SDL_Surface *onto) {
+/* Update the dirty zone of the containing sprite pool whenever a sprite is changed */
+static void sprite_dirty(sprite_t s) {
+  if (!s->sp) /* sometimes, the position is changed when the sprite is not in pool (for example for countdown) */
+     return;
+  SDL_Rect *dirty = &(s->sp->dirty);
+  SDL_Rect *sprite = &(s->pos);
+
+//  DEBUG("Add sprite %d %d %d %d to dirt %d %d %d %d ",
+//	sprite->x,sprite->y,sprite->w, sprite->h,
+//	dirty->x,dirty->y,dirty->w, dirty->h);
+   
+  dirty->x = MIN(dirty->x, sprite->x);
+  dirty->y = MIN(dirty->y, sprite->y);
+  dirty->w = MAX(dirty->w, sprite->x - dirty->x + sprite->w);
+  dirty->h = MAX(dirty->h, sprite->y - dirty->y + sprite->h);
+  if (dirty->x<0 || dirty->y<0){
+     display_backtrace();
+     fail("Invalid dirt: sprite=%d %d %d %d, dirt=%d %d %d %d",
+	  sprite->x,sprite->y,sprite->w,sprite->h,
+	  dirty->x,dirty->y,dirty->w,dirty->h);
+  }
+//  DEBUG("New dirty: %d %d %d %d ",
+//	dirty->x,dirty->y,dirty->w, dirty->h);
+}   
+
+static void sprite_draw(sprite_pool_t sp, sprite_t s, SDL_Surface *onto, SDL_Rect *from, SDL_Rect *to) {
   frame_t f=s->animation->element[s->frame];
 
   SDL_BlitSurface(f->surf, NULL, onto, &s->pos);  
 }
+
 void sprite_pool_draw( sprite_pool_t sp, SDL_Surface *onto, SDL_Rect *offset) {
   int i;
   sprite_t s;
@@ -218,25 +259,91 @@
   /* flag all sprites as new */
   for ( i = 0; i < sp->pool->size; i++ ) {
     s = sp->pool->element[i];
-    s->state = SPIRIT_NEW;
+    sprite_dirty(s);
   }
   
-  sprite_pool_redraw( sp, onto, 0/* not forcefully*/ , offset);
+  sprite_pool_redraw( sp, onto, offset);
 }
 
-void sprite_pool_redraw( sprite_pool_t sp, SDL_Surface *onto, int forceful,
-			 SDL_Rect *offset ) {
-  int i;
+void sprite_pool_redraw( sprite_pool_t sp, SDL_Surface *onto, SDL_Rect *offset ) {
+  int i,j;
   sprite_t s;
+  SDL_Rect fromRect;
+  int minx, maxx, miny, maxy; /* corners of the dirty zone */
+  Set layer[NB_LAYERS];
+  static int inited = 0;
 
-  /* redraw background */
-  SDL_BlitSurface(sp->theme->background, NULL, onto, offset);
+//  SDL_BlitSurface(sp->theme->background, NULL, onto, offset);
+
+  if (sp->dirty.w==0 || sp->dirty.h == 0) {
+     return;
+  }
+   
+  minx =        sp->dirty.x;
+  maxx = minx + sp->dirty.w;
+  miny =        sp->dirty.y;
+  maxy = miny + sp->dirty.h;
+   
+  /* Create the layers on need, empty them if not */
+  if (!inited) {
+     for ( i = 0; i < NB_LAYERS; i++ )
+       layer[i] = set_new( sp->pool->size );
+  } else {
+     for ( i = 0; i < NB_LAYERS; i++ )
+       set_empty( layer[i] );
+  }  
+
+//  DEBUG("bg %d %d %d %d dirty %d %d %d %d",
+//	offset->x,offset->y,sp->theme->background->w,sp->theme->background->h,
+//	sp->dirty.x,sp->dirty.y,sp->dirty.h,sp->dirty.w);
+  /* Redraw the background at the dirty zone */
+  fromRect.x = sp->dirty.x - offset->x;
+  fromRect.y = sp->dirty.y - offset->y;
+  fromRect.w = sp->dirty.w;
+  fromRect.h = sp->dirty.h;
+   
+  SDL_BlitSurface(sp->theme->background, &fromRect, onto, &sp->dirty);
 
+  /* Check which sprites need repainting (full or partial) and sort them by layer */
   for ( i = 0; i < sp->pool->size; i++ ) {
-    s = sp->pool->element[i];
-    sprite_draw(sp, s, onto);
+     s = sp->pool->element[i];
+     
+     SDL_Rect *p=&(s->pos);
+     
+     if ( ( BETWEEN(p->x,        minx, maxx) && BETWEEN(p->y,        miny, maxy) ) ||
+	  ( BETWEEN(p->x + p->w, minx, maxx) && BETWEEN(p->y + p->h, miny, maxy) ) ||
+	  ( BETWEEN(p->x,        minx, maxx) && BETWEEN(p->y + p->h, miny, maxy) ) ||
+	  ( BETWEEN(p->x + p->w, minx, maxx) && BETWEEN(p->y,        miny, maxy) ) ) 
+       {
+	  /* sprite at least intersects with dirty zone. Push it into its layer */
+	  set_add(layer[s->layer], s);
+       }
+  }
+   
+  for ( i = 0; i < NB_LAYERS; i++ ) {
+     for (j=0; j<layer[i]->size; j++) {
+	s = layer[i]->element[j];	  
+	SDL_Rect *p=&(s->pos);
+	/* Compute intersection zone. */
+	SDL_Rect inter,from;
+	inter.x = MAX(minx, p->x);
+	inter.y = MAX(miny, p->y);
+	inter.w = MIN(maxx, p->x + p->w) - inter.x;
+	inter.h = MIN(maxy, p->y + p->h) - inter.y;
+	
+	from.x=inter.x - p->x;
+	from.y=inter.y - p->y;
+	from.w=inter.w;
+	from.h=inter.h;
+	
+	sprite_draw(sp, s, onto, &from,&inter);
+     }
   }
+   
+  sprite_pool_clean(sp);
 }
+
+
 #if 0
 void sprite_pool_redraw( sprite_pool_t sp, SDL_Surface *onto, int forceful ) {
   int i, j, layer;
@@ -256,7 +363,6 @@
   for ( layer = 0; layer < sp->nb_layers; layer++ )
     set_empty( sp->layer[layer] );
 
-
   /* pass 1 : redraw background */
 
   for ( i = 0; i < sp->pool->size; i++ ) {

Index: board.h
===================================================================
RCS file: /cvsroot/xbubble/xbubble-sdl/src/board.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- board.h	16 Sep 2006 00:49:01 -0000	1.8
+++ board.h	23 Oct 2006 14:44:31 -0000	1.9
@@ -105,7 +105,7 @@
 
 void board_animate( board_t board , int dt );
 void board_draw( board_t board );
-void board_redraw( board_t board, int forcefully );
+void board_redraw( board_t board );
 
 void board_explode( board_t board );
 void board_freeze( board_t board );




More information about the Xbubble-commits mailing list